Last active
October 9, 2015 14:27
-
-
Save teslamint/3522208 to your computer and use it in GitHub Desktop.
CodeIgniter CI_Model extended
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
/** | |
* extended CI_Model | |
* | |
* @access public | |
* @extends CI_Model | |
* @see http://thetechnofreak.com/technofreak/hook-system-php/ for hook system reference | |
*/ | |
class MY_Model extends CI_Model { | |
private $key_field = 'id'; | |
private $fields = array('id'); | |
private $table_name = ''; | |
private $table_prefix = ''; | |
private $required_fields = array(); | |
private $optional_fields = array(); | |
private $hooks = array(); | |
protected $allow_operator = '/[<>]\=?\ |\!\=\ /i'; | |
function __construct() { | |
parent::__construct(); | |
$this->add_action('post_count_all_result_hook', 'self::_post_count_all_result_hook'); | |
$this->add_action( 'before_get_where_loop', 'self::_before_get_where_loop' ); | |
$this->add_action( 'after_get_where_loop', 'self::_after_get_where_loop' ); | |
$this->_log('started.'); | |
} | |
function __destruct() { | |
$this->_log('end.'); | |
} | |
/** | |
* get function. | |
* | |
* @access public | |
* @param array $options (default: array()) | |
* @return void | |
*/ | |
public function get($options = array()) { | |
$this->_log('started.'); | |
if (!empty($this->table_prefix)) { | |
$table_prefix = "{$this->table_prefix}."; | |
} else { | |
$table_prefix = ""; | |
} | |
// where hook | |
$this->execute_action('before_get_where_loop', $options); | |
foreach($options as $key => $value) { | |
if (in_array($key, $this->fields) && isset($value)) { | |
if (preg_match('/^(not )?null$/i', $value)) { | |
$this->db->where("{$table_prefix}{$key} IS ". strtoupper($value)); | |
} elseif (strpos($value, '%') !== FALSE) { | |
$this->db->where("{$table_prefix}{$key} LIKE '{$value}'"); | |
} elseif (preg_match($this->allow_operator, $value, $matches) > 0) { | |
$this->db->where("{$table_prefix}{$key} {$matches[0]}", trim(preg_replace($this->allow_operator, '', $value))); | |
} else { | |
$this->db->where("{$table_prefix}{$key}", $value); | |
} | |
} | |
$this->execute_action('inside_get_where_loop', array($key => $value)); | |
} | |
$this->execute_action('after_get_where_loop', $options); | |
if (!empty($options['order_by']) && in_array($options['order_by'], $this->fields)) { | |
if (!empty($options['desc'])) | |
$options['desc'] = $options['desc'] === 'desc' ? 'desc' : 'asc'; | |
else | |
$options['desc'] = 'asc'; | |
$this->db->order_by($options['order_by'], $options['desc']); | |
} | |
if (!empty($options['limit'])) { | |
$options['start'] = !empty($options['start']) ? $options['start'] : 0; | |
$this->db->limit($options['limit'], $options['start']); | |
} | |
// select hook | |
$this->execute_action('select_hook', $options); | |
if (!empty($this->table_prefix)) | |
$query_table = sprintf("%s AS %s", $this->table_name, $this->table_prefix); | |
else $query_table = $this->table_name; | |
// pre_get hook | |
$this->execute_action('pre_get_hook', $options); | |
$query = $this->db->get($query_table); | |
// post_get hook | |
$this->execute_action('post_get_hook', array('options' => $options, 'query' => &$query)); | |
$this->_log('get query: '. $this->db->last_query()); | |
if (!$query) { | |
$this->_log('error', $this->db->_error_message()); | |
return FALSE; | |
} | |
$this->_log('end.'); | |
return $query->result(); | |
} | |
/** | |
* insert function. | |
* | |
* @access public | |
* @param array $options (default: array()) | |
* @return void | |
*/ | |
public function insert($options = array()) { | |
$this->_log('started.'); | |
$this->execute_action('before_insert_where_loop', $options); | |
foreach($this->required_fields as $key) { | |
if (array_key_exists($key, $options) && isset($options[$key])) { | |
$this->db->set($key, $options[$key]); | |
unset($options[$key]); | |
} | |
} | |
foreach($this->optional_fields as $key) { | |
if (array_key_exists($key, $options) && !empty($options[$key])) { | |
$this->db->set($key, $options[$key]); | |
unset($options[$key]); | |
} | |
} | |
$this->execute_action('after_insert_where_loop', $options); | |
if ( count( $options ) ) { | |
// unknown column | |
$this->_log('error', 'unknown column: '. var_export($options, TRUE)); | |
} | |
$this->execute_action('pre_insert_hook', $options); | |
$query = $this->db->insert($this->table_name); | |
$this->execute_action('post_insert_hook', $options); | |
$this->_log('insert query: '. $this->db->last_query()); | |
if (!$query) { | |
$this->_log('error', $this->db->_error_message()); | |
return FALSE; | |
} | |
$id = $this->db->insert_id(); | |
$this->_log('insert_id: '.$id); | |
$this->_log('end.'); | |
return intval($id); | |
} | |
/** | |
* insert with ignore option | |
* | |
* @param unknown $options (optional) | |
* @return unknown | |
*/ | |
public function insert_ignore($options = array()) { | |
$this->_log('started.'); | |
$this->execute_action('before_insert_where_loop', $options); | |
foreach ($this->required_fields as $key) { | |
if (array_key_exists($key, $options) && isset($options[$key])) { | |
$this->db->set($key, $options[$key]); | |
unset($options[$key]); | |
} | |
} | |
foreach ($this->optional_fields as $key) { | |
if (array_key_exists($key, $options) && !empty($options[$key])) { | |
$this->db->set($key, $options[$key]); | |
unset($options[$key]); | |
} | |
} | |
if ( count( $options ) ) { | |
// unknown column | |
$this->_log('error', 'unknown column: '. var_export($options, TRUE)); | |
} | |
$this->execute_action('pre_insert_ignore_hook', $options); | |
$insert_query = $this->db->insert_string($this->table_name); | |
$insert_query = str_replace('INSERT INTO', 'INSERT IGNORE INTO', $insert_query); | |
$query = $this->db->query($insert_query); | |
$this->execute_action('post_insert_ignore_hook', $options); | |
$this->_log('insert query: '. $this->db->last_query()); | |
if (!$query) { | |
$this->_log('error', $this->db->_error_message()); | |
return FALSE; | |
} | |
// required to use mysqli as db driver | |
$id = $this->db->mysql_insert_id(); | |
$this->_log('insert_id: '.$id); | |
$this->_log('end.'); | |
return intval($id); | |
} | |
/** | |
* insert_batch function. | |
* | |
* @access public | |
* @param array $options (default: array()) | |
* @return void | |
*/ | |
public function insert_batch($options = array()) { | |
$this->_log('started.'); | |
$this->execute_action('before_insert_batch_query', $options); | |
$query = $this->db->insert_batch($this->table_name, $options, $this->key_field); | |
$this->execute_action('after_insert_batch_query', $options); | |
$this->_log('insert batch query: '. $this->db->last_query()); | |
if (!$query) { | |
$this->_log('error', $this->db->_error_message()); | |
return FALSE; | |
} | |
$this->_log('end.'); | |
return $this->db->affected_rows(); | |
} | |
/** | |
* update function. | |
* | |
* @access public | |
* @param array $options (default: array()) | |
* @return void | |
*/ | |
public function update($options = array()) { | |
$this->_log('started.'); | |
$this->execute_action('before_update_where_loop', $options); | |
foreach($options as $key => $value) { | |
if (strncmp($key, $this->key_field, strlen($this->key_field)) === 0) | |
continue; | |
if (in_array($key, $this->fields) && isset($value)) { | |
if ( $value === NULL || strcmp($value, 'NULL') === 0 || $value === '') | |
$this->db->set($key, NULL); | |
else | |
$this->db->set($key, $value); | |
} else { | |
$this->_log('error', "unknown column or no value: {$key} = {$value}"); | |
} | |
} | |
$this->execute_action('after_update_where_loop', $options); | |
$this->db->where($this->key_field, $options[$this->key_field]); | |
$this->execute_action('pre_update_hook', $options); | |
$query = $this->db->update($this->table_name); | |
$this->execute_action('post_update_hook', $options); | |
if ( ! $query ) { | |
$this->_log('error', $this->db->_error_message()); | |
return FALSE; | |
} | |
$this->_log('update query: '. $this->db->last_query()); | |
$this->_log('end.'); | |
return $this->db->affected_rows(); | |
} | |
/** | |
* update_batch function. | |
* | |
* @access public | |
* @param array $options (default: array()) | |
* @return void | |
*/ | |
public function update_batch($options = array()) { | |
$this->_log('started.'); | |
if (count($options) < 1) | |
return FALSE; | |
$this->execute_action('pre_update_batch_hook', $options); | |
$query = $this->db->update_batch($this->table_name, $options, $this->key_field); | |
$this->execute_action('post_update_batch_hook', $options); | |
$this->_log('update batch query: '. $this->db->last_query()); | |
$this->_log('end.'); | |
if ($query) | |
return $this->db->affected_rows(); | |
else { | |
$this->_log('error', $this->db->_error_message()); | |
return FALSE; | |
} | |
} | |
/** | |
* delete function. | |
* | |
* @access public | |
* @param float $brand_id (default: 0) | |
* @return void | |
*/ | |
public function delete($id = 0) { | |
$this->_log('started.'); | |
$result = FALSE; | |
if ( intval( $id ) ) { | |
$this->db->where($this->key_field, $id); | |
$this->execute_action('pre_delete_hook', array('id' => $id)); | |
$query = $this->db->delete($this->table_name); | |
$this->execute_action('post_delete_hook', array('id' => $id)); | |
$this->_log('delete query: '. $this->db->last_query()); | |
if (!$query) { | |
$this->_log('error', $this->db->_error_message()); | |
} else | |
$result = TRUE; | |
} | |
$this->_log('end.'); | |
return $result; | |
} | |
/** | |
* count_all function. | |
* | |
* @access public | |
* @return integer - count of records | |
*/ | |
public function count_all() { | |
$this->_log('started.'); | |
$result = 0; | |
$this->execute_action('pre_count_all_hook', array()); | |
if (!empty($this->table_prefix)) | |
$query_table = sprintf("%s AS %s", $this->table_name, $this->table_prefix); | |
else $query_table = $this->table_name; | |
$result = $this->db->count_all($query_table); | |
$this->_log('count_all query: '. $this->db->last_query()); | |
$this->execute_action('post_count_all_hook', array()); | |
$this->_log('end.'); | |
return $result; | |
} | |
/** | |
* get count of query results | |
* @param array $options columns | |
* @return integer - count of records | |
*/ | |
public function count_all_results($options = array()) { | |
$this->_log('started.'); | |
$result = 0; | |
$this->execute_action('pre_count_all_result_hook', array()); | |
if (!empty($this->table_prefix)) | |
$query_table = sprintf("%s AS %s", $this->table_name, $this->table_prefix); | |
else $query_table = $this->table_name; | |
$result = $this->db->count_all_results($query_table); | |
$this->_log('count_all_results query: '. $this->db->last_query()); | |
$this->execute_action('post_count_all_result_hook', array()); | |
$this->_log('end.'); | |
return $result; | |
} | |
// hook functions ----------------------------- | |
/** | |
* add hook action | |
* @param string $where name of hook to use | |
* @param string $callback name of function | |
* @param integer $priority priority of function call (0~, default: 50) | |
*/ | |
public function add_action($where, $callback, $priority = 50) { | |
$this->_log('started.'); | |
if ( !isset($this->hooks[$where])) { | |
$this->hooks[$where] = array(); | |
} | |
if (intval($priority) < 0) { | |
$priority = abs($priority); | |
} | |
if ( isset( $this->hooks[$where][$callback] ) && $this->hooks[$where][$callback] === $priority ) { | |
// skip | |
$this->_log('callback already registered. skipped.'); | |
} else { | |
$this->hooks[$where][$callback] = $priority; | |
$this->_log('add callback: '. $callback .' to: '. $where); | |
} | |
$this->_log('end.'); | |
} | |
/** | |
* remove hook action | |
* | |
* @param string $where name of hook to use | |
* @param string $callback name of function | |
*/ | |
public function remove_action($where, $callback) { | |
$this->_log('started.'); | |
if ( isset($this->hooks[$where][$callback])) { | |
unset($this->hooks[$where][$callback]); | |
$this->_log( 'remove callback: '. $callback .' from: '. $where ); | |
} | |
$this->_log('end.'); | |
} | |
/** | |
* execute hook action | |
* | |
* @param string $where name of hook to use | |
* @param array $args array of arguments | |
*/ | |
public function execute_action($where, $args = array()) { | |
$this->_log('started.'); | |
$class = get_class($this); | |
if ( isset($this->hooks[$where]) && is_array($this->hooks[$where])) { | |
arsort($this->hooks[$where]); | |
foreach ($this->hooks[$where] as $callback => $priority) { | |
$this->_log( 'executing callback: '. $callback .' with priority: '. $priority ); | |
call_user_func(array($class, $callback), $args); | |
} | |
} | |
$this->_log('end.'); | |
} | |
// get/set functions -------------------------- | |
/** | |
* | |
* | |
* @return unknown | |
*/ | |
public function get_fields() { | |
return $this->fields; | |
} | |
/** | |
* | |
* | |
* @param unknown $name (optional) | |
*/ | |
public function set_table_name($name = '') { | |
$this->table_name = $name; | |
} | |
/** | |
* | |
* | |
* @return unknown | |
*/ | |
public function get_table_name() { | |
return $this->table_name; | |
} | |
/** | |
* | |
* | |
* @param unknown $value (optional) | |
*/ | |
public function set_table_prefix($value='') | |
{ | |
$this->table_prefix = $value; | |
} | |
/** | |
* | |
* | |
* @return unknown | |
*/ | |
public function get_table_prefix() | |
{ | |
return $this->table_prefix; | |
} | |
/** | |
* | |
* | |
* @param unknown $fields (optional) | |
*/ | |
public function set_required_fields($fields = array()) { | |
$this->required_fields = $fields; | |
} | |
/** | |
* | |
* | |
* @return unknown | |
*/ | |
public function get_required_fields() { | |
return $this->required_fields; | |
} | |
/** | |
* | |
* | |
* @param unknown $fields (optional) | |
*/ | |
public function set_optional_fields($fields = array()) { | |
$this->optional_fields = $fields; | |
} | |
/** | |
* | |
* | |
* @param unknown $fields (optional) | |
* @return unknown | |
*/ | |
public function get_optional_fields($fields = array()) { | |
return $this->optional_fields; | |
} | |
/** | |
* | |
* | |
* @param unknown $field (optional) | |
*/ | |
public function set_key_field($field = 'id') { | |
$this->key_field = $field; | |
} | |
/** | |
* | |
* | |
* @return unknown | |
*/ | |
public function get_key_field() { | |
return $this->key_field; | |
} | |
/** | |
* | |
* | |
* @param unknown $more_fields (optional) | |
*/ | |
public function combine_fields($more_fields = array()) { | |
$this->fields = array_merge(array($this->key_field), $this->required_fields, $this->optional_fields, $more_fields); | |
$this->fields = array_flip(array_flip($this->fields)); // remove null or duplicate element just in case. | |
$this->_log('$this->fields: '. var_export($this->fields, TRUE)); | |
} | |
// protected function ---------------- | |
/** | |
* logging message via CI's log_message() | |
*/ | |
protected function _log() { | |
$num_arg = func_num_args(); | |
if ( ! intval( $num_arg ) ) | |
return; | |
$trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS | DEBUG_BACKTRACE_PROVIDE_OBJECT ); | |
$func = $trace[1]['function']; | |
$line = $trace[0]['line']; | |
$object = $trace[1]['object']; | |
if ( is_object( $object ) ) | |
$class = get_class( $object ); | |
else | |
$class = get_called_class(); | |
$level = 'debug'; | |
$message = ''; | |
switch ( $num_arg ) { | |
case 1: | |
$message = func_get_arg( 0 ); | |
break; | |
case 2: | |
$message = func_get_arg( 1 ); | |
$level = ( strcasecmp( $func, func_get_arg( 0 ) ) === 0 ) ? $level : func_get_arg( 0 ); | |
$func = ( ! method_exists( $class, $func ) ) ? func_get_arg( 0 ) : $func; | |
break; | |
default: | |
list( $func, $level, $message ) = func_get_args(); | |
if ( ! method_exists( $class, $func ) ) { | |
// maybe swapped | |
$temp = $func; | |
$func = $level; | |
$level = $func; | |
} | |
} | |
$message = str_replace( PHP_EOL, ' ', $message ); | |
log_message( $level, "{$class}::{$func}({$line}): {$message}" ); | |
} | |
/** | |
* start db query cache | |
*/ | |
protected function _before_get_where_loop() { | |
$this->db->flush_cache(); | |
$this->db->start_cache(); | |
$this->_log( 'db cache start' ); | |
} | |
/** | |
* stop db query cache | |
*/ | |
protected function _after_get_where_loop() { | |
$this->db->stop_cache(); | |
$this->_log( 'db cache stop' ); | |
} | |
/** | |
* flush db cache after get count of results | |
*/ | |
protected function _post_count_all_result_hook() { | |
$this->_log('running!'); | |
$this->db->flush_cache(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment