Skip to content

Instantly share code, notes, and snippets.

@teslamint
Last active October 9, 2015 14:27
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teslamint/3522208 to your computer and use it in GitHub Desktop.
Save teslamint/3522208 to your computer and use it in GitHub Desktop.
CodeIgniter CI_Model extended
<?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