From a8c2551be2b1422ea3a5723a5fbbe48515c04fb0 Mon Sep 17 00:00:00 2001 From: Eike Foken Date: Tue, 13 Sep 2011 19:15:50 +0200 Subject: [PATCH] Upgrade to CodeIgniter 2.0.3 --- application/config/autoload.php | 2 +- application/config/user_agents.php | 1 + index.php | 5 +- system/core/CodeIgniter.php | 24 +- system/core/Common.php | 73 ++- system/core/Config.php | 67 +- system/core/Controller.php | 7 +- system/core/Exceptions.php | 4 +- system/core/Hooks.php | 8 +- system/core/Input.php | 2 +- system/core/Lang.php | 12 +- system/core/Loader.php | 272 ++++---- system/core/Output.php | 6 +- system/core/Router.php | 14 +- system/core/Security.php | 18 +- system/core/URI.php | 12 +- system/database/DB.php | 12 +- system/database/DB_active_rec.php | 300 ++++----- system/database/DB_driver.php | 6 +- system/database/DB_result.php | 95 +-- .../database/drivers/mysql/mysql_driver.php | 17 +- system/database/drivers/mysql/mysql_forge.php | 8 +- .../database/drivers/mysqli/mysqli_driver.php | 17 +- .../database/drivers/mysqli/mysqli_forge.php | 8 +- .../drivers/postgre/postgre_driver.php | 18 + system/database/drivers/sqlsrv/index.html | 10 + .../database/drivers/sqlsrv/sqlsrv_driver.php | 598 ++++++++++++++++++ .../database/drivers/sqlsrv/sqlsrv_forge.php | 248 ++++++++ .../database/drivers/sqlsrv/sqlsrv_result.php | 169 +++++ .../drivers/sqlsrv/sqlsrv_utility.php | 88 +++ system/fonts/texb.ttf | Bin 152992 -> 143830 bytes system/helpers/download_helper.php | 8 +- system/helpers/file_helper.php | 8 +- system/helpers/form_helper.php | 28 +- system/helpers/html_helper.php | 17 +- system/helpers/inflector_helper.php | 113 ++-- system/helpers/smiley_helper.php | 8 +- system/helpers/text_helper.php | 8 +- system/helpers/url_helper.php | 11 +- system/language/english/profiler_lang.php | 3 + .../libraries/Cache/drivers/Cache_dummy.php | 24 +- system/libraries/Calendar.php | 2 +- system/libraries/Cart.php | 4 +- system/libraries/Driver.php | 12 +- system/libraries/Email.php | 46 +- system/libraries/Encrypt.php | 2 +- system/libraries/Form_validation.php | 6 +- system/libraries/Log.php | 2 +- system/libraries/Pagination.php | 2 +- system/libraries/Profiler.php | 78 ++- system/libraries/Session.php | 8 +- system/libraries/Upload.php | 8 +- system/libraries/User_agent.php | 8 +- 53 files changed, 1949 insertions(+), 578 deletions(-) create mode 100755 system/database/drivers/sqlsrv/index.html create mode 100755 system/database/drivers/sqlsrv/sqlsrv_driver.php create mode 100755 system/database/drivers/sqlsrv/sqlsrv_forge.php create mode 100755 system/database/drivers/sqlsrv/sqlsrv_result.php create mode 100755 system/database/drivers/sqlsrv/sqlsrv_utility.php diff --git a/application/config/autoload.php b/application/config/autoload.php index f667d20..3fadc5b 100755 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -37,7 +37,7 @@ | */ -$autoload['packages'] = array(APPPATH.'third_party'); +$autoload['packages'] = array(); /* diff --git a/application/config/user_agents.php b/application/config/user_agents.php index cd1f904..0c44ed0 100755 --- a/application/config/user_agents.php +++ b/application/config/user_agents.php @@ -44,6 +44,7 @@ $platforms = array ( 'unix' => 'Unknown Unix OS' ); + // The order of this array should NOT be changed. Many browsers return // multiple browser types so we want to identify the sub-type first. $browsers = array( diff --git a/index.php b/index.php index 6e67c2d..f4ac11a 100755 --- a/index.php +++ b/index.php @@ -98,7 +98,7 @@ if (defined('ENVIRONMENT')) // if your controller is not in a sub-folder within the "controllers" folder // $routing['directory'] = ''; - // The controller class file name. Example: Mycontroller.php + // The controller class file name. Example: Mycontroller // $routing['controller'] = ''; // The controller function you wish to be called. @@ -163,6 +163,7 @@ if (defined('ENVIRONMENT')) define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME)); // The PHP file extension + // this global constant is deprecated. define('EXT', '.php'); // Path to the system folder @@ -198,7 +199,7 @@ if (defined('ENVIRONMENT')) * And away we go... * */ -require_once BASEPATH.'core/CodeIgniter'.EXT; +require_once BASEPATH.'core/CodeIgniter.php'; /* End of file index.php */ /* Location: ./index.php */ \ No newline at end of file diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php index e022e1b..94fecb5 100755 --- a/system/core/CodeIgniter.php +++ b/system/core/CodeIgniter.php @@ -32,7 +32,7 @@ * Define the CodeIgniter Version * ------------------------------------------------------ */ - define('CI_VERSION', '2.0.2'); + define('CI_VERSION', '2.0.3'); /* * ------------------------------------------------------ @@ -46,20 +46,20 @@ * Load the global functions * ------------------------------------------------------ */ - require(BASEPATH.'core/Common'.EXT); + require(BASEPATH.'core/Common.php'); /* * ------------------------------------------------------ * Load the framework constants * ------------------------------------------------------ */ - if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants'.EXT)) + if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/constants.php')) { - require(APPPATH.'config/'.ENVIRONMENT.'/constants'.EXT); + require(APPPATH.'config/'.ENVIRONMENT.'/constants.php'); } else { - require(APPPATH.'config/constants'.EXT); + require(APPPATH.'config/constants.php'); } /* @@ -224,7 +224,7 @@ * */ // Load the base controller class - require BASEPATH.'core/Controller'.EXT; + require BASEPATH.'core/Controller.php'; function &get_instance() { @@ -232,20 +232,20 @@ } - if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller'.EXT)) + if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php')) { - require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller'.EXT; + require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'; } // Load the local application controller // Note: The Router class automatically validates the controller path using the router->_validate_request(). // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid. - if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT)) + if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php')) { show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.'); } - include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT); + include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'); // Set a mark point for benchmarking $BM->mark('loading_time:_base_classes_end'); @@ -318,12 +318,12 @@ $method = (isset($x[1]) ? $x[1] : 'index'); if ( ! class_exists($class)) { - if ( ! file_exists(APPPATH.'controllers/'.$class.EXT)) + if ( ! file_exists(APPPATH.'controllers/'.$class.'.php')) { show_404("{$class}/{$method}"); } - include_once(APPPATH.'controllers/'.$class.EXT); + include_once(APPPATH.'controllers/'.$class.'.php'); unset($CI); $CI = new $class(); } diff --git a/system/core/Common.php b/system/core/Common.php index 1aca809..db9fbeb 100755 --- a/system/core/Common.php +++ b/system/core/Common.php @@ -39,6 +39,8 @@ * @param string * @return bool TRUE if the current version is $version or higher */ +if ( ! function_exists('is_php')) +{ function is_php($version = '5.0.0') { static $_is_php; @@ -51,6 +53,7 @@ return $_is_php[$version]; } +} // ------------------------------------------------------------------------ @@ -64,6 +67,8 @@ * @access private * @return void */ +if ( ! function_exists('is_really_writable')) +{ function is_really_writable($file) { // If we're on a Unix server with safe_mode off we call is_writable @@ -96,6 +101,7 @@ fclose($fp); return TRUE; } +} // ------------------------------------------------------------------------ @@ -112,6 +118,8 @@ * @param string the class name prefix * @return object */ +if ( ! function_exists('load_class')) +{ function &load_class($class, $directory = 'libraries', $prefix = 'CI_') { static $_classes = array(); @@ -128,13 +136,13 @@ // thenin the local application/libraries folder foreach (array(BASEPATH, APPPATH) as $path) { - if (file_exists($path.$directory.'/'.$class.EXT)) + if (file_exists($path.$directory.'/'.$class.'.php')) { $name = $prefix.$class; if (class_exists($name) === FALSE) { - require($path.$directory.'/'.$class.EXT); + require($path.$directory.'/'.$class.'.php'); } break; @@ -142,13 +150,13 @@ } // Is the request a class extension? If so we load it too - if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.EXT)) + if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php')) { $name = config_item('subclass_prefix').$class; if (class_exists($name) === FALSE) { - require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.EXT); + require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'); } } @@ -157,7 +165,7 @@ { // Note: We use exit() rather then show_error() in order to avoid a // self-referencing loop with the Excptions class - exit('Unable to locate the specified class: '.$class.EXT); + exit('Unable to locate the specified class: '.$class.'.php'); } // Keep track of what we just loaded @@ -166,6 +174,7 @@ $_classes[$class] = new $name(); return $_classes[$class]; } +} // -------------------------------------------------------------------- @@ -176,6 +185,8 @@ * @access public * @return array */ +if ( ! function_exists('is_loaded')) +{ function is_loaded($class = '') { static $_is_loaded = array(); @@ -187,6 +198,7 @@ return $_is_loaded; } +} // ------------------------------------------------------------------------ @@ -199,6 +211,8 @@ * @access private * @return array */ +if ( ! function_exists('get_config')) +{ function &get_config($replace = array()) { static $_config; @@ -209,9 +223,9 @@ } // Is the config file in the environment folder? - if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config'.EXT)) + if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php')) { - $file_path = APPPATH.'config/config'.EXT; + $file_path = APPPATH.'config/config.php'; } // Fetch the config file @@ -242,6 +256,7 @@ return $_config[0] =& $config; } +} // ------------------------------------------------------------------------ @@ -251,6 +266,8 @@ * @access public * @return mixed */ +if ( ! function_exists('config_item')) +{ function config_item($item) { static $_config_item = array(); @@ -268,6 +285,7 @@ return $_config_item[$item]; } +} // ------------------------------------------------------------------------ @@ -283,12 +301,15 @@ * @access public * @return void */ +if ( ! function_exists('show_error')) +{ function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered') { $_error =& load_class('Exceptions', 'core'); echo $_error->show_error($heading, $message, 'error_general', $status_code); exit; } +} // ------------------------------------------------------------------------ @@ -302,12 +323,15 @@ * @access public * @return void */ +if ( ! function_exists('show_404')) +{ function show_404($page = '', $log_error = TRUE) { $_error =& load_class('Exceptions', 'core'); $_error->show_404($page, $log_error); exit; } +} // ------------------------------------------------------------------------ @@ -320,6 +344,8 @@ * @access public * @return void */ +if ( ! function_exists('log_message')) +{ function log_message($level = 'error', $message, $php_error = FALSE) { static $_log; @@ -332,6 +358,7 @@ $_log =& load_class('Log'); $_log->write_log($level, $message, $php_error); } +} // ------------------------------------------------------------------------ @@ -343,6 +370,8 @@ * @param string * @return void */ +if ( ! function_exists('set_status_header')) +{ function set_status_header($code = 200, $text = '') { $stati = array( @@ -417,6 +446,7 @@ header("HTTP/1.1 {$code} {$text}", TRUE, $code); } } +} // -------------------------------------------------------------------- @@ -434,6 +464,8 @@ * @access private * @return void */ +if ( ! function_exists('_exception_handler')) +{ function _exception_handler($severity, $message, $filepath, $line) { // We don't bother with "strict" notices since they tend to fill up @@ -463,19 +495,22 @@ $_error->log_exception($severity, $message, $filepath, $line); } +} - // -------------------------------------------------------------------- +// -------------------------------------------------------------------- - /** - * Remove Invisible Characters - * - * This prevents sandwiching null characters - * between ascii characters, like Java\0script. - * - * @access public - * @param string - * @return string - */ +/** + * Remove Invisible Characters + * + * This prevents sandwiching null characters + * between ascii characters, like Java\0script. + * + * @access public + * @param string + * @return string + */ +if ( ! function_exists('remove_invisible_characters')) +{ function remove_invisible_characters($str, $url_encoded = TRUE) { $non_displayables = array(); @@ -499,7 +534,7 @@ return $str; } - +} /* End of file Common.php */ /* Location: ./system/core/Common.php */ \ No newline at end of file diff --git a/system/core/Config.php b/system/core/Config.php index 863c5ef..0e6f10e 100755 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -80,7 +80,7 @@ class CI_Config { */ function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) { - $file = ($file == '') ? 'config' : str_replace(EXT, '', $file); + $file = ($file == '') ? 'config' : str_replace('.php', '', $file); $found = FALSE; $loaded = FALSE; @@ -92,7 +92,7 @@ class CI_Config { foreach ($check_locations as $location) { - $file_path = $path.'config/'.$location.EXT; + $file_path = $path.'config/'.$location.'.php'; if (in_array($file_path, $this->is_loaded, TRUE)) { @@ -144,6 +144,7 @@ class CI_Config { $loaded = TRUE; log_message('debug', 'Config file loaded: '.$file_path); + break; } if ($loaded === FALSE) @@ -152,7 +153,7 @@ class CI_Config { { return FALSE; } - show_error('The configuration file '.$file.EXT.' does not exist.'); + show_error('The configuration file '.$file.'.php'.' does not exist.'); } return TRUE; @@ -202,10 +203,7 @@ class CI_Config { // -------------------------------------------------------------------- /** - * Fetch a config file item - adds slash after item - * - * The second parameter allows a slash to be added to the end of - * the item, in the case of a path. + * Fetch a config file item - adds slash after item (if item is not empty) * * @access public * @param string the config item name @@ -218,6 +216,10 @@ class CI_Config { { return FALSE; } + if( trim($this->config[$item]) == '') + { + return ''; + } return rtrim($this->config[$item], '/').'/'; } @@ -226,6 +228,7 @@ class CI_Config { /** * Site URL + * Returns base_url . index_page [. uri_string] * * @access public * @param string the URI string @@ -238,16 +241,50 @@ class CI_Config { return $this->slash_item('base_url').$this->item('index_page'); } + if ($this->item('enable_query_strings') == FALSE) + { + $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix'); + return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix; + } + else + { + return $this->slash_item('base_url').$this->item('index_page').'?'.$this->_uri_string($uri); + } + } + + // ------------------------------------------------------------- + + /** + * Base URL + * Returns base_url [. uri_string] + * + * @access public + * @param string $uri + * @return string + */ + function base_url($uri = '') + { + return $this->slash_item('base_url').ltrim($this->_uri_string($uri),'/'); + } + + // ------------------------------------------------------------- + + /** + * Build URI string for use in Config::site_url() and Config::base_url() + * + * @access protected + * @param $uri + * @return string + */ + protected function _uri_string($uri) + { if ($this->item('enable_query_strings') == FALSE) { if (is_array($uri)) { $uri = implode('/', $uri); } - - $index = $this->item('index_page') == '' ? '' : $this->slash_item('index_page'); - $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix'); - return $this->slash_item('base_url').$index.trim($uri, '/').$suffix; + $uri = trim($uri, '/'); } else { @@ -261,16 +298,14 @@ class CI_Config { $str .= $prefix.$key.'='.$val; $i++; } - $uri = $str; } - - return $this->slash_item('base_url').$this->item('index_page').'?'.$uri; } + return $uri; } // -------------------------------------------------------------------- - + /** * System URL * @@ -326,4 +361,4 @@ class CI_Config { // END CI_Config class /* End of file Config.php */ -/* Location: ./system/core/Config.php */ \ No newline at end of file +/* Location: ./system/core/Config.php */ diff --git a/system/core/Controller.php b/system/core/Controller.php index 469663f..ec86b79 100755 --- a/system/core/Controller.php +++ b/system/core/Controller.php @@ -48,12 +48,9 @@ class CI_Controller { $this->load =& load_class('Loader', 'core'); - $this->load->_base_classes =& is_loaded(); - - $this->load->_ci_autoloader(); - + $this->load->set_base_classes()->ci_autoloader(); + log_message('debug', "Controller Class Initialized"); - } public static function &get_instance() diff --git a/system/core/Exceptions.php b/system/core/Exceptions.php index f565956..bff86a9 100755 --- a/system/core/Exceptions.php +++ b/system/core/Exceptions.php @@ -128,7 +128,7 @@ class CI_Exceptions { ob_end_flush(); } ob_start(); - include(APPPATH.'errors/'.$template.EXT); + include(APPPATH.'errors/'.$template.'.php'); $buffer = ob_get_contents(); ob_end_clean(); return $buffer; @@ -164,7 +164,7 @@ class CI_Exceptions { ob_end_flush(); } ob_start(); - include(APPPATH.'errors/error_php'.EXT); + include(APPPATH.'errors/error_php.php'); $buffer = ob_get_contents(); ob_end_clean(); echo $buffer; diff --git a/system/core/Hooks.php b/system/core/Hooks.php index 24fa105..fd6380f 100755 --- a/system/core/Hooks.php +++ b/system/core/Hooks.php @@ -65,13 +65,13 @@ class CI_Hooks { // Grab the "hooks" definition file. // If there are no hooks, we're done. - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/hooks'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'); } - elseif (is_file(APPPATH.'config/hooks'.EXT)) + elseif (is_file(APPPATH.'config/hooks.php')) { - include(APPPATH.'config/hooks'.EXT); + include(APPPATH.'config/hooks.php'); } diff --git a/system/core/Input.php b/system/core/Input.php index dc7612e..cfbef94 100755 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -672,7 +672,7 @@ class CI_Input { */ public function is_cli_request() { - return (bool) defined('STDIN'); + return (php_sapi_name() == 'cli') or defined('STDIN'); } } diff --git a/system/core/Lang.php b/system/core/Lang.php index 0b926a3..170e6c7 100755 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -51,14 +51,14 @@ class CI_Lang { */ function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '') { - $langfile = str_replace(EXT, '', $langfile); + $langfile = str_replace('.php', '', $langfile); if ($add_suffix == TRUE) { $langfile = str_replace('_lang.', '', $langfile).'_lang'; } - $langfile .= EXT; + $langfile .= '.php'; if (in_array($langfile, $this->is_loaded, TRUE)) { @@ -129,19 +129,19 @@ class CI_Lang { */ function line($line = '') { - $line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; + $value = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; // Because killer robots like unicorns! - if ($line === FALSE) + if ($value === FALSE) { log_message('error', 'Could not find the language line "'.$line.'"'); } - return $line; + return $value; } } // END Language Class /* End of file Lang.php */ -/* Location: ./system/core/Lang.php */ \ No newline at end of file +/* Location: ./system/core/Lang.php */ diff --git a/system/core/Loader.php b/system/core/Loader.php index e75805d..7c8b298 100755 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -29,38 +29,77 @@ class CI_Loader { // All these are set automatically. Don't mess with them. - var $_ci_ob_level; - var $_ci_view_path = ''; - var $_ci_library_paths = array(); - var $_ci_model_paths = array(); - var $_ci_helper_paths = array(); - var $_base_classes = array(); // Set by the controller class - var $_ci_cached_vars = array(); - var $_ci_classes = array(); - var $_ci_loaded_files = array(); - var $_ci_models = array(); - var $_ci_helpers = array(); - var $_ci_varmap = array('unit_test' => 'unit', 'user_agent' => 'agent'); - + protected $_ci_ob_level; + protected $_ci_view_paths = array(); + protected $_ci_library_paths = array(); + protected $_ci_model_paths = array(); + protected $_ci_helper_paths = array(); + protected $_base_classes = array(); // Set by the controller class + protected $_ci_cached_vars = array(); + protected $_ci_classes = array(); + protected $_ci_loaded_files = array(); + protected $_ci_models = array(); + protected $_ci_helpers = array(); + protected $_ci_varmap = array('unit_test' => 'unit', + 'user_agent' => 'agent'); /** * Constructor * * Sets the path to the view files and gets the initial output buffering level - * - * @access public */ - function __construct() + public function __construct() { - $this->_ci_view_path = APPPATH.'views/'; $this->_ci_ob_level = ob_get_level(); $this->_ci_library_paths = array(APPPATH, BASEPATH); $this->_ci_helper_paths = array(APPPATH, BASEPATH); $this->_ci_model_paths = array(APPPATH); - + $this->_ci_view_paths = array(APPPATH.'views/' => TRUE); + log_message('debug', "Loader Class Initialized"); } + // -------------------------------------------------------------------- + + /** + * Set _base_classes variable + * + * This method is called once in CI_Controller. + * + * @param array + * @return object + */ + public function set_base_classes() + { + $this->_base_classes =& is_loaded(); + + return $this; + } + + // -------------------------------------------------------------------- + + /** + * Is Loaded + * + * A utility function to test if a class is in the self::$_ci_classes array. + * This function returns the object name if the class tested for is loaded, + * and returns FALSE if it isn't. + * + * It is mainly used in the form_helper -> _get_validation_object() + * + * @param string class being checked for + * @return mixed class object name on the CI SuperObject or FALSE + */ + public function is_loaded($class) + { + if (isset($this->_ci_classes[$class])) + { + return $this->_ci_classes[$class]; + } + + return FALSE; + } + // -------------------------------------------------------------------- /** @@ -69,13 +108,12 @@ class CI_Loader { * This function lets users load and instantiate classes. * It is designed to be called from a user's app controllers. * - * @access public * @param string the name of the class * @param mixed the optional parameters * @param string an optional object name * @return void */ - function library($library = '', $params = NULL, $object_name = NULL) + public function library($library = '', $params = NULL, $object_name = NULL) { if (is_array($library)) { @@ -107,13 +145,12 @@ class CI_Loader { * * This function lets users load and instantiate models. * - * @access public * @param string the name of the class * @param string name for the model * @param bool database connection * @return void */ - function model($model, $name = '', $db_conn = FALSE) + public function model($model, $name = '', $db_conn = FALSE) { if (is_array($model)) { @@ -161,7 +198,7 @@ class CI_Loader { foreach ($this->_ci_model_paths as $mod_path) { - if ( ! file_exists($mod_path.'models/'.$path.$model.EXT)) + if ( ! file_exists($mod_path.'models/'.$path.$model.'.php')) { continue; } @@ -181,7 +218,7 @@ class CI_Loader { load_class('Model', 'core'); } - require_once($mod_path.'models/'.$path.$model.EXT); + require_once($mod_path.'models/'.$path.$model.'.php'); $model = ucfirst($model); @@ -200,13 +237,12 @@ class 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) + public function database($params = '', $return = FALSE, $active_record = NULL) { // Grab the super object $CI =& get_instance(); @@ -217,7 +253,7 @@ class CI_Loader { return FALSE; } - require_once(BASEPATH.'database/DB'.EXT); + require_once(BASEPATH.'database/DB.php'); if ($return === TRUE) { @@ -237,10 +273,9 @@ class CI_Loader { /** * Load the Utilities Class * - * @access public * @return string */ - function dbutil() + public function dbutil() { if ( ! class_exists('CI_DB')) { @@ -253,8 +288,8 @@ class CI_Loader { // this use is deprecated and strongly discouraged $CI->load->dbforge(); - require_once(BASEPATH.'database/DB_utility'.EXT); - require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT); + require_once(BASEPATH.'database/DB_utility.php'); + require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility.php'); $class = 'CI_DB_'.$CI->db->dbdriver.'_utility'; $CI->dbutil = new $class(); @@ -265,10 +300,9 @@ class CI_Loader { /** * Load the Database Forge Class * - * @access public * @return string */ - function dbforge() + public function dbforge() { if ( ! class_exists('CI_DB')) { @@ -277,8 +311,8 @@ class CI_Loader { $CI =& get_instance(); - require_once(BASEPATH.'database/DB_forge'.EXT); - require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT); + require_once(BASEPATH.'database/DB_forge.php'); + require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php'); $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'; $CI->dbforge = new $class(); @@ -297,13 +331,12 @@ class CI_Loader { * some cases it's advantageous to be able to return data so that * a developer can process it in some way. * - * @access public * @param string * @param array * @param bool * @return void */ - function view($view, $vars = array(), $return = FALSE) + public function view($view, $vars = array(), $return = FALSE) { return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); } @@ -315,12 +348,11 @@ class CI_Loader { * * This is a generic file loader * - * @access public * @param string * @param bool * @return string */ - function file($path, $return = FALSE) + public function file($path, $return = FALSE) { return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); } @@ -333,11 +365,10 @@ class CI_Loader { * Once variables are set they become available within * the controller class and its "view" files. * - * @access public * @param array * @return void */ - function vars($vars = array(), $val = '') + public function vars($vars = array(), $val = '') { if ($val != '' AND is_string($vars)) { @@ -357,16 +388,30 @@ class CI_Loader { // -------------------------------------------------------------------- + /** + * Get Variable + * + * Check if a variable is set and retrieve it. + * + * @param array + * @return void + */ + public function get_var($key) + { + return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL; + } + + // -------------------------------------------------------------------- + /** * Load Helper * * This function loads the specified helper file. * - * @access public * @param mixed * @return void */ - function helper($helpers = array()) + public function helper($helpers = array()) { foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper) { @@ -375,16 +420,16 @@ class CI_Loader { continue; } - $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT; + $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.'.php'; // Is this a helper extension request? if (file_exists($ext_helper)) { - $base_helper = BASEPATH.'helpers/'.$helper.EXT; + $base_helper = BASEPATH.'helpers/'.$helper.'.php'; if ( ! file_exists($base_helper)) { - show_error('Unable to load the requested file: helpers/'.$helper.EXT); + show_error('Unable to load the requested file: helpers/'.$helper.'.php'); } include_once($ext_helper); @@ -398,9 +443,9 @@ class CI_Loader { // Try to load the helper foreach ($this->_ci_helper_paths as $path) { - if (file_exists($path.'helpers/'.$helper.EXT)) + if (file_exists($path.'helpers/'.$helper.'.php')) { - include_once($path.'helpers/'.$helper.EXT); + include_once($path.'helpers/'.$helper.'.php'); $this->_ci_helpers[$helper] = TRUE; log_message('debug', 'Helper loaded: '.$helper); @@ -411,7 +456,7 @@ class CI_Loader { // unable to load the helper if ( ! isset($this->_ci_helpers[$helper])) { - show_error('Unable to load the requested file: helpers/'.$helper.EXT); + show_error('Unable to load the requested file: helpers/'.$helper.'.php'); } } } @@ -424,11 +469,10 @@ class CI_Loader { * This is simply an alias to the above function in case the * user has written the plural form of this function. * - * @access public * @param array * @return void */ - function helpers($helpers = array()) + public function helpers($helpers = array()) { $this->helper($helpers); } @@ -438,12 +482,11 @@ class CI_Loader { /** * Loads a language file * - * @access public * @param array * @param string * @return void */ - function language($file = array(), $lang = '') + public function language($file = array(), $lang = '') { $CI =& get_instance(); @@ -463,11 +506,10 @@ class CI_Loader { /** * Loads a config file * - * @access public * @param string * @return void */ - function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) + public function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) { $CI =& get_instance(); $CI->config->load($file, $use_sections, $fail_gracefully); @@ -485,12 +527,12 @@ class CI_Loader { * @param string an optional object name * @return void */ - function driver($library = '', $params = NULL, $object_name = NULL) + public function driver($library = '', $params = NULL, $object_name = NULL) { if ( ! class_exists('CI_Driver_Library')) { // we aren't instantiating an object here, that'll be done by the Library itself - require BASEPATH.'libraries/Driver'.EXT; + require BASEPATH.'libraries/Driver.php'; } // We can save the loader some time since Drivers will *always* be in a subfolder, @@ -510,18 +552,20 @@ class CI_Loader { * * Prepends a parent path to the library, model, helper, and config path arrays * - * @access public * @param string + * @param boolean * @return void */ - function add_package_path($path) + public function add_package_path($path, $view_cascade=TRUE) { $path = rtrim($path, '/').'/'; - + array_unshift($this->_ci_library_paths, $path); array_unshift($this->_ci_model_paths, $path); array_unshift($this->_ci_helper_paths, $path); + $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths; + // Add config file path $config =& $this->_ci_get_component('config'); array_unshift($config->_config_paths, $path); @@ -534,11 +578,10 @@ class CI_Loader { * * Return a list of all package paths, by default it will ignore BASEPATH. * - * @access public * @param string * @return void */ - function get_package_paths($include_base = FALSE) + public function get_package_paths($include_base = FALSE) { return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths; } @@ -551,11 +594,10 @@ class CI_Loader { * Remove a path from the library, model, and helper path arrays if it exists * If no path is provided, the most recently added path is removed. * - * @access public * @param type * @return type */ - function remove_package_path($path = '', $remove_config_path = TRUE) + public function remove_package_path($path = '', $remove_config_path = TRUE) { $config =& $this->_ci_get_component('config'); @@ -564,12 +606,12 @@ class CI_Loader { $void = array_shift($this->_ci_library_paths); $void = array_shift($this->_ci_model_paths); $void = array_shift($this->_ci_helper_paths); + $void = array_shift($this->_ci_view_paths); $void = array_shift($config->_config_paths); } else { $path = rtrim($path, '/').'/'; - foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var) { if (($key = array_search($path, $this->{$var})) !== FALSE) @@ -577,6 +619,11 @@ class CI_Loader { unset($this->{$var}[$key]); } } + + if (isset($this->_ci_view_paths[$path.'views/'])) + { + unset($this->_ci_view_paths[$path.'views/']); + } if (($key = array_search($path, $config->_config_paths)) !== FALSE) { @@ -588,6 +635,7 @@ class CI_Loader { $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH))); $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH))); $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH))); + $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE)); $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH))); } @@ -600,32 +648,47 @@ class CI_Loader { * Variables are prefixed with _ci_ to avoid symbol collision with * variables made available to view files * - * @access private * @param array * @return void */ - function _ci_load($_ci_data) + protected function _ci_load($_ci_data) { // Set the default data variables foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val) { $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val]; } + + $file_exists = FALSE; // Set the path to the requested file - if ($_ci_path == '') - { - $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); - $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view; - $_ci_path = $this->_ci_view_path.$_ci_file; - } - else + if ($_ci_path != '') { $_ci_x = explode('/', $_ci_path); $_ci_file = end($_ci_x); } + else + { + $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION); + $_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view; - if ( ! file_exists($_ci_path)) + foreach ($this->_ci_view_paths as $view_file => $cascade) + { + if (file_exists($view_file.$_ci_file)) + { + $_ci_path = $view_file.$_ci_file; + $file_exists = TRUE; + break; + } + + if ( ! $cascade) + { + break; + } + } + } + + if ( ! $file_exists && ! file_exists($_ci_path)) { show_error('Unable to load the requested file: '.$_ci_file); } @@ -721,18 +784,17 @@ class CI_Loader { * * This function loads the requested class. * - * @access private * @param string the item that is being loaded * @param mixed any additional parameters * @param string an optional object name * @return void */ - function _ci_load_class($class, $params = NULL, $object_name = NULL) + protected function _ci_load_class($class, $params = NULL, $object_name = NULL) { // Get the class name, and while we're at it trim any slashes. // The directory path can be included as part of the class name, // but we don't want a leading slash - $class = str_replace(EXT, '', trim($class, '/')); + $class = str_replace('.php', '', trim($class, '/')); // Was the path included with the class name? // We look for a slash to determine this @@ -749,12 +811,12 @@ class CI_Loader { // We'll test for both lowercase and capitalized versions of the file name foreach (array(ucfirst($class), strtolower($class)) as $class) { - $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT; + $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php'; // Is this a class extension request? if (file_exists($subclass)) { - $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT; + $baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php'; if ( ! file_exists($baseclass)) { @@ -793,7 +855,7 @@ class CI_Loader { $is_duplicate = FALSE; foreach ($this->_ci_library_paths as $path) { - $filepath = $path.'libraries/'.$subdir.$class.EXT; + $filepath = $path.'libraries/'.$subdir.$class.'.php'; // Does the file exist? No? Bummer... if ( ! file_exists($filepath)) @@ -849,13 +911,12 @@ class CI_Loader { /** * Instantiates a class * - * @access private * @param string * @param string * @param string an optional object name * @return null */ - function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL) + protected function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL) { // Is there an associated config file for this class? Note: these should always be lowercase if ($config === NULL) @@ -872,24 +933,24 @@ class CI_Loader { // We test for both uppercase and lowercase, for servers that // are case-sensitive with regard to file names. Check for environment // first, global next - if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT)) + if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php')) { - include_once($path .'config/'.ENVIRONMENT.'/'.strtolower($class).EXT); + include_once($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'); break; } - elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT)) + elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php')) { - include_once($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).EXT); + include_once($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'); break; } - elseif (file_exists($path .'config/'.strtolower($class).EXT)) + elseif (file_exists($path .'config/'.strtolower($class).'.php')) { - include_once($path .'config/'.strtolower($class).EXT); + include_once($path .'config/'.strtolower($class).'.php'); break; } - elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).EXT)) + elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).'.php')) { - include_once($path .'config/'.ucfirst(strtolower($class)).EXT); + include_once($path .'config/'.ucfirst(strtolower($class)).'.php'); break; } } @@ -959,19 +1020,21 @@ class CI_Loader { * The config/autoload.php file contains an array that permits sub-systems, * libraries, and helpers to be loaded automatically. * - * @access private + * This function is public, as it's used in the CI_Controller class. + * However, there is no reason you should ever needs to use it. + * * @param array * @return void */ - function _ci_autoloader() + public function ci_autoloader() { - if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload'.EXT)) + if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php')) { - include_once(APPPATH.'config/'.ENVIRONMENT.'/autoload'.EXT); + include_once(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'); } else { - include_once(APPPATH.'config/autoload'.EXT); + include_once(APPPATH.'config/autoload.php'); } @@ -1046,11 +1109,10 @@ class CI_Loader { * * Takes an object as input and converts the class variables to array key/vals * - * @access private * @param object * @return array */ - function _ci_object_to_array($object) + protected function _ci_object_to_array($object) { return (is_object($object)) ? get_object_vars($object) : $object; } @@ -1060,10 +1122,9 @@ class CI_Loader { /** * Get a reference to a specific library or model * - * @access private * @return bool */ - function &_ci_get_component($component) + protected function &_ci_get_component($component) { $CI =& get_instance(); return $CI->$component; @@ -1076,29 +1137,26 @@ class CI_Loader { * * This function preps the name of various items to make loading them more reliable. * - * @access private * @param mixed * @return array */ - function _ci_prep_filename($filename, $extension) + protected function _ci_prep_filename($filename, $extension) { if ( ! is_array($filename)) { - return array(strtolower(str_replace(EXT, '', str_replace($extension, '', $filename)).$extension)); + return array(strtolower(str_replace('.php', '', str_replace($extension, '', $filename)).$extension)); } else { foreach ($filename as $key => $val) { - $filename[$key] = strtolower(str_replace(EXT, '', str_replace($extension, '', $val)).$extension); + $filename[$key] = strtolower(str_replace('.php', '', str_replace($extension, '', $val)).$extension); } return $filename; } } - - } /* End of file Loader.php */ -/* Location: ./system/core/Loader.php */ +/* Location: ./system/core/Loader.php */ \ No newline at end of file diff --git a/system/core/Output.php b/system/core/Output.php index 45a82f3..05ace91 100755 --- a/system/core/Output.php +++ b/system/core/Output.php @@ -42,13 +42,13 @@ class CI_Output { $this->_zlib_oc = @ini_get('zlib.output_compression'); // Get mime types for later - if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT)) + if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) { - include APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT; + include APPPATH.'config/'.ENVIRONMENT.'/mimes.php'; } else { - include APPPATH.'config/mimes'.EXT; + include APPPATH.'config/mimes.php'; } diff --git a/system/core/Router.php b/system/core/Router.php index d451aab..5e92a04 100755 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -87,13 +87,13 @@ class CI_Router { } // Load the routes.php file. - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/routes.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/routes'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/routes.php'); } - elseif (is_file(APPPATH.'config/routes'.EXT)) + elseif (is_file(APPPATH.'config/routes.php')) { - include(APPPATH.'config/routes'.EXT); + include(APPPATH.'config/routes.php'); } $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route; @@ -227,7 +227,7 @@ class CI_Router { } // Does the requested controller exist in the root folder? - if (file_exists(APPPATH.'controllers/'.$segments[0].EXT)) + if (file_exists(APPPATH.'controllers/'.$segments[0].'.php')) { return $segments; } @@ -242,7 +242,7 @@ class CI_Router { if (count($segments) > 0) { // Does the requested controller exist in the sub-folder? - if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT)) + if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].'.php')) { show_404($this->fetch_directory().$segments[0]); } @@ -264,7 +264,7 @@ class CI_Router { } // Does the default controller exist in the sub-folder? - if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT)) + if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.'.php')) { $this->directory = ''; return array(); diff --git a/system/core/Security.php b/system/core/Security.php index ceef977..3617cad 100755 --- a/system/core/Security.php +++ b/system/core/Security.php @@ -58,8 +58,20 @@ class CI_Security { */ public function __construct() { - // Append application specific cookie prefix to token name - $this->_csrf_cookie_name = (config_item('cookie_prefix')) ? config_item('cookie_prefix').$this->_csrf_token_name : $this->_csrf_token_name; + // CSRF config + foreach(array('csrf_expire', 'csrf_token_name', 'csrf_cookie_name') as $key) + { + if (FALSE !== ($val = config_item($key))) + { + $this->{'_'.$key} = $val; + } + } + + // Append application specific cookie prefix + if (config_item('cookie_prefix')) + { + $this->_csrf_cookie_name = config_item('cookie_prefix').$this->_csrf_cookie_name; + } // Set the CSRF hash $this->_csrf_set_hash(); @@ -817,4 +829,4 @@ class CI_Security { // END Security Class /* End of file Security.php */ -/* Location: ./system/libraries/Security.php */ \ No newline at end of file +/* Location: ./system/libraries/Security.php */ diff --git a/system/core/URI.php b/system/core/URI.php index 80dc62e..20f0f00 100755 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -62,7 +62,7 @@ class CI_URI { if (strtoupper($this->config->item('uri_protocol')) == 'AUTO') { // Is the request coming from the command line? - if (defined('STDIN')) + if (php_sapi_name() == 'cli' or defined('STDIN')) { $this->_set_uri_string($this->_parse_cli_args()); return; @@ -120,7 +120,7 @@ class CI_URI { $path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri); $this->_set_uri_string($path); } - + // -------------------------------------------------------------------- /** @@ -133,7 +133,7 @@ class CI_URI { { // Filter out control characters $str = remove_invisible_characters($str, FALSE); - + // If the URI contains only a slash we'll kill it $this->uri_string = ($str == '/') ? '' : $str; } @@ -151,7 +151,7 @@ class CI_URI { */ private function _detect_uri() { - if ( ! isset($_SERVER['REQUEST_URI'])) + if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME'])) { return ''; } @@ -184,12 +184,12 @@ class CI_URI { $_SERVER['QUERY_STRING'] = ''; $_GET = array(); } - + if ($uri == '/' || empty($uri)) { return '/'; } - + $uri = parse_url($uri, PHP_URL_PATH); // Do some final cleaning of the URI and return it diff --git a/system/database/DB.php b/system/database/DB.php index 8bf1ba8..33207d8 100755 --- a/system/database/DB.php +++ b/system/database/DB.php @@ -28,11 +28,11 @@ function &DB($params = '', $active_record_override = NULL) 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'.EXT)) + if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/database.php')) { - if ( ! file_exists($file_path = APPPATH.'config/database'.EXT)) + if ( ! file_exists($file_path = APPPATH.'config/database.php')) { - show_error('The configuration file database'.EXT.' does not exist.'); + show_error('The configuration file database.php does not exist.'); } } @@ -116,11 +116,11 @@ function &DB($params = '', $active_record_override = NULL) $active_record = $active_record_override; } - require_once(BASEPATH.'database/DB_driver'.EXT); + require_once(BASEPATH.'database/DB_driver.php'); if ( ! isset($active_record) OR $active_record == TRUE) { - require_once(BASEPATH.'database/DB_active_rec'.EXT); + require_once(BASEPATH.'database/DB_active_rec.php'); if ( ! class_exists('CI_DB')) { @@ -135,7 +135,7 @@ function &DB($params = '', $active_record_override = NULL) } } - require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT); + require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver.php'); // Instantiate the DB adapter $driver = 'CI_DB_'.$params['dbdriver'].'_driver'; diff --git a/system/database/DB_active_rec.php b/system/database/DB_active_rec.php index db84713..2af3553 100755 --- a/system/database/DB_active_rec.php +++ b/system/database/DB_active_rec.php @@ -58,7 +58,9 @@ class CI_DB_active_record extends CI_DB_driver { var $ar_cache_having = array(); var $ar_cache_orderby = array(); var $ar_cache_set = array(); - + + var $ar_no_escape = array(); + var $ar_cache_no_escape = array(); // -------------------------------------------------------------------- @@ -67,18 +69,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Generates the SELECT portion of the query * - * @access public * @param string * @return object */ - function select($select = '*', $escape = NULL) + public function select($select = '*', $escape = NULL) { - // Set the global value if this was sepecified - if (is_bool($escape)) - { - $this->_protect_identifiers = $escape; - } - if (is_string($select)) { $select = explode(',', $select); @@ -91,11 +86,13 @@ class CI_DB_active_record extends CI_DB_driver { if ($val != '') { $this->ar_select[] = $val; + $this->ar_no_escape[] = $escape; if ($this->ar_caching === TRUE) { $this->ar_cache_select[] = $val; $this->ar_cache_exists[] = 'select'; + $this->ar_cache_no_escape[] = $escape; } } } @@ -109,12 +106,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Generates a SELECT MAX(field) portion of a query * - * @access public * @param string the field * @param string an alias * @return object */ - function select_max($select = '', $alias = '') + public function select_max($select = '', $alias = '') { return $this->_max_min_avg_sum($select, $alias, 'MAX'); } @@ -126,12 +122,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Generates a SELECT MIN(field) portion of a query * - * @access public * @param string the field * @param string an alias * @return object */ - function select_min($select = '', $alias = '') + public function select_min($select = '', $alias = '') { return $this->_max_min_avg_sum($select, $alias, 'MIN'); } @@ -143,12 +138,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Generates a SELECT AVG(field) portion of a query * - * @access public * @param string the field * @param string an alias * @return object */ - function select_avg($select = '', $alias = '') + public function select_avg($select = '', $alias = '') { return $this->_max_min_avg_sum($select, $alias, 'AVG'); } @@ -160,12 +154,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Generates a SELECT SUM(field) portion of a query * - * @access public * @param string the field * @param string an alias * @return object */ - function select_sum($select = '', $alias = '') + public function select_sum($select = '', $alias = '') { return $this->_max_min_avg_sum($select, $alias, 'SUM'); } @@ -180,12 +173,11 @@ class CI_DB_active_record extends CI_DB_driver { * select_avg() * select_sum() * - * @access public * @param string the field * @param string an alias * @return object */ - function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX') + protected function _max_min_avg_sum($select = '', $alias = '', $type = 'MAX') { if ( ! is_string($select) OR $select == '') { @@ -222,11 +214,10 @@ class CI_DB_active_record extends CI_DB_driver { /** * Determines the alias name based on the table * - * @access private * @param string * @return string */ - function _create_alias_from_table($item) + protected function _create_alias_from_table($item) { if (strpos($item, '.') !== FALSE) { @@ -243,11 +234,10 @@ class CI_DB_active_record extends CI_DB_driver { * * Sets a flag which tells the query string compiler to add DISTINCT * - * @access public * @param bool * @return object */ - function distinct($val = TRUE) + public function distinct($val = TRUE) { $this->ar_distinct = (is_bool($val)) ? $val : TRUE; return $this; @@ -260,11 +250,10 @@ class CI_DB_active_record extends CI_DB_driver { * * Generates the FROM portion of the query * - * @access public * @param mixed can be a string or array * @return object */ - function from($from) + public function from($from) { foreach ((array)$from as $val) { @@ -313,13 +302,12 @@ class CI_DB_active_record extends CI_DB_driver { * * Generates the JOIN portion of the query * - * @access public * @param string * @param string the join condition * @param string the type of join * @return object */ - function join($table, $cond, $type = '') + public function join($table, $cond, $type = '') { if ($type != '') { @@ -369,12 +357,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates the WHERE portion of the query. Separates * multiple calls with AND * - * @access public * @param mixed * @param mixed * @return object */ - function where($key, $value = NULL, $escape = TRUE) + public function where($key, $value = NULL, $escape = TRUE) { return $this->_where($key, $value, 'AND ', $escape); } @@ -387,12 +374,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates the WHERE portion of the query. Separates * multiple calls with OR * - * @access public * @param mixed * @param mixed * @return object */ - function or_where($key, $value = NULL, $escape = TRUE) + public function or_where($key, $value = NULL, $escape = TRUE) { return $this->_where($key, $value, 'OR ', $escape); } @@ -402,15 +388,14 @@ class CI_DB_active_record extends CI_DB_driver { /** * Where * - * Called by where() or orwhere() + * Called by where() or or_where() * - * @access private * @param mixed * @param mixed * @param string * @return object */ - function _where($key, $value = NULL, $type = 'AND ', $escape = NULL) + protected function _where($key, $value = NULL, $type = 'AND ', $escape = NULL) { if ( ! is_array($key)) { @@ -441,10 +426,10 @@ class CI_DB_active_record extends CI_DB_driver { $v = ' '.$this->escape($v); } - + if ( ! $this->_has_operator($k)) { - $k .= ' ='; + $k .= ' = '; } } else @@ -473,12 +458,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a WHERE field IN ('item', 'item') SQL query joined with * AND if appropriate * - * @access public * @param string The field to search * @param array The values searched on * @return object */ - function where_in($key = NULL, $values = NULL) + public function where_in($key = NULL, $values = NULL) { return $this->_where_in($key, $values); } @@ -491,12 +475,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a WHERE field IN ('item', 'item') SQL query joined with * OR if appropriate * - * @access public * @param string The field to search * @param array The values searched on * @return object */ - function or_where_in($key = NULL, $values = NULL) + public function or_where_in($key = NULL, $values = NULL) { return $this->_where_in($key, $values, FALSE, 'OR '); } @@ -509,12 +492,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a WHERE field NOT IN ('item', 'item') SQL query joined * with AND if appropriate * - * @access public * @param string The field to search * @param array The values searched on * @return object */ - function where_not_in($key = NULL, $values = NULL) + public function where_not_in($key = NULL, $values = NULL) { return $this->_where_in($key, $values, TRUE); } @@ -527,12 +509,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a WHERE field NOT IN ('item', 'item') SQL query joined * with OR if appropriate * - * @access public * @param string The field to search * @param array The values searched on * @return object */ - function or_where_not_in($key = NULL, $values = NULL) + public function or_where_not_in($key = NULL, $values = NULL) { return $this->_where_in($key, $values, TRUE, 'OR '); } @@ -544,14 +525,13 @@ class CI_DB_active_record extends CI_DB_driver { * * Called by where_in, where_in_or, where_not_in, where_not_in_or * - * @access public * @param string The field to search * @param array The values searched on * @param boolean If the statement would be IN or NOT IN * @param string * @return object */ - function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ') + protected function _where_in($key = NULL, $values = NULL, $not = FALSE, $type = 'AND ') { if ($key === NULL OR $values === NULL) { @@ -594,12 +574,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a %LIKE% portion of the query. Separates * multiple calls with AND * - * @access public * @param mixed * @param mixed * @return object */ - function like($field, $match = '', $side = 'both') + public function like($field, $match = '', $side = 'both') { return $this->_like($field, $match, 'AND ', $side); } @@ -612,12 +591,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a NOT LIKE portion of the query. Separates * multiple calls with AND * - * @access public * @param mixed * @param mixed * @return object */ - function not_like($field, $match = '', $side = 'both') + public function not_like($field, $match = '', $side = 'both') { return $this->_like($field, $match, 'AND ', $side, 'NOT'); } @@ -630,12 +608,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a %LIKE% portion of the query. Separates * multiple calls with OR * - * @access public * @param mixed * @param mixed * @return object */ - function or_like($field, $match = '', $side = 'both') + public function or_like($field, $match = '', $side = 'both') { return $this->_like($field, $match, 'OR ', $side); } @@ -648,12 +625,11 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a NOT LIKE portion of the query. Separates * multiple calls with OR * - * @access public * @param mixed * @param mixed * @return object */ - function or_not_like($field, $match = '', $side = 'both') + public function or_not_like($field, $match = '', $side = 'both') { return $this->_like($field, $match, 'OR ', $side, 'NOT'); } @@ -665,13 +641,12 @@ class CI_DB_active_record extends CI_DB_driver { * * Called by like() or orlike() * - * @access private * @param mixed * @param mixed * @param string * @return object */ - function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '') + protected function _like($field, $match = '', $type = 'AND ', $side = 'both', $not = '') { if ( ! is_array($field)) { @@ -721,11 +696,10 @@ class CI_DB_active_record extends CI_DB_driver { /** * GROUP BY * - * @access public * @param string * @return object */ - function group_by($by) + public function group_by($by) { if (is_string($by)) { @@ -757,12 +731,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Separates multiple calls with AND * - * @access public * @param string * @param string * @return object */ - function having($key, $value = '', $escape = TRUE) + public function having($key, $value = '', $escape = TRUE) { return $this->_having($key, $value, 'AND ', $escape); } @@ -774,12 +747,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Separates multiple calls with OR * - * @access public * @param string * @param string * @return object */ - function or_having($key, $value = '', $escape = TRUE) + public function or_having($key, $value = '', $escape = TRUE) { return $this->_having($key, $value, 'OR ', $escape); } @@ -791,12 +763,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Called by having() or or_having() * - * @access private * @param string * @param string * @return object */ - function _having($key, $value = '', $type = 'AND ', $escape = TRUE) + protected function _having($key, $value = '', $type = 'AND ', $escape = TRUE) { if ( ! is_array($key)) { @@ -819,7 +790,7 @@ class CI_DB_active_record extends CI_DB_driver { if ($v != '') { - $v = ' '.$this->escape_str($v); + $v = ' '.$this->escape($v); } $this->ar_having[] = $prefix.$k.$v; @@ -838,12 +809,11 @@ class CI_DB_active_record extends CI_DB_driver { /** * Sets the ORDER BY value * - * @access public * @param string * @param string direction: asc or desc * @return object */ - function order_by($orderby, $direction = '') + public function order_by($orderby, $direction = '') { if (strtolower($direction) == 'random') { @@ -894,12 +864,11 @@ class CI_DB_active_record extends CI_DB_driver { /** * Sets the LIMIT value * - * @access public * @param integer the limit value * @param integer the offset value * @return object */ - function limit($value, $offset = '') + public function limit($value, $offset = '') { $this->ar_limit = $value; @@ -916,11 +885,10 @@ class CI_DB_active_record extends CI_DB_driver { /** * Sets the OFFSET value * - * @access public * @param integer the offset value * @return object */ - function offset($offset) + public function offset($offset) { $this->ar_offset = $offset; return $this; @@ -931,13 +899,12 @@ class CI_DB_active_record extends CI_DB_driver { /** * The "set" function. Allows key/value pairs to be set for inserting or updating * - * @access public * @param mixed * @param string * @param boolean * @return object */ - function set($key, $value = '', $escape = TRUE) + public function set($key, $value = '', $escape = TRUE) { $key = $this->_object_to_array($key); @@ -969,13 +936,12 @@ class CI_DB_active_record extends CI_DB_driver { * Compiles the select statement based on the other functions called * and runs the query * - * @access public * @param string the table * @param string the limit clause * @param string the offset clause * @return object */ - function get($table = '', $limit = null, $offset = null) + public function get($table = '', $limit = null, $offset = null) { if ($table != '') { @@ -1001,11 +967,10 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a platform-specific query string that counts all records * returned by an Active Record query. * - * @access public * @param string * @return string */ - function count_all_results($table = '') + public function count_all_results($table = '') { if ($table != '') { @@ -1034,13 +999,12 @@ class CI_DB_active_record extends CI_DB_driver { * * Allows the where clause, limit and offset to be added directly * - * @access public * @param string the where clause * @param string the limit clause * @param string the offset clause * @return object */ - function get_where($table = '', $where = null, $limit = null, $offset = null) + public function get_where($table = '', $where = null, $limit = null, $offset = null) { if ($table != '') { @@ -1071,12 +1035,11 @@ class CI_DB_active_record extends CI_DB_driver { * * Compiles batch insert strings and runs the queries * - * @access public * @param string the table to retrieve the results from * @param array an associative array of insert values * @return object */ - function insert_batch($table = '', $set = NULL) + public function insert_batch($table = '', $set = NULL) { if ( ! is_null($set)) { @@ -1129,14 +1092,12 @@ class CI_DB_active_record extends CI_DB_driver { /** * The "set_insert_batch" function. Allows key/value pairs to be set for batch inserts * - * @access public * @param mixed * @param string * @param boolean * @return object */ - - function set_insert_batch($key, $value = '', $escape = TRUE) + public function set_insert_batch($key, $value = '', $escape = TRUE) { $key = $this->_object_to_array_batch($key); @@ -1191,8 +1152,7 @@ class CI_DB_active_record extends CI_DB_driver { * * Compiles an insert string and runs the query * - * @access public - * @param string the table to retrieve the results from + * @param string the table to insert data into * @param array an associative array of insert values * @return object */ @@ -1232,7 +1192,18 @@ class CI_DB_active_record extends CI_DB_driver { return $this->query($sql); } - function replace($table = '', $set = NULL) + // -------------------------------------------------------------------- + + /** + * Replace + * + * Compiles an replace into string and runs the query + * + * @param string the table to replace data into + * @param array an associative array of insert values + * @return object + */ + public function replace($table = '', $set = NULL) { if ( ! is_null($set)) { @@ -1275,13 +1246,12 @@ class CI_DB_active_record extends CI_DB_driver { * * Compiles an update string and runs the query * - * @access public * @param string the table to retrieve the results from * @param array an associative array of update values * @param mixed the where clause * @return object */ - function update($table = '', $set = NULL, $where = NULL, $limit = NULL) + public function update($table = '', $set = NULL, $where = NULL, $limit = NULL) { // Combine any cached components with the current statements $this->_merge_cache(); @@ -1338,13 +1308,12 @@ class CI_DB_active_record extends CI_DB_driver { * * Compiles an update string and runs the query * - * @access public * @param string the table to retrieve the results from * @param array an associative array of update values * @param string the where key * @return object */ - function update_batch($table = '', $set = NULL, $index = NULL) + public function update_batch($table = '', $set = NULL, $index = NULL) { // Combine any cached components with the current statements $this->_merge_cache(); @@ -1404,14 +1373,12 @@ class CI_DB_active_record extends CI_DB_driver { /** * The "set_update_batch" function. Allows key/value pairs to be set for batch updating * - * @access public * @param array * @param string * @param boolean * @return object */ - - function set_update_batch($key, $index = '', $escape = TRUE) + public function set_update_batch($key, $index = '', $escape = TRUE) { $key = $this->_object_to_array_batch($key); @@ -1464,11 +1431,10 @@ class CI_DB_active_record extends CI_DB_driver { * * Compiles a delete string and runs "DELETE FROM table" * - * @access public * @param string the table to empty * @return object */ - function empty_table($table = '') + public function empty_table($table = '') { if ($table == '') { @@ -1504,11 +1470,10 @@ class CI_DB_active_record extends CI_DB_driver { * If the database does not support the truncate() command * This function maps to "DELETE FROM table" * - * @access public * @param string the table to truncate * @return object */ - function truncate($table = '') + public function truncate($table = '') { if ($table == '') { @@ -1542,14 +1507,13 @@ class CI_DB_active_record extends CI_DB_driver { * * Compiles a delete string and runs the query * - * @access public * @param mixed the table(s) to delete from. String or array * @param mixed the where clause * @param mixed the limit clause * @param boolean * @return object */ - function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE) + public function delete($table = '', $where = '', $limit = NULL, $reset_data = TRUE) { // Combine any cached components with the current statements $this->_merge_cache(); @@ -1619,11 +1583,10 @@ class CI_DB_active_record extends CI_DB_driver { * * Prepends a database prefix if one exists in configuration * - * @access public * @param string the table * @return string */ - function dbprefix($table = '') + public function dbprefix($table = '') { if ($table == '') { @@ -1635,16 +1598,30 @@ class CI_DB_active_record extends CI_DB_driver { // -------------------------------------------------------------------- + /** + * Set DB Prefix + * + * Set's the DB Prefix to something new without needing to reconnect + * + * @param string the prefix + * @return string + */ + public function set_dbprefix($prefix = '') + { + return $this->dbprefix = $prefix; + } + + // -------------------------------------------------------------------- + /** * Track Aliases * * Used to track SQL statements written with aliased tables. * - * @access private * @param string The table to inspect * @return string */ - function _track_aliases($table) + protected function _track_aliases($table) { if (is_array($table)) { @@ -1687,10 +1664,9 @@ class CI_DB_active_record extends CI_DB_driver { * Generates a query string based on which functions were used. * Should not be called directly. The get() function calls it. * - * @access private * @return string */ - function _compile_select($select_override = FALSE) + protected function _compile_select($select_override = FALSE) { // Combine any cached components with the current statements $this->_merge_cache(); @@ -1718,7 +1694,8 @@ class CI_DB_active_record extends CI_DB_driver { // is because until the user calls the from() function we don't know if there are aliases foreach ($this->ar_select as $key => $val) { - $this->ar_select[$key] = $this->_protect_identifiers($val); + $no_escape = isset($this->ar_no_escape[$key]) ? $this->ar_no_escape[$key] : NULL; + $this->ar_select[$key] = $this->_protect_identifiers($val, FALSE, $no_escape); } $sql .= implode(', ', $this->ar_select); @@ -1753,9 +1730,7 @@ class CI_DB_active_record extends CI_DB_driver { if (count($this->ar_where) > 0 OR count($this->ar_like) > 0) { - $sql .= "\n"; - - $sql .= "WHERE "; + $sql .= "\nWHERE "; } $sql .= implode("\n", $this->ar_where); @@ -1830,11 +1805,10 @@ class CI_DB_active_record extends CI_DB_driver { * * Takes an object as input and converts the class variables to array key/vals * - * @access public * @param object * @return array */ - function _object_to_array($object) + public function _object_to_array($object) { if ( ! is_object($object)) { @@ -1861,11 +1835,10 @@ class CI_DB_active_record extends CI_DB_driver { * * Takes an object as input and converts the class variables to array key/vals * - * @access public * @param object * @return array */ - function _object_to_array_batch($object) + public function _object_to_array_batch($object) { if ( ! is_object($object)) { @@ -1901,10 +1874,9 @@ class CI_DB_active_record extends CI_DB_driver { * * Starts AR caching * - * @access public * @return void */ - function start_cache() + public function start_cache() { $this->ar_caching = TRUE; } @@ -1916,10 +1888,9 @@ class CI_DB_active_record extends CI_DB_driver { * * Stops AR caching * - * @access public * @return void */ - function stop_cache() + public function stop_cache() { $this->ar_caching = FALSE; } @@ -1934,22 +1905,21 @@ class CI_DB_active_record extends CI_DB_driver { * @access public * @return void */ - function flush_cache() + public function flush_cache() { - $this->_reset_run( - array( - 'ar_cache_select' => array(), - 'ar_cache_from' => array(), - 'ar_cache_join' => array(), - 'ar_cache_where' => array(), - 'ar_cache_like' => array(), - 'ar_cache_groupby' => array(), - 'ar_cache_having' => array(), - 'ar_cache_orderby' => array(), - 'ar_cache_set' => array(), - 'ar_cache_exists' => array() - ) - ); + $this->_reset_run(array( + 'ar_cache_select' => array(), + 'ar_cache_from' => array(), + 'ar_cache_join' => array(), + 'ar_cache_where' => array(), + 'ar_cache_like' => array(), + 'ar_cache_groupby' => array(), + 'ar_cache_having' => array(), + 'ar_cache_orderby' => array(), + 'ar_cache_set' => array(), + 'ar_cache_exists' => array(), + 'ar_cache_no_escape' => array() + )); } // -------------------------------------------------------------------- @@ -1960,10 +1930,9 @@ class CI_DB_active_record extends CI_DB_driver { * When called, this function merges any cached AR arrays with * locally called ones. * - * @access private * @return void */ - function _merge_cache() + protected function _merge_cache() { if (count($this->ar_cache_exists) == 0) { @@ -1989,6 +1958,8 @@ class CI_DB_active_record extends CI_DB_driver { { $this->_track_aliases($this->ar_from); } + + $this->ar_no_escape = $this->ar_cache_no_escape; } // -------------------------------------------------------------------- @@ -1996,11 +1967,10 @@ class CI_DB_active_record extends CI_DB_driver { /** * Resets the active record values. Called by the get() function * - * @access private * @param array An array of fields to reset * @return void */ - function _reset_run($ar_reset_items) + protected function _reset_run($ar_reset_items) { foreach ($ar_reset_items as $item => $default_value) { @@ -2016,27 +1986,27 @@ class CI_DB_active_record extends CI_DB_driver { /** * Resets the active record values. Called by the get() function * - * @access private * @return void */ - function _reset_select() + protected function _reset_select() { $ar_reset_items = array( - 'ar_select' => array(), - 'ar_from' => array(), - 'ar_join' => array(), - 'ar_where' => array(), - 'ar_like' => array(), - 'ar_groupby' => array(), - 'ar_having' => array(), - 'ar_orderby' => array(), - 'ar_wherein' => array(), - 'ar_aliased_tables' => array(), - 'ar_distinct' => FALSE, - 'ar_limit' => FALSE, - 'ar_offset' => FALSE, - 'ar_order' => FALSE, - ); + 'ar_select' => array(), + 'ar_from' => array(), + 'ar_join' => array(), + 'ar_where' => array(), + 'ar_like' => array(), + 'ar_groupby' => array(), + 'ar_having' => array(), + 'ar_orderby' => array(), + 'ar_wherein' => array(), + 'ar_aliased_tables' => array(), + 'ar_no_escape' => array(), + 'ar_distinct' => FALSE, + 'ar_limit' => FALSE, + 'ar_offset' => FALSE, + 'ar_order' => FALSE, + ); $this->_reset_run($ar_reset_items); } @@ -2048,25 +2018,23 @@ class CI_DB_active_record extends CI_DB_driver { * * Called by the insert() update() insert_batch() update_batch() and delete() functions * - * @access private * @return void */ - function _reset_write() + protected function _reset_write() { $ar_reset_items = array( - 'ar_set' => array(), - 'ar_from' => array(), - 'ar_where' => array(), - 'ar_like' => array(), - 'ar_orderby' => array(), - 'ar_keys' => array(), - 'ar_limit' => FALSE, - 'ar_order' => FALSE - ); + 'ar_set' => array(), + 'ar_from' => array(), + 'ar_where' => array(), + 'ar_like' => array(), + 'ar_orderby' => array(), + 'ar_keys' => array(), + 'ar_limit' => FALSE, + 'ar_order' => FALSE + ); $this->_reset_run($ar_reset_items); } - } /* End of file DB_active_rec.php */ diff --git a/system/database/DB_driver.php b/system/database/DB_driver.php index e7a9de4..10e8ed0 100755 --- a/system/database/DB_driver.php +++ b/system/database/DB_driver.php @@ -424,8 +424,8 @@ class CI_DB_driver { if ( ! class_exists($driver)) { - include_once(BASEPATH.'database/DB_result'.EXT); - include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result'.EXT); + include_once(BASEPATH.'database/DB_result.php'); + include_once(BASEPATH.'database/drivers/'.$this->dbdriver.'/'.$this->dbdriver.'_result.php'); } return $driver; @@ -1115,7 +1115,7 @@ class CI_DB_driver { if ( ! class_exists('CI_DB_Cache')) { - if ( ! @include(BASEPATH.'database/DB_cache'.EXT)) + if ( ! @include(BASEPATH.'database/DB_cache.php')) { return $this->cache_off(); } diff --git a/system/database/DB_result.php b/system/database/DB_result.php index 76e1d6a..0c4e781 100755 --- a/system/database/DB_result.php +++ b/system/database/DB_result.php @@ -28,14 +28,14 @@ */ class CI_DB_result { - var $conn_id = NULL; - var $result_id = NULL; - var $result_array = array(); - var $result_object = array(); - var $custom_result_object = array(); - var $current_row = 0; - var $num_rows = 0; - var $row_data = NULL; + var $conn_id = NULL; + var $result_id = NULL; + var $result_array = array(); + var $result_object = array(); + var $custom_result_object = array(); + var $current_row = 0; + var $num_rows = 0; + var $row_data = NULL; /** @@ -47,47 +47,52 @@ class CI_DB_result { */ function result($type = 'object') { - if ($type == 'array') return $this->result_array(); - else if ($type == 'object') return $this->result_object(); - else return $this->custom_result_object($type); + if ($type == 'array') return $this->result_array(); + else if ($type == 'object') return $this->result_object(); + else return $this->custom_result_object($type); } // -------------------------------------------------------------------- - /** - * Custom query result. - * - * @param class_name A string that represents the type of object you want back - * @return array of objects - */ - function custom_result_object($class_name) - { - if (array_key_exists($class_name, $this->custom_result_object)) - { - return $this->custom_result_object[$class_name]; - } - - if ($this->result_id === FALSE OR $this->num_rows() == 0) - { - return array(); - } + /** + * Custom query result. + * + * @param class_name A string that represents the type of object you want back + * @return array of objects + */ + function custom_result_object($class_name) + { + if (array_key_exists($class_name, $this->custom_result_object)) + { + return $this->custom_result_object[$class_name]; + } + + if ($this->result_id === FALSE OR $this->num_rows() == 0) + { + return array(); + } + + // add the data to the object + $this->_data_seek(0); + $result_object = array(); - // add the data to the object - $this->_data_seek(0); - $result_object = array(); while ($row = $this->_fetch_object()) - { - $object = new $class_name(); - foreach ($row as $key => $value) - { - $object->$key = $value; - } + { + $object = new $class_name(); + + foreach ($row as $key => $value) + { + $object->$key = $value; + } + $result_object[] = $object; } - // return the array - return $this->custom_result_object[$class_name] = $result_object; - } + // return the array + return $this->custom_result_object[$class_name] = $result_object; + } + + // -------------------------------------------------------------------- /** * Query result. "object" version. @@ -180,9 +185,9 @@ class CI_DB_result { $n = 0; } - if ($type == 'object') return $this->row_object($n); - else if ($type == 'array') return $this->row_array($n); - else return $this->custom_row_object($n, $type); + if ($type == 'object') return $this->row_object($n); + else if ($type == 'array') return $this->row_array($n); + else return $this->custom_row_object($n, $type); } // -------------------------------------------------------------------- @@ -219,7 +224,7 @@ class CI_DB_result { // -------------------------------------------------------------------- - /** + /** * Returns a single result row - custom object version * * @access public @@ -242,7 +247,7 @@ class CI_DB_result { return $result[$this->current_row]; } - /** + /** * Returns a single result row - object version * * @access public diff --git a/system/database/drivers/mysql/mysql_driver.php b/system/database/drivers/mysql/mysql_driver.php index 4ff9b0a..b7d547c 100755 --- a/system/database/drivers/mysql/mysql_driver.php +++ b/system/database/drivers/mysql/mysql_driver.php @@ -132,7 +132,22 @@ class CI_DB_mysql_driver extends CI_DB { */ function db_set_charset($charset, $collation) { - return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id); + static $use_set_names; + + if ( ! isset($use_set_names)) + { + // mysql_set_charset() requires PHP >= 5.2.3 and MySQL >= 5.0.7, use SET NAMES as fallback + $use_set_names = (version_compare(PHP_VERSION, '5.2.3', '>=') && version_compare(mysql_get_server_info(), '5.0.7', '>=')) ? FALSE : TRUE; + } + + if ($use_set_names) + { + return @mysql_query("SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'", $this->conn_id); + } + else + { + return @mysql_set_charset($charset, $this->conn_id); + } } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysql/mysql_forge.php b/system/database/drivers/mysql/mysql_forge.php index 529ec98..c1cae13 100755 --- a/system/database/drivers/mysql/mysql_forge.php +++ b/system/database/drivers/mysql/mysql_forge.php @@ -119,9 +119,13 @@ class CI_DB_mysql_forge extends CI_DB_forge { $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; } - if (array_key_exists('NULL', $attributes)) + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) { - $sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL'; + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; } if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php index ccdabce..b8586c2 100755 --- a/system/database/drivers/mysqli/mysqli_driver.php +++ b/system/database/drivers/mysqli/mysqli_driver.php @@ -132,7 +132,22 @@ class CI_DB_mysqli_driver extends CI_DB { */ function _db_set_charset($charset, $collation) { - return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'"); + static $use_set_names; + + if ( ! isset($use_set_names)) + { + // mysqli_set_charset() requires MySQL >= 5.0.7, use SET NAMES as fallback + $use_set_names = (version_compare(mysqli_get_server_info($this->conn_id), '5.0.7', '>=')) ? FALSE : TRUE; + } + + if ($use_set_names) + { + return @mysqli_query($this->conn_id, "SET NAMES '".$this->escape_str($charset)."' COLLATE '".$this->escape_str($collation)."'"); + } + else + { + return @mysqli_set_charset($this->conn_id, $charset); + } } // -------------------------------------------------------------------- diff --git a/system/database/drivers/mysqli/mysqli_forge.php b/system/database/drivers/mysqli/mysqli_forge.php index d509733..2605494 100755 --- a/system/database/drivers/mysqli/mysqli_forge.php +++ b/system/database/drivers/mysqli/mysqli_forge.php @@ -104,9 +104,13 @@ class CI_DB_mysqli_forge extends CI_DB_forge { $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; } - if (array_key_exists('NULL', $attributes)) + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) { - $sql .= ($attributes['NULL'] === TRUE) ? ' NULL' : ' NOT NULL'; + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; } if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) diff --git a/system/database/drivers/postgre/postgre_driver.php b/system/database/drivers/postgre/postgre_driver.php index 47ff362..1403968 100755 --- a/system/database/drivers/postgre/postgre_driver.php +++ b/system/database/drivers/postgre/postgre_driver.php @@ -553,6 +553,24 @@ class CI_DB_postgre_driver extends CI_DB { // -------------------------------------------------------------------- + /** + * Insert_batch statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert_batch($table, $keys, $values) + { + return "INSERT INTO ".$table." (".implode(', ', $keys).") VALUES ".implode(', ', $values); + } + + // -------------------------------------------------------------------- + /** * Update statement * diff --git a/system/database/drivers/sqlsrv/index.html b/system/database/drivers/sqlsrv/index.html new file mode 100755 index 0000000..c942a79 --- /dev/null +++ b/system/database/drivers/sqlsrv/index.html @@ -0,0 +1,10 @@ + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + \ No newline at end of file diff --git a/system/database/drivers/sqlsrv/sqlsrv_driver.php b/system/database/drivers/sqlsrv/sqlsrv_driver.php new file mode 100755 index 0000000..1d32792 --- /dev/null +++ b/system/database/drivers/sqlsrv/sqlsrv_driver.php @@ -0,0 +1,598 @@ +char_set)) ? 'UTF-8' : $this->char_set; + + $connection = array( + 'UID' => empty($this->username) ? '' : $this->username, + 'PWD' => empty($this->password) ? '' : $this->password, + 'Database' => $this->database, + 'ConnectionPooling' => $pooling ? 1 : 0, + 'CharacterSet' => $character_set, + 'ReturnDatesAsStrings' => 1 + ); + + // If the username and password are both empty, assume this is a + // 'Windows Authentication Mode' connection. + if(empty($connection['UID']) && empty($connection['PWD'])) { + unset($connection['UID'], $connection['PWD']); + } + + return sqlsrv_connect($this->hostname, $connection); + } + + // -------------------------------------------------------------------- + + /** + * Persistent database connection + * + * @access private called by the base class + * @return resource + */ + function db_pconnect() + { + $this->db_connect(TRUE); + } + + // -------------------------------------------------------------------- + + /** + * Reconnect + * + * Keep / reestablish the db connection if no queries have been + * sent for a length of time exceeding the server's idle timeout + * + * @access public + * @return void + */ + function reconnect() + { + // not implemented in MSSQL + } + + // -------------------------------------------------------------------- + + /** + * Select the database + * + * @access private called by the base class + * @return resource + */ + function db_select() + { + return $this->_execute('USE ' . $this->database); + } + + // -------------------------------------------------------------------- + + /** + * Set client character set + * + * @access public + * @param string + * @param string + * @return resource + */ + function db_set_charset($charset, $collation) + { + // @todo - add support if needed + return TRUE; + } + + // -------------------------------------------------------------------- + + /** + * Execute the query + * + * @access private called by the base class + * @param string an SQL query + * @return resource + */ + function _execute($sql) + { + $sql = $this->_prep_query($sql); + return sqlsrv_query($this->conn_id, $sql, null, array( + 'Scrollable' => SQLSRV_CURSOR_STATIC, + 'SendStreamParamsAtExec' => true + )); + } + + // -------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @access private called by execute() + * @param string an SQL query + * @return string + */ + function _prep_query($sql) + { + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @access public + * @return bool + */ + function trans_begin($test_mode = FALSE) + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->_trans_failure = ($test_mode === TRUE) ? TRUE : FALSE; + + return sqlsrv_begin_transaction($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @access public + * @return bool + */ + function trans_commit() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + return sqlsrv_commit($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @access public + * @return bool + */ + function trans_rollback() + { + if ( ! $this->trans_enabled) + { + return TRUE; + } + + // When transactions are nested we only begin/commit/rollback the outermost ones + if ($this->_trans_depth > 0) + { + return TRUE; + } + + return sqlsrv_rollback($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Escape String + * + * @access public + * @param string + * @param bool whether or not the string will be used in a LIKE condition + * @return string + */ + function escape_str($str, $like = FALSE) + { + // Escape single quotes + return str_replace("'", "''", $str); + } + + // -------------------------------------------------------------------- + + /** + * Affected Rows + * + * @access public + * @return integer + */ + function affected_rows() + { + return @sqlrv_rows_affected($this->conn_id); + } + + // -------------------------------------------------------------------- + + /** + * Insert ID + * + * Returns the last id created in the Identity column. + * + * @access public + * @return integer + */ + function insert_id() + { + return $this->query('select @@IDENTITY as insert_id')->row('insert_id'); + } + + // -------------------------------------------------------------------- + + /** + * Parse major version + * + * Grabs the major version number from the + * database server version string passed in. + * + * @access private + * @param string $version + * @return int16 major version number + */ + function _parse_major_version($version) + { + preg_match('/([0-9]+)\.([0-9]+)\.([0-9]+)/', $version, $ver_info); + return $ver_info[1]; // return the major version b/c that's all we're interested in. + } + + // -------------------------------------------------------------------- + + /** + * Version number query string + * + * @access public + * @return string + */ + function _version() + { + $info = sqlsrv_server_info($this->conn_id); + return sprintf("select '%s' as ver", $info['SQLServerVersion']); + } + + // -------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @access public + * @param string + * @return string + */ + function count_all($table = '') + { + if ($table == '') + return '0'; + + $query = $this->query("SELECT COUNT(*) AS numrows FROM " . $this->dbprefix . $table); + + if ($query->num_rows() == 0) + return '0'; + + $row = $query->row(); + return $row->numrows; + } + + // -------------------------------------------------------------------- + + /** + * List table query + * + * Generates a platform-specific query string so that the table names can be fetched + * + * @access private + * @param boolean + * @return string + */ + function _list_tables($prefix_limit = FALSE) + { + return "SELECT name FROM sysobjects WHERE type = 'U' ORDER BY name"; + } + + // -------------------------------------------------------------------- + + /** + * List column query + * + * Generates a platform-specific query string so that the column names can be fetched + * + * @access private + * @param string the table name + * @return string + */ + function _list_columns($table = '') + { + return "SELECT * FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$this->_escape_table($table)."'"; + } + + // -------------------------------------------------------------------- + + /** + * Field data query + * + * Generates a platform-specific query so that the column data can be retrieved + * + * @access public + * @param string the table name + * @return object + */ + function _field_data($table) + { + return "SELECT TOP 1 * FROM " . $this->_escape_table($table); + } + + // -------------------------------------------------------------------- + + /** + * The error message string + * + * @access private + * @return string + */ + function _error_message() + { + $error = array_shift(sqlsrv_errors()); + return !empty($error['message']) ? $error['message'] : null; + } + + // -------------------------------------------------------------------- + + /** + * The error message number + * + * @access private + * @return integer + */ + function _error_number() + { + $error = array_shift(sqlsrv_errors()); + return isset($error['SQLSTATE']) ? $error['SQLSTATE'] : null; + } + + // -------------------------------------------------------------------- + + /** + * Escape Table Name + * + * This function adds backticks if the table name has a period + * in it. Some DBs will get cranky unless periods are escaped + * + * @access private + * @param string the table name + * @return string + */ + function _escape_table($table) + { + return $table; + } + + + /** + * Escape the SQL Identifiers + * + * This function escapes column and table names + * + * @access private + * @param string + * @return string + */ + function _escape_identifiers($item) + { + return $item; + } + + // -------------------------------------------------------------------- + + /** + * From Tables + * + * This function implicitly groups FROM tables so there is no confusion + * about operator precedence in harmony with SQL standards + * + * @access public + * @param type + * @return type + */ + function _from_tables($tables) + { + if ( ! is_array($tables)) + { + $tables = array($tables); + } + + return implode(', ', $tables); + } + + // -------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @access public + * @param string the table name + * @param array the insert keys + * @param array the insert values + * @return string + */ + function _insert($table, $keys, $values) + { + return "INSERT INTO ".$this->_escape_table($table)." (".implode(', ', $keys).") VALUES (".implode(', ', $values).")"; + } + + // -------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @access public + * @param string the table name + * @param array the update data + * @param array the where clause + * @param array the orderby clause + * @param array the limit clause + * @return string + */ + function _update($table, $values, $where) + { + foreach($values as $key => $val) + { + $valstr[] = $key." = ".$val; + } + + return "UPDATE ".$this->_escape_table($table)." SET ".implode(', ', $valstr)." WHERE ".implode(" ", $where); + } + + // -------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @access public + * @param string the table name + * @return string + */ + function _truncate($table) + { + return "TRUNCATE ".$table; + } + + // -------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @access public + * @param string the table name + * @param array the where clause + * @param string the limit clause + * @return string + */ + function _delete($table, $where) + { + return "DELETE FROM ".$this->_escape_table($table)." WHERE ".implode(" ", $where); + } + + // -------------------------------------------------------------------- + + /** + * Limit string + * + * Generates a platform-specific LIMIT clause + * + * @access public + * @param string the sql query string + * @param integer the number of rows to limit the query to + * @param integer the offset value + * @return string + */ + function _limit($sql, $limit, $offset) + { + $i = $limit + $offset; + + return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$i.' ', $sql); + } + + // -------------------------------------------------------------------- + + /** + * Close DB Connection + * + * @access public + * @param resource + * @return void + */ + function _close($conn_id) + { + @sqlsrv_close($conn_id); + } + +} + + + +/* End of file mssql_driver.php */ +/* Location: ./system/database/drivers/mssql/mssql_driver.php */ \ No newline at end of file diff --git a/system/database/drivers/sqlsrv/sqlsrv_forge.php b/system/database/drivers/sqlsrv/sqlsrv_forge.php new file mode 100755 index 0000000..cc88ec5 --- /dev/null +++ b/system/database/drivers/sqlsrv/sqlsrv_forge.php @@ -0,0 +1,248 @@ +db->_escape_identifiers($table); + } + + // -------------------------------------------------------------------- + + /** + * Create Table + * + * @access private + * @param string the table name + * @param array the fields + * @param mixed primary key(s) + * @param mixed key(s) + * @param boolean should 'IF NOT EXISTS' be added to the SQL + * @return bool + */ + function _create_table($table, $fields, $primary_keys, $keys, $if_not_exists) + { + $sql = 'CREATE TABLE '; + + if ($if_not_exists === TRUE) + { + $sql .= 'IF NOT EXISTS '; + } + + $sql .= $this->db->_escape_identifiers($table)." ("; + $current_field_count = 0; + + foreach ($fields as $field=>$attributes) + { + // Numeric field names aren't allowed in databases, so if the key is + // numeric, we know it was assigned by PHP and the developer manually + // entered the field information, so we'll simply add it to the list + if (is_numeric($field)) + { + $sql .= "\n\t$attributes"; + } + else + { + $attributes = array_change_key_case($attributes, CASE_UPPER); + + $sql .= "\n\t".$this->db->_protect_identifiers($field); + + $sql .= ' '.$attributes['TYPE']; + + if (array_key_exists('CONSTRAINT', $attributes)) + { + $sql .= '('.$attributes['CONSTRAINT'].')'; + } + + if (array_key_exists('UNSIGNED', $attributes) && $attributes['UNSIGNED'] === TRUE) + { + $sql .= ' UNSIGNED'; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + $sql .= ' DEFAULT \''.$attributes['DEFAULT'].'\''; + } + + if (array_key_exists('NULL', $attributes) && $attributes['NULL'] === TRUE) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if (array_key_exists('AUTO_INCREMENT', $attributes) && $attributes['AUTO_INCREMENT'] === TRUE) + { + $sql .= ' AUTO_INCREMENT'; + } + } + + // don't add a comma on the end of the last field + if (++$current_field_count < count($fields)) + { + $sql .= ','; + } + } + + if (count($primary_keys) > 0) + { + $primary_keys = $this->db->_protect_identifiers($primary_keys); + $sql .= ",\n\tPRIMARY KEY (" . implode(', ', $primary_keys) . ")"; + } + + if (is_array($keys) && count($keys) > 0) + { + foreach ($keys as $key) + { + if (is_array($key)) + { + $key = $this->db->_protect_identifiers($key); + } + else + { + $key = array($this->db->_protect_identifiers($key)); + } + + $sql .= ",\n\tFOREIGN KEY (" . implode(', ', $key) . ")"; + } + } + + $sql .= "\n)"; + + return $sql; + } + + // -------------------------------------------------------------------- + + /** + * Alter table query + * + * Generates a platform-specific query so that a table can be altered + * Called by add_column(), drop_column(), and column_alter(), + * + * @access private + * @param string the ALTER type (ADD, DROP, CHANGE) + * @param string the column name + * @param string the table name + * @param string the column definition + * @param string the default value + * @param boolean should 'NOT NULL' be added + * @param string the field after which we should add the new field + * @return object + */ + function _alter_table($alter_type, $table, $column_name, $column_definition = '', $default_value = '', $null = '', $after_field = '') + { + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table)." $alter_type ".$this->db->_protect_identifiers($column_name); + + // DROP has everything it needs now. + if ($alter_type == 'DROP') + { + return $sql; + } + + $sql .= " $column_definition"; + + if ($default_value != '') + { + $sql .= " DEFAULT \"$default_value\""; + } + + if ($null === NULL) + { + $sql .= ' NULL'; + } + else + { + $sql .= ' NOT NULL'; + } + + if ($after_field != '') + { + $sql .= ' AFTER ' . $this->db->_protect_identifiers($after_field); + } + + return $sql; + + } + + // -------------------------------------------------------------------- + + /** + * Rename a table + * + * Generates a platform-specific query so that a table can be renamed + * + * @access private + * @param string the old table name + * @param string the new table name + * @return string + */ + function _rename_table($table_name, $new_table_name) + { + // I think this syntax will work, but can find little documentation on renaming tables in MSSQL + $sql = 'ALTER TABLE '.$this->db->_protect_identifiers($table_name)." RENAME TO ".$this->db->_protect_identifiers($new_table_name); + return $sql; + } + +} + +/* End of file mssql_forge.php */ +/* Location: ./system/database/drivers/mssql/mssql_forge.php */ \ No newline at end of file diff --git a/system/database/drivers/sqlsrv/sqlsrv_result.php b/system/database/drivers/sqlsrv/sqlsrv_result.php new file mode 100755 index 0000000..bf0abd1 --- /dev/null +++ b/system/database/drivers/sqlsrv/sqlsrv_result.php @@ -0,0 +1,169 @@ +result_id); + } + + // -------------------------------------------------------------------- + + /** + * Number of fields in the result set + * + * @access public + * @return integer + */ + function num_fields() + { + return @sqlsrv_num_fields($this->result_id); + } + + // -------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * Generates an array of column names + * + * @access public + * @return array + */ + function list_fields() + { + $field_names = array(); + foreach(sqlsrv_field_metadata($this->result_id) as $offset => $field) + { + $field_names[] = $field['Name']; + } + + return $field_names; + } + + // -------------------------------------------------------------------- + + /** + * Field data + * + * Generates an array of objects containing field meta-data + * + * @access public + * @return array + */ + function field_data() + { + $retval = array(); + foreach(sqlsrv_field_metadata($this->result_id) as $offset => $field) + { + $F = new stdClass(); + $F->name = $field['Name']; + $F->type = $field['Type']; + $F->max_length = $field['Size']; + $F->primary_key = 0; + $F->default = ''; + + $retval[] = $F; + } + + return $retval; + } + + // -------------------------------------------------------------------- + + /** + * Free the result + * + * @return null + */ + function free_result() + { + if (is_resource($this->result_id)) + { + sqlsrv_free_stmt($this->result_id); + $this->result_id = FALSE; + } + } + + // -------------------------------------------------------------------- + + /** + * Data Seek + * + * Moves the internal pointer to the desired offset. We call + * this internally before fetching results to make sure the + * result set starts at zero + * + * @access private + * @return array + */ + function _data_seek($n = 0) + { + // Not implemented + } + + // -------------------------------------------------------------------- + + /** + * Result - associative array + * + * Returns the result set as an array + * + * @access private + * @return array + */ + function _fetch_assoc() + { + return sqlsrv_fetch_array($this->result_id, SQLSRV_FETCH_ASSOC); + } + + // -------------------------------------------------------------------- + + /** + * Result - object + * + * Returns the result set as an object + * + * @access private + * @return object + */ + function _fetch_object() + { + return sqlsrv_fetch_object($this->result_id); + } + +} + + +/* End of file mssql_result.php */ +/* Location: ./system/database/drivers/mssql/mssql_result.php */ \ No newline at end of file diff --git a/system/database/drivers/sqlsrv/sqlsrv_utility.php b/system/database/drivers/sqlsrv/sqlsrv_utility.php new file mode 100755 index 0000000..13a1850 --- /dev/null +++ b/system/database/drivers/sqlsrv/sqlsrv_utility.php @@ -0,0 +1,88 @@ +db->display_error('db_unsuported_feature'); + } + +} + +/* End of file mssql_utility.php */ +/* Location: ./system/database/drivers/mssql/mssql_utility.php */ \ No newline at end of file diff --git a/system/fonts/texb.ttf b/system/fonts/texb.ttf index 6792342a33277106ecd28a130476b2aeb0983af2..383c88b86b7c17e2e284732af48b2bfc359647ae 100755 GIT binary patch delta 59402 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 E%A)ovwIx96Fph>n4U`fq29X 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 delta 68545 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 Hbw>R!N diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php index f8073d2..1145688 100755 --- a/system/helpers/download_helper.php +++ b/system/helpers/download_helper.php @@ -58,13 +58,13 @@ if ( ! function_exists('force_download')) $extension = end($x); // Load the mime types - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); } - elseif (is_file(APPPATH.'config/mimes'.EXT)) + elseif (is_file(APPPATH.'config/mimes.php')) { - include(APPPATH.'config/mimes'.EXT); + include(APPPATH.'config/mimes.php'); } // Set a default mime if we can't find it diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php index 4434494..3931667 100755 --- a/system/helpers/file_helper.php +++ b/system/helpers/file_helper.php @@ -352,13 +352,13 @@ if ( ! function_exists('get_mime_by_extension')) if ( ! is_array($mimes)) { - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); } - elseif (is_file(APPPATH.'config/mimes'.EXT)) + elseif (is_file(APPPATH.'config/mimes.php')) { - include(APPPATH.'config/mimes'.EXT); + include(APPPATH.'config/mimes.php'); } if ( ! is_array($mimes)) diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php index acd75c2..2925d3c 100755 --- a/system/helpers/form_helper.php +++ b/system/helpers/form_helper.php @@ -72,7 +72,7 @@ if ( ! function_exists('form_open')) if (is_array($hidden) AND count($hidden) > 0) { - $form .= sprintf("\n
%s
", form_hidden($hidden)); + $form .= sprintf("
%s
", form_hidden($hidden)); } return $form; @@ -1032,25 +1032,23 @@ if ( ! function_exists('_get_validation_object')) { $CI =& get_instance(); - // We set this as a variable since we're returning by reference + // We set this as a variable since we're returning by reference. $return = FALSE; - - if ( ! isset($CI->load->_ci_classes) OR ! isset($CI->load->_ci_classes['form_validation'])) + + if (FALSE !== ($object = $CI->load->is_loaded('form_validation'))) { - return $return; + if ( ! isset($CI->$object) OR ! is_object($CI->$object)) + { + return $return; + } + + return $CI->$object; } - - $object = $CI->load->_ci_classes['form_validation']; - - if ( ! isset($CI->$object) OR ! is_object($CI->$object)) - { - return $return; - } - - return $CI->$object; + + return $return; } } /* End of file form_helper.php */ -/* Location: ./system/helpers/form_helper.php */ \ No newline at end of file +/* Location: ./system/helpers/form_helper.php */ diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php index c6103ab..b64b606 100755 --- a/system/helpers/html_helper.php +++ b/system/helpers/html_helper.php @@ -40,9 +40,10 @@ */ if ( ! function_exists('heading')) { - function heading($data = '', $h = '1') + function heading($data = '', $h = '1', $attributes = '') { - return "".$data.""; + $attributes = ($attributes != '') ? ' '.$attributes : $attributes; + return "".$data.""; } } @@ -123,6 +124,10 @@ if ( ! function_exists('_list')) } $attributes = $atts; } + elseif (is_string($attributes) AND strlen($attributes) > 0) + { + $attributes = ' '. $attributes; + } // Write the opening list tag $out .= "<".$type.$attributes.">\n"; @@ -258,13 +263,13 @@ if ( ! function_exists('doctype')) if ( ! is_array($_doctypes)) { - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/doctypes'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/doctypes'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/doctypes.php'); } - elseif (is_file(APPPATH.'config/doctypes'.EXT)) + elseif (is_file(APPPATH.'config/doctypes.php')) { - include(APPPATH.'config/doctypes'.EXT); + include(APPPATH.'config/doctypes.php'); } if ( ! is_array($_doctypes)) diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php index c7c113b..7b99bc5 100755 --- a/system/helpers/inflector_helper.php +++ b/system/helpers/inflector_helper.php @@ -41,30 +41,48 @@ if ( ! function_exists('singular')) { function singular($str) { - $str = trim($str); - $end = substr($str, -3); - - $str = preg_replace('/(.*)?([s|c]h)es/i','$1$2',$str); - - if (strtolower($end) == 'ies') - { - $str = substr($str, 0, strlen($str)-3).(preg_match('/[a-z]/',$end) ? 'y' : 'Y'); - } - elseif (strtolower($end) == 'ses') - { - $str = substr($str, 0, strlen($str)-2); - } - else - { - $end = strtolower(substr($str, -1)); + $result = strval($str); - if ($end == 's') + $singular_rules = array( + '/(matr)ices$/' => '\1ix', + '/(vert|ind)ices$/' => '\1ex', + '/^(ox)en/' => '\1', + '/(alias)es$/' => '\1', + '/([octop|vir])i$/' => '\1us', + '/(cris|ax|test)es$/' => '\1is', + '/(shoe)s$/' => '\1', + '/(o)es$/' => '\1', + '/(bus|campus)es$/' => '\1', + '/([m|l])ice$/' => '\1ouse', + '/(x|ch|ss|sh)es$/' => '\1', + '/(m)ovies$/' => '\1\2ovie', + '/(s)eries$/' => '\1\2eries', + '/([^aeiouy]|qu)ies$/' => '\1y', + '/([lr])ves$/' => '\1f', + '/(tive)s$/' => '\1', + '/(hive)s$/' => '\1', + '/([^f])ves$/' => '\1fe', + '/(^analy)ses$/' => '\1sis', + '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/' => '\1\2sis', + '/([ti])a$/' => '\1um', + '/(p)eople$/' => '\1\2erson', + '/(m)en$/' => '\1an', + '/(s)tatuses$/' => '\1\2tatus', + '/(c)hildren$/' => '\1\2hild', + '/(n)ews$/' => '\1\2ews', + '/([^u])s$/' => '\1', + ); + + foreach ($singular_rules as $rule => $replacement) + { + if (preg_match($rule, $result)) { - $str = substr($str, 0, strlen($str)-1); + $result = preg_replace($rule, $replacement, $result); + break; } } - return $str; + return $result; } } @@ -83,40 +101,41 @@ if ( ! function_exists('singular')) if ( ! function_exists('plural')) { function plural($str, $force = FALSE) - { - $str = trim($str); - $end = substr($str, -1); + { + $result = strval($str); + + $plural_rules = array( + '/^(ox)$/' => '\1\2en', // ox + '/([m|l])ouse$/' => '\1ice', // mouse, louse + '/(matr|vert|ind)ix|ex$/' => '\1ices', // matrix, vertex, index + '/(x|ch|ss|sh)$/' => '\1es', // search, switch, fix, box, process, address + '/([^aeiouy]|qu)y$/' => '\1ies', // query, ability, agency + '/(hive)$/' => '\1s', // archive, hive + '/(?:([^f])fe|([lr])f)$/' => '\1\2ves', // half, safe, wife + '/sis$/' => 'ses', // basis, diagnosis + '/([ti])um$/' => '\1a', // datum, medium + '/(p)erson$/' => '\1eople', // person, salesperson + '/(m)an$/' => '\1en', // man, woman, spokesman + '/(c)hild$/' => '\1hildren', // child + '/(buffal|tomat)o$/' => '\1\2oes', // buffalo, tomato + '/(bu|campu)s$/' => '\1\2ses', // bus, campus + '/(alias|status|virus)/' => '\1es', // alias + '/(octop)us$/' => '\1i', // octopus + '/(ax|cris|test)is$/' => '\1es', // axis, crisis + '/s$/' => 's', // no change (compatibility) + '/$/' => 's', + ); - if (preg_match('/y/i',$end)) + foreach ($plural_rules as $rule => $replacement) { - // Y preceded by vowel => regular plural - $vowels = array('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'); - $str = in_array(substr($str, -2, 1), $vowels) ? $str.'s' : substr($str, 0, -1).'ies'; - } - elseif (preg_match('/h/i',$end)) - { - if(preg_match('/^[c|s]h$/i',substr($str, -2))) + if (preg_match($rule, $result)) { - $str .= 'es'; + $result = preg_replace($rule, $replacement, $result); + break; } - else - { - $str .= 's'; - } - } - elseif (preg_match('/s/i',$end)) - { - if ($force == TRUE) - { - $str .= 'es'; - } - } - else - { - $str .= 's'; } - return $str; + return $result; } } diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php index a2d1031..6d88893 100755 --- a/system/helpers/smiley_helper.php +++ b/system/helpers/smiley_helper.php @@ -229,13 +229,13 @@ if ( ! function_exists('_get_smiley_array')) { function _get_smiley_array() { - if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys'.EXT)) + if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/smileys.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/smileys'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/smileys.php'); } - elseif (file_exists(APPPATH.'config/smileys'.EXT)) + elseif (file_exists(APPPATH.'config/smileys.php')) { - include(APPPATH.'config/smileys'.EXT); + include(APPPATH.'config/smileys.php'); } if (isset($smileys) AND is_array($smileys)) diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php index cca0939..33d7fa2 100755 --- a/system/helpers/text_helper.php +++ b/system/helpers/text_helper.php @@ -366,13 +366,13 @@ if ( ! function_exists('convert_accented_characters')) { function convert_accented_characters($str) { - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/foreign_chars.php'); } - elseif (is_file(APPPATH.'config/foreign_chars'.EXT)) + elseif (is_file(APPPATH.'config/foreign_chars.php')) { - include(APPPATH.'config/foreign_chars'.EXT); + include(APPPATH.'config/foreign_chars.php'); } if ( ! isset($foreign_characters)) diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index d0516ce..9f4b852 100755 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -50,18 +50,21 @@ if ( ! function_exists('site_url')) /** * Base URL - * - * Returns the "base_url" item from your config file + * + * Create a local URL based on your basepath. + * Segments can be passed in as a string or an array, same as site_url + * or a URL to a file can be passed in, e.g. to an image file. * * @access public + * @param string * @return string */ if ( ! function_exists('base_url')) { - function base_url() + function base_url($uri = '') { $CI =& get_instance(); - return $CI->config->slash_item('base_url'); + return $CI->config->base_url($uri); } } diff --git a/system/language/english/profiler_lang.php b/system/language/english/profiler_lang.php index b6460fb..1111158 100755 --- a/system/language/english/profiler_lang.php +++ b/system/language/english/profiler_lang.php @@ -9,6 +9,7 @@ $lang['profiler_post_data'] = 'POST DATA'; $lang['profiler_uri_string'] = 'URI STRING'; $lang['profiler_memory_usage'] = 'MEMORY USAGE'; $lang['profiler_config'] = 'CONFIG VARIABLES'; +$lang['profiler_session_data'] = 'SESSION DATA'; $lang['profiler_headers'] = 'HTTP HEADERS'; $lang['profiler_no_db'] = 'Database driver is not currently loaded'; $lang['profiler_no_queries'] = 'No queries were run'; @@ -17,6 +18,8 @@ $lang['profiler_no_get'] = 'No GET data exists'; $lang['profiler_no_uri'] = 'No URI data exists'; $lang['profiler_no_memory'] = 'Memory Usage Unavailable'; $lang['profiler_no_profiles'] = 'No Profile data - all Profiler sections have been disabled.'; +$lang['profiler_section_hide'] = 'Hide'; +$lang['profiler_section_show'] = 'Show'; /* End of file profiler_lang.php */ /* Location: ./system/language/english/profiler_lang.php */ \ No newline at end of file diff --git a/system/libraries/Cache/drivers/Cache_dummy.php b/system/libraries/Cache/drivers/Cache_dummy.php index de47acb..f96a68e 100755 --- a/system/libraries/Cache/drivers/Cache_dummy.php +++ b/system/libraries/Cache/drivers/Cache_dummy.php @@ -10,29 +10,29 @@ * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 2.0 - * @filesource + * @filesource */ // ------------------------------------------------------------------------ /** - * CodeIgniter Dummy Caching Class + * CodeIgniter Dummy Caching Class * * @package CodeIgniter * @subpackage Libraries * @category Core * @author ExpressionEngine Dev Team - * @link + * @link */ class CI_Cache_dummy extends CI_Driver { /** - * Get + * Get * * Since this is the dummy class, it's always going to return FALSE. * - * @param string + * @param string * @return Boolean FALSE */ public function get($id) @@ -40,8 +40,8 @@ class CI_Cache_dummy extends CI_Driver { return FALSE; } - // ------------------------------------------------------------------------ - + // ------------------------------------------------------------------------ + /** * Cache Save * @@ -55,7 +55,7 @@ class CI_Cache_dummy extends CI_Driver { { return TRUE; } - + // ------------------------------------------------------------------------ /** @@ -112,7 +112,7 @@ class CI_Cache_dummy extends CI_Driver { /** * Is this caching driver supported on the system? * Of course this one is. - * + * * @return TRUE; */ public function is_supported() @@ -121,9 +121,9 @@ class CI_Cache_dummy extends CI_Driver { } // ------------------------------------------------------------------------ - + } // End Class -/* End of file Cache_apc.php */ -/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */ \ No newline at end of file +/* End of file Cache_dummy.php */ +/* Location: ./system/libraries/Cache/drivers/Cache_dummy.php */ \ No newline at end of file diff --git a/system/libraries/Calendar.php b/system/libraries/Calendar.php index 72d228e..df0fd6e 100755 --- a/system/libraries/Calendar.php +++ b/system/libraries/Calendar.php @@ -47,7 +47,7 @@ class CI_Calendar { { $this->CI =& get_instance(); - if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE)) + if ( ! in_array('calendar_lang.php', $this->CI->lang->is_loaded, TRUE)) { $this->CI->lang->load('calendar'); } diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php index 7f65b48..b2eaa9a 100755 --- a/system/libraries/Cart.php +++ b/system/libraries/Cart.php @@ -374,6 +374,7 @@ class CI_Cart { // Lets add up the individual prices and set the cart sub-total $total = 0; + $items = 0; foreach ($this->_cart_contents as $key => $val) { // We make sure the array contains the proper indexes @@ -383,13 +384,14 @@ class CI_Cart { } $total += ($val['price'] * $val['qty']); + $items += $val['qty']; // Set the subtotal $this->_cart_contents[$key]['subtotal'] = ($this->_cart_contents[$key]['price'] * $this->_cart_contents[$key]['qty']); } // Set the cart total and total items. - $this->_cart_contents['total_items'] = count($this->_cart_contents); + $this->_cart_contents['total_items'] = $items; $this->_cart_contents['cart_total'] = $total; // Is our cart empty? If so we delete it from the session diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php index d1838f2..c32f2c1 100755 --- a/system/libraries/Driver.php +++ b/system/libraries/Driver.php @@ -43,11 +43,11 @@ class CI_Driver_Library { // The class will be prefixed with the parent lib $child_class = $this->lib_name.'_'.$child; - + // Remove the CI_ prefix and lowercase - $lib_name = strtolower(preg_replace('/^CI_/', '', $this->lib_name)); - $driver_name = strtolower(preg_replace('/^CI_/', '', $child_class)); - + $lib_name = ucfirst(strtolower(str_replace('CI_', '', $this->lib_name))); + $driver_name = strtolower(str_replace('CI_', '', $child_class)); + if (in_array($driver_name, array_map('strtolower', $this->valid_drivers))) { // check and see if the driver is in a separate file @@ -59,7 +59,7 @@ class CI_Driver_Library { // loves me some nesting! foreach (array(ucfirst($driver_name), $driver_name) as $class) { - $filepath = $path.'libraries/'.$lib_name.'/drivers/'.$class.EXT; + $filepath = $path.'libraries/'.$lib_name.'/drivers/'.$class.'.php'; if (file_exists($filepath)) { @@ -226,4 +226,4 @@ class CI_Driver { // END CI_Driver CLASS /* End of file Driver.php */ -/* Location: ./system/libraries/Driver.php */ \ No newline at end of file +/* Location: ./system/libraries/Driver.php */ diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 6c21f11..03eccea 100755 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -395,7 +395,7 @@ class CI_Email { public function attach($filename, $disposition = 'attachment') { $this->_attach_name[] = $filename; - $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename)))); + $this->_attach_type[] = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION)); $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters return $this; } @@ -722,7 +722,7 @@ class CI_Email { { if ( ! is_array($email)) { - $this->_set_error_message('email_must_be_array'); + $this->_set_error_message('lang:email_must_be_array'); return FALSE; } @@ -730,7 +730,7 @@ class CI_Email { { if ( ! $this->valid_email($val)) { - $this->_set_error_message('email_invalid_address', $val); + $this->_set_error_message('lang:email_invalid_address', $val); return FALSE; } } @@ -1131,7 +1131,7 @@ class CI_Email { if ( ! file_exists($filename)) { - $this->_set_error_message('email_attachment_missing', $filename); + $this->_set_error_message('lang:email_attachment_missing', $filename); return FALSE; } @@ -1146,7 +1146,7 @@ class CI_Email { if ( ! $fp = fopen($filename, FOPEN_READ)) { - $this->_set_error_message('email_attachment_unreadable', $filename); + $this->_set_error_message('lang:email_attachment_unreadable', $filename); return FALSE; } @@ -1353,7 +1353,7 @@ class CI_Email { ( ! isset($this->_bcc_array) AND ! isset($this->_headers['Bcc'])) AND ( ! isset($this->_headers['Cc']))) { - $this->_set_error_message('email_no_recipients'); + $this->_set_error_message('lang:email_no_recipients'); return FALSE; } @@ -1484,7 +1484,7 @@ class CI_Email { if ( ! $this->_send_with_mail()) { - $this->_set_error_message('email_send_failure_phpmail'); + $this->_set_error_message('lang:email_send_failure_phpmail'); return FALSE; } break; @@ -1492,7 +1492,7 @@ class CI_Email { if ( ! $this->_send_with_sendmail()) { - $this->_set_error_message('email_send_failure_sendmail'); + $this->_set_error_message('lang:email_send_failure_sendmail'); return FALSE; } break; @@ -1500,14 +1500,14 @@ class CI_Email { if ( ! $this->_send_with_smtp()) { - $this->_set_error_message('email_send_failure_smtp'); + $this->_set_error_message('lang:email_send_failure_smtp'); return FALSE; } break; } - $this->_set_error_message('email_sent', $this->_get_protocol()); + $this->_set_error_message('lang:email_sent', $this->_get_protocol()); return TRUE; } @@ -1578,8 +1578,8 @@ class CI_Email { if ($status != 0) { - $this->_set_error_message('email_exit_status', $status); - $this->_set_error_message('email_no_socket'); + $this->_set_error_message('lang:email_exit_status', $status); + $this->_set_error_message('lang:email_no_socket'); return FALSE; } @@ -1598,7 +1598,7 @@ class CI_Email { { if ($this->smtp_host == '') { - $this->_set_error_message('email_no_hostname'); + $this->_set_error_message('lang:email_no_hostname'); return FALSE; } @@ -1647,7 +1647,7 @@ class CI_Email { if (strncmp($reply, '250', 3) != 0) { - $this->_set_error_message('email_smtp_error', $reply); + $this->_set_error_message('lang:email_smtp_error', $reply); return FALSE; } @@ -1674,7 +1674,7 @@ class CI_Email { if ( ! is_resource($this->_smtp_connect)) { - $this->_set_error_message('email_smtp_error', $errno." ".$errstr); + $this->_set_error_message('lang:email_smtp_error', $errno." ".$errstr); return FALSE; } @@ -1737,7 +1737,7 @@ class CI_Email { if (substr($reply, 0, 3) != $resp) { - $this->_set_error_message('email_smtp_error', $reply); + $this->_set_error_message('lang:email_smtp_error', $reply); return FALSE; } @@ -1766,7 +1766,7 @@ class CI_Email { if ($this->smtp_user == "" AND $this->smtp_pass == "") { - $this->_set_error_message('email_no_smtp_unpw'); + $this->_set_error_message('lang:email_no_smtp_unpw'); return FALSE; } @@ -1776,7 +1776,7 @@ class CI_Email { if (strncmp($reply, '334', 3) != 0) { - $this->_set_error_message('email_failed_smtp_login', $reply); + $this->_set_error_message('lang:email_failed_smtp_login', $reply); return FALSE; } @@ -1786,7 +1786,7 @@ class CI_Email { if (strncmp($reply, '334', 3) != 0) { - $this->_set_error_message('email_smtp_auth_un', $reply); + $this->_set_error_message('lang:email_smtp_auth_un', $reply); return FALSE; } @@ -1796,7 +1796,7 @@ class CI_Email { if (strncmp($reply, '235', 3) != 0) { - $this->_set_error_message('email_smtp_auth_pw', $reply); + $this->_set_error_message('lang:email_smtp_auth_pw', $reply); return FALSE; } @@ -1815,7 +1815,7 @@ class CI_Email { { if ( ! fwrite($this->_smtp_connect, $data . $this->newline)) { - $this->_set_error_message('email_smtp_data_failure', $data); + $this->_set_error_message('lang:email_smtp_data_failure', $data); return FALSE; } else @@ -1942,7 +1942,7 @@ class CI_Email { $CI =& get_instance(); $CI->lang->load('email'); - if (FALSE === ($line = $CI->lang->line($msg))) + if (substr($msg, 0, 5) != 'lang:' || FALSE === ($line = $CI->lang->line(substr($msg, 5)))) { $this->_debug_msg[] = str_replace('%s', $val, $msg)."
"; } @@ -2059,4 +2059,4 @@ class CI_Email { // END CI_Email class /* End of file Email.php */ -/* Location: ./system/libraries/Email.php */ \ No newline at end of file +/* Location: ./system/libraries/Email.php */ diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php index e5f6587..b30a8cf 100755 --- a/system/libraries/Encrypt.php +++ b/system/libraries/Encrypt.php @@ -524,7 +524,7 @@ class CI_Encrypt { { if ( ! function_exists('mhash')) { - require_once(BASEPATH.'libraries/Sha1'.EXT); + require_once(BASEPATH.'libraries/Sha1.php'); $SH = new CI_SHA; return $SH->generate($str); } diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index cfc02ed..6f79a55 100755 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -628,6 +628,10 @@ class CI_Form_validation { $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result; } } + else + { + log_message('debug', "Unable to find validation rule: ".$rule); + } continue; } @@ -1357,4 +1361,4 @@ class CI_Form_validation { // END Form Validation Class /* End of file Form_validation.php */ -/* Location: ./system/libraries/Form_validation.php */ \ No newline at end of file +/* Location: ./system/libraries/Form_validation.php */ diff --git a/system/libraries/Log.php b/system/libraries/Log.php index fb2c5a4..9f1db76 100755 --- a/system/libraries/Log.php +++ b/system/libraries/Log.php @@ -83,7 +83,7 @@ class CI_Log { return FALSE; } - $filepath = $this->_log_path.'log-'.date('Y-m-d').EXT; + $filepath = $this->_log_path.'log-'.date('Y-m-d').'.php'; $message = ''; if ( ! file_exists($filepath)) diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index 1113f86..cc62e66 100755 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -30,7 +30,7 @@ class CI_Pagination { var $prefix = ''; // A custom prefix added to the path. var $suffix = ''; // A custom suffix added to the path. - var $total_rows = ''; // Total number of items (database results) + var $total_rows = 0; // Total number of items (database results) var $per_page = 10; // Max number of items you want shown per page var $num_links = 2; // Number of "digit" links to show before/after the currently viewed page var $cur_page = 0; // The current page being viewed diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index 8a1f18c..082a5ee 100755 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -32,8 +32,6 @@ */ class CI_Profiler { - var $CI; - protected $_available_sections = array( 'benchmarks', 'get', @@ -43,14 +41,27 @@ class CI_Profiler { 'controller_info', 'queries', 'http_headers', + 'session_data', 'config' ); + protected $_query_toggle_count = 25; + + protected $CI; + + // -------------------------------------------------------------------- + public function __construct($config = array()) { $this->CI =& get_instance(); $this->CI->load->language('profiler'); + if (isset($config['query_toggle_count'])) + { + $this->_query_toggle_count = (int) $config['query_toggle_count']; + unset($config['query_toggle_count']); + } + // default all sections to display foreach ($this->_available_sections as $section) { @@ -162,7 +173,7 @@ class CI_Profiler { $output .= "\n"; $output .= '  '.$this->CI->lang->line('profiler_queries').'  '; $output .= "\n"; - $output .= "\n\n\n"; + $output .= "\n\n
\n"; $output .="\n"; $output .= "
".$this->CI->lang->line('profiler_no_db')."
\n"; $output .= ""; @@ -178,13 +189,26 @@ class CI_Profiler { $output = "\n\n"; + $count = 0; + foreach ($dbs as $db) { + $count++; + + $hide_queries = (count($db->queries) > $this->_query_toggle_count) ? ' display:none' : ''; + + $show_hide_js = '('.$this->CI->lang->line('profiler_section_hide').')'; + + if ($hide_queries != '') + { + $show_hide_js = '('.$this->CI->lang->line('profiler_section_show').')'; + } + $output .= '
'; $output .= "\n"; - $output .= '  '.$this->CI->lang->line('profiler_database').':  '.$db->database.'   '.$this->CI->lang->line('profiler_queries').': '.count($db->queries).'   '; + $output .= '  '.$this->CI->lang->line('profiler_database').':  '.$db->database.'   '.$this->CI->lang->line('profiler_queries').': '.count($db->queries).'  '.$show_hide_js.''; $output .= "\n"; - $output .= "\n\n\n"; + $output .= "\n\n
\n"; if (count($db->queries) == 0) { @@ -388,7 +412,7 @@ class CI_Profiler { } else { - $output .= "
".$this->CI->lang->line('profiler_no_memory_usage')."
"; + $output .= "
".$this->CI->lang->line('profiler_no_memory')."
"; } $output .= ""; @@ -410,10 +434,10 @@ class CI_Profiler { $output = "\n\n"; $output .= '
'; $output .= "\n"; - $output .= '  '.$this->CI->lang->line('profiler_headers').'  '; + $output .= '  '.$this->CI->lang->line('profiler_headers').'  ('.$this->CI->lang->line('profiler_section_show').')'; $output .= "\n"; - $output .= "\n\n
\n"; + $output .= "\n\n
\n"; foreach (array('HTTP_ACCEPT', 'HTTP_USER_AGENT', 'HTTP_CONNECTION', 'SERVER_PORT', 'SERVER_NAME', 'REMOTE_ADDR', 'SERVER_SOFTWARE', 'HTTP_ACCEPT_LANGUAGE', 'SCRIPT_NAME', 'REQUEST_METHOD',' HTTP_HOST', 'REMOTE_HOST', 'CONTENT_TYPE', 'SERVER_PROTOCOL', 'QUERY_STRING', 'HTTP_ACCEPT_ENCODING', 'HTTP_X_FORWARDED_FOR') as $header) { @@ -441,10 +465,10 @@ class CI_Profiler { $output = "\n\n"; $output .= '
'; $output .= "\n"; - $output .= '  '.$this->CI->lang->line('profiler_config').'  '; + $output .= '  '.$this->CI->lang->line('profiler_config').'  ('.$this->CI->lang->line('profiler_section_show').')'; $output .= "\n"; - $output .= "\n\n
\n"; + $output .= "\n\n
\n"; foreach ($this->CI->config->config as $config=>$val) { @@ -464,6 +488,39 @@ class CI_Profiler { // -------------------------------------------------------------------- + /** + * Compile session userdata + * + * @return string + */ + private function _compile_session_data() + { + if ( ! isset($this->CI->session)) + { + return; + } + + $output = '
'; + $output .= '  '.$this->CI->lang->line('profiler_session_data').'  ('.$this->CI->lang->line('profiler_section_show').')'; + $output .= "
"; + + foreach ($this->CI->session->all_userdata() as $key => $val) + { + if (is_array($val)) + { + $val = print_r($val, TRUE); + } + + $output .= "\n"; + } + + $output .= ''; + $output .= "
"; + return $output; + } + + // -------------------------------------------------------------------- + /** * Run the Profiler * @@ -493,7 +550,6 @@ class CI_Profiler { return $output; } - } // END CI_Profiler class diff --git a/system/libraries/Session.php b/system/libraries/Session.php index 1822940..2c8a801 100755 --- a/system/libraries/Session.php +++ b/system/libraries/Session.php @@ -189,7 +189,7 @@ class CI_Session { } // Does the User Agent Match? - if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 50))) + if ($this->sess_match_useragent == TRUE AND trim($session['user_agent']) != trim(substr($this->CI->input->user_agent(), 0, 120))) { $this->sess_destroy(); return FALSE; @@ -316,7 +316,7 @@ class CI_Session { $this->userdata = array( 'session_id' => md5(uniqid($sessid, TRUE)), 'ip_address' => $this->CI->input->ip_address(), - 'user_agent' => substr($this->CI->input->user_agent(), 0, 50), + 'user_agent' => substr($this->CI->input->user_agent(), 0, 120), 'last_activity' => $this->now ); @@ -435,11 +435,11 @@ class CI_Session { * Fetch all session data * * @access public - * @return mixed + * @return array */ function all_userdata() { - return ( ! isset($this->userdata)) ? FALSE : $this->userdata; + return $this->userdata; } // -------------------------------------------------------------------- diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index e80049f..3177424 100755 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -945,13 +945,13 @@ class CI_Upload { if (count($this->mimes) == 0) { - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/mimes'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'); } - elseif (is_file(APPPATH.'config/mimes'.EXT)) + elseif (is_file(APPPATH.'config/mimes.php')) { - include(APPPATH.'config//mimes'.EXT); + include(APPPATH.'config//mimes.php'); } else { diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index 04cda73..016102a 100755 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -84,13 +84,13 @@ class CI_User_agent { */ private function _load_agent_file() { - if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/user_agents'.EXT)) + if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php')) { - include(APPPATH.'config/'.ENVIRONMENT.'/user_agents'.EXT); + include(APPPATH.'config/'.ENVIRONMENT.'/user_agents.php'); } - elseif (is_file(APPPATH.'config/user_agents'.EXT)) + elseif (is_file(APPPATH.'config/user_agents.php')) { - include(APPPATH.'config/user_agents'.EXT); + include(APPPATH.'config/user_agents.php'); } else {