Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- defined('BASEPATH') OR exit('No direct script access allowed');
- /**
- * CodeIgniter Base Model.
- *
- * @package CodeIgniter
- * @category Core Extension
- * @author Kader Bouyakoub <bkader@mail.com>
- * @link https://github.com/bkader
- * @link https://twitter.com/KaderBouyakoub
- */
- class MY_Model extends CI_Model
- {
- /**
- * holds the current model class name.
- * @var string
- */
- protected $model = null;
- /**
- * holds the current db group.
- * @var string
- */
- protected $db_group;
- /**
- * instance of $this->db object.
- * @var object
- */
- protected $database;
- /**
- * current table name set or guessed.
- * @var string
- */
- protected $table = null;
- /**
- * array of current table fields.
- * @var array
- */
- protected $fields = array();
- /**
- * holds the current table's primary key.
- * @var string
- */
- protected $primary_key = null;
- /**
- * how is data returned? As array of object.
- * @var string
- */
- protected $return_type = 'object';
- /**
- * whether to use unix_timestamp or mysql datetime.
- * @var boolean
- */
- protected $unix_timestamp = true;
- /**
- * use this format when using mysql datetime.
- * @var string
- */
- protected $datetime_format = 'Y-m-d H:i:s';
- /**
- * column that holds the date of creation.
- * @var string
- */
- protected $created_at = 'created_at';
- /**
- * column that holds the date of update.
- * @var string
- */
- protected $updated_at = 'updated_at';
- /**
- * whether to remove the record or update the column of deletion.
- * @var boolean
- */
- protected $soft_delete = false;
- /**
- * column that holds the date of deletion.
- * @var string
- */
- protected $deleted_at = 'deleted_at';
- /**
- * if set to TRUE, retrieve deleted records as well.
- * @var boolean
- */
- protected $even_deleted = false;
- /**
- * if set to TRUE, retrieve only deleted records.
- * @var boolean
- */
- protected $only_deleted = false;
- /**
- * attributes that will be removed from data before insert or update.
- * @var array
- */
- protected $protected_attributes = array();
- /**
- * whether to skip form validation or not.
- * @var boolean
- */
- protected $skip_validation = false;
- /**
- * array of form validation rules.
- * @var array
- */
- protected $validation_rules = array();
- /**
- * before and after observers.
- */
- protected $before_create = array();
- protected $before_update = array();
- protected $before_delete = array();
- protected $before_find = array();
- protected $after_create = array();
- protected $after_update = array();
- protected $after_delete = array();
- protected $after_find = array();
- /**
- * holds the array of data that will be used before insert or update.
- * @var array|false
- */
- protected $data = false;
- /**
- * holds the result of query before returning it.
- * @var mixed
- */
- protected $result = false;
- /**
- * relationship getter.
- * @var array
- */
- protected $with = array();
- /**
- * Contains any related objects of which this model
- * is singularly related.
- * @var array
- */
- protected $has_one = array();
- /**
- * Contains any related objects of which this model
- * is related one or more times.
- * @var array
- */
- protected $has_many = array();
- /**
- * class constructor
- *
- * @return void
- */
- public function __construct()
- {
- parent::__construct();
- $this->model = ucfirst(get_class($this));
- $this->_fetch_table();
- $this->_set_database();
- $this->_fetch_fields();
- $this->_set_primary_key();
- $this->_set_soft_delete();
- // default observers if none are set.
- array_unshift($this->before_create, 'protect_attributes', 'created_at');
- array_unshift($this->before_update, 'protect_attributes', 'updated_at');
- }
- // ------------------------------------------------------------------------
- /**
- * override methods call to create additional special ones :D.
- */
- public function __call($method, $params)
- {
- // No table set? Nothing to do.
- if (empty($this->table))
- {
- show_error("Table name is not set for '{$this->model}' class.");
- }
- // The method exists in this class? Call it.
- elseif (method_exists($this, $method))
- {
- return call_user_func_array(array($this, $method), $params);
- }
- // Add methods to observers.
- elseif (preg_match('/^before_([^)]+)$/', $method, $m))
- {
- if (isset($this->{$m[0]}) && is_array($this->{$m[0]}))
- {
- is_array($params[0]) && $params = $params[0];
- foreach ($params as $param)
- {
- array_push($this->{$m[0]}, $param);
- }
- }
- return $this;
- }
- // Retrieve by a given column name?
- elseif (preg_match('/^find_by_([^)]+)$/', $method, $m) && count($m) == 2)
- {
- $field = $m[1];
- $match = array_shift($params);
- if (strpos($field, '_or_'))
- {
- $field = explode('_or_', $field);
- }
- $result = false;
- if (is_array($field))
- {
- $_params = $params;
- foreach ($field as $_field)
- {
- array_unshift($_params, $_field, $match);
- if ($found = call_user_func_array(array($this, 'find_by'), $_params))
- {
- $result = $found;
- break;
- }
- $_params = $params;
- }
- }
- else
- {
- array_unshift($params, $field, $match);
- $result = call_user_func_array(array($this, 'find_by'), $params);
- }
- return $result;
- }
- // Retrieve multiple records by a given column name?
- elseif (preg_match('/^find_many_by_([^)]+)$/', $method, $m) && count($m) == 2)
- {
- array_unshift($params, $m[1]);
- return call_user_func_array(array($this, 'find_many'), $params);
- }
- // Update a row using update_by() method
- elseif ((preg_match('/^update_by_([^)]+)$/', $method, $m)
- OR preg_match('/^delete_by_([^)]+)$/', $method, $m))
- && count($m) == 2)
- {
- $method = str_replace("_{$m[1]}", '', $method);
- array_unshift($params, $m[1]);
- return call_user_func_array(array($this, $method), $params);
- }
- // No need to create the method, we use the existing one.
- elseif ($method == 'update_many' OR $method == 'delete_many')
- {
- $method = str_replace('many', 'by', $method);
- return call_user_func_array(array($this, $method), $params);
- }
- // Update multiple records using update_many() method
- elseif ((preg_match('/^update_many_by_([^)]+)$/', $method, $m)
- OR preg_match('/^delete_many_by_([^)]+)$/', $method, $m))
- && count($m) == 2)
- {
- $method = str_replace("many_by_{$m[1]}", 'by', $method);
- array_unshift($params, $m[1]);
- return call_user_func_array(array($this, $method), $params);
- }
- // Remove records even if $soft_delete is set to true.
- elseif (strpos($method, 'remove') === 0)
- {
- $method = str_replace('remove', 'delete', $method);
- $this->soft_delete = false;
- return call_user_func_array(array($this, $method), $params);
- }
- elseif (method_exists($this->database, $method))
- {
- return call_user_func_array(array($this->database, $method), $params);
- }
- // No method found? Show error.
- else
- {
- show_error("Method $method() does not exist in class {$this->model}");
- }
- }
- // ------------------------------------------------------------------------
- // INTERNAL METHODS
- // ------------------------------------------------------------------------
- /**
- * Attempts to guess table's name if not set.
- */
- private function _fetch_table()
- {
- if ($this->table == null)
- {
- // Load inflector helper.
- function_exists('plural') OR $this->load->helper('inflector');
- $this->table = plural(preg_replace('/(_m|_model)?$/', '', strtolower($this->model)));
- }
- }
- /**
- * prepares database object.
- */
- private function _set_database()
- {
- if ($this->db_group !== null)
- {
- $this->database = $this->load->database($this->db_group, true, true);
- }
- else
- {
- if ( ! isset($this->db) or ! is_object($this->db))
- {
- $this->load->database('', false, true);
- }
- }
- $this->database = $this->db;
- }
- /**
- * prepares an array of table's columns.
- */
- private function _fetch_fields()
- {
- if (is_object($this->database) && $this->table != null && $this->table != 'mies')
- {
- $this->fields = $this->database->list_fields($this->table);
- }
- }
- /**
- * try to guess the primary key if not set
- */
- private function _set_primary_key()
- {
- if ($this->table != null && $this->table != 'mies' && $this->primary_key == null)
- {
- $this->primary_key = $this->database->query("SHOW KEYS FROM `".$this->table."` WHERE Key_name = 'PRIMARY'")->row()->Column_name;
- }
- }
- /**
- * try to guess if soft delete should be turned on or not.
- */
- private function _set_soft_delete()
- {
- if (is_object($this->database) && $this->table != null)
- {
- $this->soft_delete = in_array($this->deleted_at, $this->fields);
- }
- }
- /**
- * remove protected attributes form data
- */
- public function protect_attributes()
- {
- foreach ($this->protected_attributes as $attr)
- {
- if (is_object($this->data))
- {
- unset($this->data->{$attr});
- }
- else
- {
- unset($this->data[$attr]);
- }
- }
- }
- /**
- * returns the array of table's columns.
- */
- public function list_fields()
- {
- if (empty($this->fields))
- {
- $this->_fetch_fields();
- }
- return $this->fields;
- }
- /**
- * prepare the return type.
- */
- private function return_type($multi = false)
- {
- $method = $multi ? 'result' : 'row';
- $method .= ($this->return_type == 'array') ? '_array' : '';
- return $method;
- }
- /**
- * validate data before insert or update using CI form validation.
- */
- public function validate()
- {
- $data = $this->data;
- if ($this->skip_validation === false && ! empty($this->validation_rules))
- {
- foreach ($this->validation_rules as $key => $val)
- {
- $_POST[$key] = $val;
- }
- // Load form validation only if it's not loaded.
- if ( ! class_exists('CI_Form_validation', false))
- {
- $this->load->library('form_validation');
- }
- if (is_array($this->validation_rules))
- {
- $this->form_validation->set_rules($this->validation_rules);
- if ($this->form_validation->run() == true)
- {
- $this->data = $data;
- }
- else
- {
- $this->data = false;
- }
- }
- else
- {
- if ($this->form_validation->run($this->validation_rules) == true)
- {
- $this->data = $data;
- }
- else
- {
- $this->data = false;
- }
- }
- }
- $this->data = $data;
- }
- /**
- * triggers and event on $data or $result
- */
- public function trigger($event, $data = array())
- {
- if (isset($this->{$event}) && is_array($this->{$event}))
- {
- foreach ($this->{$event} as $method)
- {
- call_user_func_array(array($this, $method), $data);
- }
- }
- }
- /**
- * Set time() depending on the property $this->unix_timestamp
- */
- protected function set_datetime()
- {
- if ($this->unix_timestamp === true)
- {
- return time();
- }
- return date($this->datetime_format);
- }
- /**
- * Add date of creation to $data before insert.
- */
- protected function created_at()
- {
- if (is_object($this->data) && empty($this->data->{$this->created_at}))
- {
- $this->data->{$this->created_at} = $this->set_datetime();
- }
- elseif (is_array($this->data) && empty($this->data[$this->created_at]))
- {
- $this->data[$this->created_at] = $this->set_datetime();
- }
- }
- /**
- * Add date of update to $data before update.
- */
- protected function updated_at()
- {
- if (is_object($this->data) && empty($this->data->{$this->updated_at}))
- {
- $this->data->{$this->updated_at} = $this->set_datetime();
- }
- elseif (is_array($this->data) && empty($this->data[$this->updated_at]))
- {
- $this->data[$this->updated_at] = $this->set_datetime();
- }
- }
- /**
- * Prepares WHERE clause.
- */
- public function set_where()
- {
- $args = func_get_args();
- if ( ! empty($args))
- {
- $field = array_shift($args);
- $match = is_array($field) ? null : array_shift($args);
- if (is_array($match))
- {
- $this->database->where_in($field, $match);
- }
- else
- {
- $this->database->where($field, $match);
- }
- }
- // If there are still arguments, use them for select().
- if ( ! empty($args))
- {
- $this->database->select($args);
- }
- // We make sure to exclude deleted records
- if ($this->even_deleted === true)
- {
- $this->soft_delete = false;
- }
- if ($this->soft_delete === true)
- {
- if ($this->only_deleted === true)
- {
- $this->database->where("$this->deleted_at >=", 1);
- }
- else
- {
- $this->database->where($this->deleted_at, 0);
- }
- }
- // By returning this, we allow chaining
- return $this;
- }
- /**
- * retrieve deleted records as well.
- */
- public function even_deleted()
- {
- $this->even_deleted = true;
- return $this;
- }
- /**
- * retrieves deleted records only.
- */
- public function only_deleted()
- {
- $this->only_deleted = true;
- return $this;
- }
- public function get($table = null)
- {
- $table OR $table = $this->table;
- return $this->database->get($table);
- }
- // ------------------------------------------------------------------------
- // INSERT METHODS
- // ------------------------------------------------------------------------
- /**
- * Inserts a new record and returns its ID.
- */
- public function insert(array $data = array(), $validate = true)
- {
- $this->data = $data;
- $validate && $this->validate();
- $this->trigger('before_create');
- if ($this->database->insert($this->table, $this->data))
- {
- $insert_id = $this->database->insert_id();
- $this->trigger('after_create', $insert_id);
- return $insert_id;
- }
- return false;
- }
- /**
- * inserts multiple records and returns an array if IDs.
- */
- public function insert_many(array $data = array(), $validate = true)
- {
- $ids = array();
- foreach ($data as $_data)
- {
- $ids[] = $this->insert($_data, $validate);
- }
- return $ids;
- }
- // ------------------------------------------------------------------------
- // FINDERS
- // ------------------------------------------------------------------------
- /**
- * Retrieves a single record by its primary value with optional select.
- */
- public function find()
- {
- $args = func_get_args();
- if ( ! empty($args))
- {
- array_unshift($args, $this->primary_key);
- return call_user_func_array(array($this, 'find_by'), $args);
- }
- return false;
- }
- /**
- * Retrieves a single record by $field=$match condition with option select.
- */
- public function find_by()
- {
- call_user_func_array(array($this, 'set_where'), func_get_args());
- $this->result = $this->get($this->table);
- if ($this->result->num_rows() == 1)
- {
- $result = $this->result->{$this->return_type()}();
- $result = $this->relate($result);
- return $result;
- }
- return false;
- }
- /**
- * Retrieves multiple records by WHERE clause with optional select argument.
- */
- public function find_many()
- {
- call_user_func_array(array($this, 'set_where'), func_get_args());
- $this->result = $this->get($this->table);
- if ($this->result->num_rows() >= 1)
- {
- return $this->result->{$this->return_type(true)}();
- }
- return false;
- }
- // ------------------------------------------------------------------------
- // UPDATES
- // ------------------------------------------------------------------------
- /**
- * updates a single record by its primary key value.
- */
- public function update()
- {
- $args = func_get_args();
- if ( ! empty($args))
- {
- array_unshift($args, $this->primary_key);
- return call_user_func_array(array($this, 'update_by'), $args);
- }
- return false;
- }
- /**
- * updates a single record by WHERE clause.
- */
- public function update_by()
- {
- $args = func_get_args();
- if (empty($args))
- {
- return false;
- }
- // $data is always at the end.
- $this->data = array_pop($args);
- if ( ! is_array($this->data) OR empty($this->data))
- {
- return false;
- }
- $this->trigger('before_update');
- $this->skip_validation OR $this->validate();
- if ($this->data !== false)
- {
- call_user_func_array(array($this, 'set_where'), $args);
- $this->database->update($this->table, $this->data);
- $result = ($this->database->affected_rows() > 0);
- $this->trigger('after_update', array($this->data, $result));
- return $result;
- }
- return false;
- }
- // ------------------------------------------------------------------------
- // DELETES
- // ------------------------------------------------------------------------
- /**
- * Delete a row from the table by the primary value
- */
- public function delete($primary_value)
- {
- return $this->delete_by($this->primary_key, $primary_value);
- }
- /**
- * Delete a row from the database table by an arbitrary WHERE clause
- */
- public function delete_by()
- {
- call_user_func_array(array($this, 'set_where'), func_get_args());
- if ($this->soft_delete === true)
- {
- $datetime = $this->set_datetime();
- $this->database->update(
- $this->table,
- array($this->deleted_at => $datetime)
- );
- }
- else
- {
- $this->database->delete($this->table);
- }
- $result = ($this->database->affected_rows() > 0);
- $this->trigger('after_delete', $result);
- return $result;
- }
- // ------------------------------------------------------------------------
- // RELATIONSHIPS
- // ------------------------------------------------------------------------
- /**
- * adds a relation ship.
- */
- public function with($relation)
- {
- $args = str_replace(' ', '', explode(',', $relation));
- foreach ($args as $arg)
- {
- $this->with[] = $arg;
- }
- return $this;
- }
- /**
- * creates table's relationships
- */
- protected function relate($row)
- {
- function_exists('singular') OR $this->load->helper('inflector');
- // Loop through has_one in order to
- // get data from the related table
- if ( ! empty($this->has_one) and is_array($this->has_one))
- {
- foreach ($this->has_one as $key => $value)
- {
- $options = array();
- if (is_string($value))
- {
- $relationship = $value;
- $options['model'] = isset($options['model'])
- ? $options['model']
- : plural($value).'_model';
- }
- else
- {
- $relationship = $key;
- $options = $value;
- }
- $options['local'] = isset($options['local'])
- ? $options['local']
- : $this->primary_key;
- $options['foreign'] = isset($options['foreign'])
- ? $options['foreign']
- : singular($this->table).'_id';
- if (in_array($relationship, $this->with))
- {
- $this->load->model($options['model']);
- $_model = explode('/', $options['model']);
- $_model = end($_model);
- if (is_array($row))
- {
- $row[$relationship] = $this->{$_model}->find_by(array($options['foreign'] => $row[$options['local']]));
- }
- else
- {
- $row->$relationship = $this->{$_model}->find_by(array($options['foreign'] => $row->{$options['local']}));
- }
- }
- }
- }
- // Loop through has_many in order to
- // get data from the related table
- if ( ! empty($this->has_many) and is_array($this->has_many))
- {
- foreach ($this->has_many as $key => $value)
- {
- $options = array();
- if (is_string($value))
- {
- $relationship = $value;
- $options['model'] = isset($options['model'])
- ? $options['model']
- : plural($value).'_model';
- }
- else
- {
- $relationship = $key;
- $options = $value;
- }
- $options['local'] = isset($options['local'])
- ? $options['local']
- : $this->primary_key;
- $options['foreign'] = isset($options['foreign'])
- ? $options['foreign']
- : singular($this->table).'_id';
- if (in_array($relationship, $this->with))
- {
- $this->load->model($options['model']);
- $_model = explode('/', $options['model']);
- $_model = end($_model);
- if (is_array($row))
- {
- $row[$relationship] = $this->{$_model}->find_many(array($options['foreign'] => $row->{$options['local']}));
- }
- else
- {
- $row->$relationship = $this->{$_model}->find_many(array($options['foreign'] => $row->{$options['local']}));
- }
- }
- }
- }
- return $row;
- }
- }
- /* End of file MY_Model.php */
- /* Location: ./application/core/MY_Model.php */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement