Is there a way to catch all queries and modify them before being sent to the db outside of modifying DB_active_record.php
? This would be ideal, though I'm not averse to modifying this file if it's the only option.
I could just call this stuff from the models, but would feel better if this was something that was done in the background so as not to leave room for forgetting when and where it's happening; it'd be best to have it done in the background.
I'm using a library to encrypt query data. In the lib, I'm checking for certain keys to not encrypt, so it's not just a matter of encrypting all data, but some data in each query.
For example, modifying insert()
like so:
function insert($table = '', $set = NULL)
{
if ( ! is_null($set))
{
$this->CI =& get_instance();
$this->CI->load->library('my_encrypt');
$set = $this->CI->my_encrypt->encrypt_query($set);
$this->set($set);
}
works correctly to encrypt the data before sending to the db. However, this does nothing for updates/sets nor decryption.
Is there a way to set up an intermediary something or other that acts as a go-between between models and active record where I could encrypt and decrypt the relevant data before sending it on to AR or back to the model?
Thanks.
UPDATE:
So following the guide below, I was able to get this working. I'm using pyroCMS (ver. 1.3.2 community; CI version 2.0.2) which had already done some of the legwork.
Heres what I did.
system/cms/core/MY_Loader.php
extends MX_loader
which extends CI_Loader
; so MX_Loader
is what needs to be modified.
system/cms/libraries/MX/Loader.php
change public function database()
to:
public function database($params = '', $return = FALSE, $active_record = NULL) {
log_message('debug', 'db loader from MX/Loader');
// 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;
}
require_once(BASEPATH.'database/DB'.EXT);
// Load the DB class
$db =& DB($params, $active_record);
//get the driver name, set its path and load er up
$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;
}
CI::$APP->db = DB($params, $active_record);
return CI::$APP->db;
}
The important difference here from the article linked in the accepted answer is the setting of the db vars as pyro does it differently from regular CI.
Then in system/cms/core
add the customized driver file MY_DB_mysql_driver.php
. This will then be loaded and these methods will be available in all models. Also, methods in here using the same name as in DB_active_rec.php
will take precedence. e.g. adding an insert
method in MY_DB_mysql_driver.php will override the insert method in DB_active_rec.php
.