Last active
December 18, 2015 14:19
-
-
Save subdesign/5796813 to your computer and use it in GitHub Desktop.
Extend CI AR functions (In this case extending join() clause to handle Postgres type casting, eg. variabe::int )
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
------------------------------- | |
/application/core/MY_Loader.php | |
------------------------------- | |
<?php (defined('BASEPATH')) OR exit('No direct script access allowed'); | |
class MY_Loader extends CI_Loader { | |
/** | |
* Database Loader | |
* | |
* @access public | |
* @param string the DB credentials | |
* @param bool whether to return the DB object | |
* @param bool whether to enable active record (this allows us to override the config setting) | |
* @return object | |
*/ | |
function database($params = '', $return = FALSE, $active_record = NULL) | |
{ | |
// Grab the super object | |
$CI =& get_instance(); | |
// Do we even need to load the database class? | |
if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db)) | |
{ | |
return FALSE; | |
} | |
// Check for MY_DB in application/core | |
$my_db = config_item('subclass_prefix').'DB'; | |
$my_db_file = APPPATH.'core/'.$my_db.EXT; | |
if(file_exists($my_db_file)) | |
{ | |
require_once($my_db_file); | |
} | |
else | |
{ | |
require_once(BASEPATH.'database/DB'.EXT); | |
} | |
// Load the DB class | |
$db =& DB($params, $active_record); | |
// Check for a custom db driver | |
$my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.'_driver'; | |
$my_driver_file = APPPATH.'core/'.$my_driver.EXT; | |
if (file_exists($my_driver_file)) | |
{ | |
require_once($my_driver_file); | |
$db = new $my_driver(get_object_vars($db)); | |
} | |
if ($return === TRUE) | |
{ | |
return $db; | |
} | |
// Initialize the db variable. Needed to prevent | |
// reference errors with some configurations | |
$CI->db = ''; | |
$CI->db = $db; | |
} | |
} | |
--------------------------- | |
/application/core/MY_DB.php | |
--------------------------- | |
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
function &DB($params = '', $active_record_override = NULL) | |
{ | |
// Load the DB config file if a DSN string wasn't passed | |
if (is_string($params) AND strpos($params, '://') === FALSE) | |
{ | |
// Is the config file in the environment folder? | |
if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php')) | |
{ | |
if ( ! file_exists($file_path = APPPATH.'config/database.php')) | |
{ | |
show_error('The configuration file database.php does not exist.'); | |
} | |
} | |
include($file_path); | |
if ( ! isset($db) OR count($db) == 0) | |
{ | |
show_error('No database connection settings were found in the database config file.'); | |
} | |
if ($params != '') | |
{ | |
$active_group = $params; | |
} | |
if ( ! isset($active_group) OR ! isset($db[$active_group])) | |
{ | |
show_error('You have specified an invalid database connection group.'); | |
} | |
$params = $db[$active_group]; | |
} | |
elseif (is_string($params)) | |
{ | |
/* parse the URL from the DSN string | |
* Database settings can be passed as discreet | |
* parameters or as a data source name in the first | |
* parameter. DSNs must have this prototype: | |
* $dsn = 'driver://username:password@hostname/database'; | |
*/ | |
if (($dns = @parse_url($params)) === FALSE) | |
{ | |
show_error('Invalid DB Connection String'); | |
} | |
$params = array( | |
'dbdriver' => $dns['scheme'], | |
'hostname' => (isset($dns['host'])) ? rawurldecode($dns['host']) : '', | |
'username' => (isset($dns['user'])) ? rawurldecode($dns['user']) : '', | |
'password' => (isset($dns['pass'])) ? rawurldecode($dns['pass']) : '', | |
'database' => (isset($dns['path'])) ? rawurldecode(substr($dns['path'], 1)) : '' | |
); | |
// were additional config items set? | |
if (isset($dns['query'])) | |
{ | |
parse_str($dns['query'], $extra); | |
foreach ($extra as $key => $val) | |
{ | |
// booleans please | |
if (strtoupper($val) == "TRUE") | |
{ | |
$val = TRUE; | |
} | |
elseif (strtoupper($val) == "FALSE") | |
{ | |
$val = FALSE; | |
} | |
$params[$key] = $val; | |
} | |
} | |
} | |
// No DB specified yet? Beat them senseless... | |
if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '') | |
{ | |
show_error('You have not selected a database type to connect to.'); | |
} | |
// Load the DB classes. Note: Since the active record class is optional | |
// we need to dynamically create a class that extends proper parent class | |
// based on whether we're using the active record class or not. | |
// Kudos to Paul for discovering this clever use of eval() | |
if ($active_record_override !== NULL) | |
{ | |
$active_record = $active_record_override; | |
} | |
require_once(BASEPATH.'database/DB_driver.php'); | |
if ( ! isset($active_record) OR $active_record == TRUE) | |
{ | |
// Check for a custom active record class in application/core | |
$my_active_record = config_item('subclass_prefix').'DB_active_rec'; | |
$my_active_record_file = APPPATH.'core/'.$my_active_record.EXT; | |
if (file_exists($my_active_record_file)) | |
{ | |
require_once(BASEPATH.'database/DB_active_rec.php'); | |
require_once($my_active_record_file); | |
if ( ! class_exists('CI_DB')) | |
{ | |
eval('class CI_DB extends '.config_item('subclass_prefix').'DB_active_record { }'); | |
} | |
} | |
else | |
{ | |
require_once(BASEPATH.'database/DB_active_rec.php'); | |
if ( ! class_exists('CI_DB')) | |
{ | |
eval('class CI_DB extends CI_DB_active_record { }'); | |
} | |
} | |
} | |
else | |
{ | |
if ( ! class_exists('CI_DB')) | |
{ | |
eval('class CI_DB extends CI_DB_driver { }'); | |
} | |
} | |
require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php'); | |
// Instantiate the DB adapter | |
$driver = 'CI_DB_'.$params['dbdriver'].'_driver'; | |
$DB = new $driver($params); | |
if ($DB->autoinit == TRUE) | |
{ | |
$DB->initialize(); | |
} | |
if (isset($params['stricton']) && $params['stricton'] == TRUE) | |
{ | |
$DB->query('SET SESSION sql_mode="STRICT_ALL_TABLES"'); | |
} | |
return $DB; | |
} | |
-------------------------------------- | |
/application/core/MY_DB_active_rec.php | |
-------------------------------------- | |
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); | |
class MY_DB_active_record extends CI_DB_active_record { | |
/** | |
* Join | |
* | |
* Generates the JOIN portion of the query | |
* | |
* @param string | |
* @param string the join condition | |
* @param string the type of join | |
* @return object | |
*/ | |
public function join($table, $cond, $type = '') | |
{ | |
if ($type != '') | |
{ | |
$type = strtoupper(trim($type)); | |
if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'))) | |
{ | |
$type = ''; | |
} | |
else | |
{ | |
$type .= ' '; | |
} | |
} | |
// Extract any aliases that might exist. We use this information | |
// in the _protect_identifiers to know whether to add a table prefix | |
$this->_track_aliases($table); | |
// 1. if $cond contains :: chars then separate code with it | |
// 2. if not, use the default preg_match | |
if( strpos($cond, '::') > 0) | |
{ | |
if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match)) | |
{ | |
// 1. extract typecast from $match[3] | |
$t = explode('=', $match[3]); | |
$typecast = trim($t[0]); | |
// 2. remove 'typecast =' from $match[3] | |
$match[3] = trim($t[1]); | |
// 3. replace $match[2] content with = | |
$match[2] = ' = '; | |
$match[1] = $this->_protect_identifiers($match[1]); | |
$match[3] = $this->_protect_identifiers($match[3]); | |
// 4. add :: and typecast to the end of $match[1] | |
$match[1] .= '::'.$typecast; | |
$cond = $match[1].$match[2].$match[3]; | |
} | |
} | |
else | |
{ // Strip apart the condition and protect the identifiers | |
if (preg_match('/([\w\.]+)([\W\s]+)(.+)/', $cond, $match)) | |
{ | |
$match[1] = $this->_protect_identifiers($match[1]); | |
$match[3] = $this->_protect_identifiers($match[3]); | |
$cond = $match[1].$match[2].$match[3]; | |
//debug($cond); | |
} | |
} | |
// Assemble the JOIN statement | |
$join = $type.'JOIN '.$this->_protect_identifiers($table, TRUE, NULL, FALSE).' ON '.$cond; | |
$this->ar_join[] = $join; | |
if ($this->ar_caching === TRUE) | |
{ | |
$this->ar_cache_join[] = $join; | |
$this->ar_cache_exists[] = 'join'; | |
} | |
return $this; | |
} | |
} | |
/* End of file MY_DB_active_rec.php */ | |
/* Location: ./application/core/MY_DB_active_rec.php */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment