diff options
-rw-r--r-- | application/config/autoload.php | 25 | ||||
-rw-r--r-- | application/config/config.php | 39 | ||||
-rw-r--r-- | application/config/routes.php | 9 | ||||
-rw-r--r-- | system/core/Config.php | 45 | ||||
-rw-r--r-- | system/core/Input.php | 19 | ||||
-rw-r--r-- | system/core/Lang.php | 18 | ||||
-rw-r--r-- | system/core/Loader.php | 26 | ||||
-rw-r--r-- | system/core/Router.php | 14 | ||||
-rw-r--r-- | system/core/URI.php | 18 | ||||
-rw-r--r-- | system/database/DB_forge.php | 6 | ||||
-rw-r--r-- | system/libraries/Cache/Cache.php | 216 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/Cache_apc.php | 151 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/Cache_dummy.php | 129 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/Cache_file.php | 196 | ||||
-rw-r--r-- | system/libraries/Cache/drivers/Cache_memcached.php | 209 | ||||
-rw-r--r-- | system/libraries/Table.php | 2 | ||||
-rw-r--r-- | system/libraries/Upload.php | 13 | ||||
-rw-r--r-- | user_guide/changelog.html | 4 | ||||
-rw-r--r-- | user_guide/database/forge.html | 2 | ||||
-rw-r--r-- | user_guide/libraries/caching.html | 193 |
20 files changed, 1241 insertions, 93 deletions
diff --git a/application/config/autoload.php b/application/config/autoload.php index 5e9740844..90b1a808f 100644 --- a/application/config/autoload.php +++ b/application/config/autoload.php @@ -18,16 +18,30 @@ | | These are the things you can load automatically: | -| 1. Libraries -| 2. Helper files -| 3. Custom config files -| 4. Language files -| 5. Models +| 1. Packages +| 2. Libraries +| 3. Helper files +| 4. Custom config files +| 5. Language files +| 6. Models | */ /* | ------------------------------------------------------------------- +| Auto-load Packges +| ------------------------------------------------------------------- +| Prototype: +| +| $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared'); +| +*/ + +$autoload['packages'] = array(APPPATH.'third_party'); + + +/* +| ------------------------------------------------------------------- | Auto-load Libraries | ------------------------------------------------------------------- | These are the classes located in the system/libraries folder @@ -98,6 +112,5 @@ $autoload['language'] = array(); $autoload['model'] = array(); - /* End of file autoload.php */ /* Location: ./application/config/autoload.php */
\ No newline at end of file diff --git a/application/config/config.php b/application/config/config.php index 477d7bfc4..a844f71ab 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -10,8 +10,11 @@ | | http://example.com/ | +| If this is not set then CodeIgniter will guess the protocol, domain and +| path to your installation. +| */ -$config['base_url'] = "http://example.com/"; +$config['base_url'] = ''; /* |-------------------------------------------------------------------------- @@ -23,7 +26,7 @@ $config['base_url'] = "http://example.com/"; | variable so that it is blank. | */ -$config['index_page'] = "index.php"; +$config['index_page'] = 'index.php'; /* |-------------------------------------------------------------------------- @@ -31,7 +34,7 @@ $config['index_page'] = "index.php"; |-------------------------------------------------------------------------- | | This item determines which server global should be used to retrieve the -| URI string. The default setting of "AUTO" works for most servers. +| URI string. The default setting of 'AUTO' works for most servers. | If your links do not seem to work, try one of the other delicious flavors: | | 'AUTO' Default - auto detects @@ -41,7 +44,7 @@ $config['index_page'] = "index.php"; | 'ORIG_PATH_INFO' Uses the ORIG_PATH_INFO | */ -$config['uri_protocol'] = "AUTO"; +$config['uri_protocol'] = 'AUTO'; /* |-------------------------------------------------------------------------- @@ -54,7 +57,7 @@ $config['uri_protocol'] = "AUTO"; | http://codeigniter.com/user_guide/general/urls.html */ -$config['url_suffix'] = ""; +$config['url_suffix'] = ''; /* |-------------------------------------------------------------------------- @@ -66,7 +69,7 @@ $config['url_suffix'] = ""; | than english. | */ -$config['language'] = "english"; +$config['language'] = 'english'; /* |-------------------------------------------------------------------------- @@ -77,14 +80,14 @@ $config['language'] = "english"; | that require a character set to be provided. | */ -$config['charset'] = "UTF-8"; +$config['charset'] = 'UTF-8'; /* |-------------------------------------------------------------------------- | Enable/Disable System Hooks |-------------------------------------------------------------------------- | -| If you would like to use the "hooks" feature you must enable it by +| If you would like to use the 'hooks' feature you must enable it by | setting this variable to TRUE (boolean). See the user guide for details. | */ @@ -142,7 +145,7 @@ $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; | | Options are: TRUE or FALSE (boolean) | -| The other items let you set the query string "words" that will +| The other items let you set the query string 'words' that will | invoke your controllers and its functions: | example.com/index.php?c=controller&m=function | @@ -151,7 +154,7 @@ $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; | use segment based URLs. | */ -$config['allow_get_array'] = TRUE; +$config['allow_get_array'] = TRUE; $config['enable_query_strings'] = FALSE; $config['controller_trigger'] = 'c'; $config['function_trigger'] = 'm'; @@ -221,7 +224,7 @@ $config['cache_path'] = ''; | MUST set an encryption key. See the user guide for info. | */ -$config['encryption_key'] = ""; +$config['encryption_key'] = ''; /* |-------------------------------------------------------------------------- @@ -261,9 +264,9 @@ $config['sess_time_to_update'] = 300; | 'cookie_path' = Typically will be a forward slash | */ -$config['cookie_prefix'] = ""; -$config['cookie_domain'] = ""; -$config['cookie_path'] = "/"; +$config['cookie_prefix'] = ''; +$config['cookie_domain'] = ''; +$config['cookie_path'] = '/'; /* |-------------------------------------------------------------------------- @@ -301,7 +304,7 @@ $config['csrf_protection'] = FALSE; | means you are prematurely outputting something to your browser. It could | even be a line of whitespace at the end of one of your scripts. For | compression to work, nothing can be sent before the output buffer is called -| by the output class. Do not "echo" any values with compression enabled. +| by the output class. Do not 'echo' any values with compression enabled. | */ $config['compress_output'] = FALSE; @@ -311,9 +314,9 @@ $config['compress_output'] = FALSE; | Master Time Reference |-------------------------------------------------------------------------- | -| Options are "local" or "gmt". This pref tells the system whether to use -| your server's local time as the master "now" reference, or convert it to -| GMT. See the "date helper" page of the user guide for information +| Options are 'local' or 'gmt'. This pref tells the system whether to use +| your server's local time as the master 'now' reference, or convert it to +| GMT. See the 'date helper' page of the user guide for information | regarding date handling. | */ diff --git a/application/config/routes.php b/application/config/routes.php index 614462fd9..5f9a58343 100644 --- a/application/config/routes.php +++ b/application/config/routes.php @@ -23,16 +23,23 @@ | RESERVED ROUTES | ------------------------------------------------------------------------- | -| There is one reserved routes: +| There area two reserved routes: | | $route['default_controller'] = 'welcome'; | | This route indicates which controller class should be loaded if the | URI contains no data. In the above example, the "welcome" class | would be loaded. +| +| $route['404_override'] = 'errors/page_missing'; +| +| This route will tell the Router what URI segments to use if those provided +| in the URL cannot be matched to a valid route. +| */ $route['default_controller'] = "welcome"; +$route['404_override'] = ''; /* End of file routes.php */ diff --git a/system/core/Config.php b/system/core/Config.php index bdd1b8333..8ecfba73a 100644 --- a/system/core/Config.php +++ b/system/core/Config.php @@ -47,6 +47,24 @@ class CI_Config { { $this->config =& get_config(); log_message('debug', "Config Class Initialized"); + + // Set the base_url automatically if none was provided + if ($this->config['base_url'] == '') + { + if(isset($_SERVER['HTTP_HOST'])) + { + $base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http'; + $base_url .= '://'. $_SERVER['HTTP_HOST']; + $base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']); + } + + else + { + $base_url = 'http://localhost/'; + } + + $this->set_item('base_url', $base_url); + } } // -------------------------------------------------------------------- @@ -185,14 +203,7 @@ class CI_Config { return FALSE; } - $pref = $this->config[$item]; - - if ($pref != '' && substr($pref, -1) != '/') - { - $pref .= '/'; - } - - return $pref; + return rtrim($this->config[$item], '/').'/'; } // -------------------------------------------------------------------- @@ -208,14 +219,7 @@ class CI_Config { { if ($uri == '') { - if ($this->item('base_url') == '') - { - return $this->item('index_page'); - } - else - { - return $this->slash_item('base_url').$this->item('index_page'); - } + return $this->slash_item('base_url').$this->item('index_page'); } if ($this->item('enable_query_strings') == FALSE) @@ -244,14 +248,7 @@ class CI_Config { $uri = $str; } - if ($this->item('base_url') == '') - { - return $this->item('index_page').'?'.$uri; - } - else - { - return $this->slash_item('base_url').$this->item('index_page').'?'.$uri; - } + return $this->slash_item('base_url').$this->item('index_page').'?'.$uri; } } diff --git a/system/core/Input.php b/system/core/Input.php index 4ddc402ee..eb2048e58 100644 --- a/system/core/Input.php +++ b/system/core/Input.php @@ -49,9 +49,9 @@ class CI_Input { { log_message('debug', "Input Class Initialized"); - $this->_allow_get_array = (config_item('allow_get_array') === TRUE) ? TRUE : FALSE; - $this->_enable_xss = (config_item('global_xss_filtering') === TRUE) ? TRUE : FALSE; - $this->_enable_csrf = (config_item('csrf_protection') === TRUE) ? TRUE : FALSE; + $this->_allow_get_array = (config_item('allow_get_array') === TRUE); + $this->_enable_xss = (config_item('global_xss_filtering') === TRUE); + $this->_enable_csrf = (config_item('csrf_protection') === TRUE); // Do we need to load the security class? if ($this->_enable_xss == TRUE OR $this->_enable_csrf == TRUE) @@ -216,14 +216,7 @@ class CI_Input { } else { - if ($expire > 0) - { - $expire = time() + $expire; - } - else - { - $expire = 0; - } + $expire = ($expire > 0) ? time() + $expire : 0; } setcookie($prefix.$name, $value, $expire, $path, $domain, 0); @@ -492,7 +485,7 @@ class CI_Input { } // We strip slashes if magic quotes is on to keep things consistent - if (get_magic_quotes_gpc()) + if (function_exists('get_magic_quotes_gpc') AND get_magic_quotes_gpc()) { $str = stripslashes($str); } @@ -514,7 +507,7 @@ class CI_Input { { if (strpos($str, "\r") !== FALSE) { - $str = str_replace(array("\r\n", "\r"), "\n", $str); + $str = str_replace(array("\r\n", "\r"), PHP_EOL, $str); } } diff --git a/system/core/Lang.php b/system/core/Lang.php index e7867b354..8ec179771 100644 --- a/system/core/Lang.php +++ b/system/core/Lang.php @@ -78,17 +78,21 @@ class CI_Lang { { include($alt_path.'language/'.$idiom.'/'.$langfile); } - elseif (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile)) - { - include(APPPATH.'language/'.$idiom.'/'.$langfile); - } else { - if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile)) + $found = FALSE; + + foreach (get_instance()->load->get_package_paths(TRUE) as $package_path) { - include(BASEPATH.'language/'.$idiom.'/'.$langfile); + if (file_exists($package_path.'language/'.$idiom.'/'.$langfile)) + { + include($package_path.'language/'.$idiom.'/'.$langfile); + $found = TRUE; + break; + } } - else + + if ($found !== TRUE) { show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile); } diff --git a/system/core/Loader.php b/system/core/Loader.php index 4b6b19eea..136cae9bf 100644 --- a/system/core/Loader.php +++ b/system/core/Loader.php @@ -81,12 +81,12 @@ class CI_Loader { { foreach($library as $read) { - $this->library($read); + $this->library($read); } - + return; } - + if ($library == '' OR isset($this->_base_classes[$library])) { return FALSE; @@ -527,7 +527,7 @@ class CI_Loader { function add_package_path($path) { $path = rtrim($path, '/').'/'; - + array_unshift($this->_ci_library_paths, $path); array_unshift($this->_ci_model_paths, $path); array_unshift($this->_ci_helper_paths, $path); @@ -540,6 +540,22 @@ class CI_Loader { // -------------------------------------------------------------------- /** + * Get Package Paths + * + * 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) + { + return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths; + } + + // -------------------------------------------------------------------- + + /** * Remove Package Path * * Remove a path from the library, model, and helper path arrays if it exists @@ -563,7 +579,7 @@ class CI_Loader { 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) diff --git a/system/core/Router.php b/system/core/Router.php index 9276800c3..79a8b4fcc 100644 --- a/system/core/Router.php +++ b/system/core/Router.php @@ -270,19 +270,17 @@ class CI_Router { // If we've gotten this far it means that the URI does not correlate to a valid // controller class. We will now see if there is an override - if (isset($this->routes['404_override']) AND $this->routes['404_override'] != '') + if (!empty($this->routes['404_override'])) { - if (strpos($this->routes['404_override'], '/') !== FALSE) - { - $x = explode('/', $this->routes['404_override']); + $x = explode('/', $this->routes['404_override']); - $this->set_class($x[0]); - $this->set_method($x[1]); + $this->set_class($x[0]); + $this->set_method(isset($x[1]) ? $x[1] : 'index'); - return $x; - } + return $x; } + // Nothing else to do at this point but show a 404 show_404($segments[0]); } diff --git a/system/core/URI.php b/system/core/URI.php index f6487d3f9..047e3c9bc 100644 --- a/system/core/URI.php +++ b/system/core/URI.php @@ -133,23 +133,25 @@ class CI_URI { if (isset($_SERVER['REQUEST_URI'])) { $uri = $_SERVER['REQUEST_URI']; - if (strpos($uri, $_SERVER['HTTP_HOST']) !== FALSE) + if (strpos($uri, $_SERVER['SERVER_NAME']) !== FALSE) { - $uri = preg_replace('/^\w+:\/\/[^\/]+/','',$uri); + $uri = preg_replace('/^\w+:\/\/[^\/]+/', '', $uri); } } + // Now lets check for IIS elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) { $uri = $_SERVER['HTTP_X_REWRITE_URL']; } + // Last ditch effort (for older CGI servers, like IIS 5) elseif (isset($_SERVER['ORIG_PATH_INFO'])) { $uri = $_SERVER['ORIG_PATH_INFO']; if ( ! empty($_SERVER['QUERY_STRING'])) { - $uri .= '?'.$_SERVER['QUERY_STRING']; + $uri .= '?' . $_SERVER['QUERY_STRING']; } } @@ -173,8 +175,8 @@ class CI_URI { { // Some server's require URL's like index.php?/whatever If that is the case, // then we need to add that to our parsing. - $fc_path = ltrim(FCPATH.SELF, '/'); - if (strpos($uri, SELF.'?') !== FALSE) + $fc_path = ltrim(FCPATH . SELF, '/'); + if (strpos($uri, SELF . '?') !== FALSE) { $fc_path .= '?'; } @@ -182,7 +184,7 @@ class CI_URI { $parsed_uri = explode('/', ltrim($uri, '/')); $i = 0; - foreach(explode("/", $fc_path) as $segment) + foreach (explode("/", $fc_path) as $segment) { if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i]) { @@ -203,7 +205,7 @@ class CI_URI { } // If it is just a / or index.php then just empty it. - if ($uri == '/' || $uri == SELF) + if ($uri == '/' OR $uri == SELF) { $uri = ''; } @@ -266,7 +268,7 @@ class CI_URI { */ function _explode_segments() { - foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val) + foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val) { // Filter segments for security $val = trim($this->_filter_uri($val)); diff --git a/system/database/DB_forge.php b/system/database/DB_forge.php index f40eac82d..ce505f4ee 100644 --- a/system/database/DB_forge.php +++ b/system/database/DB_forge.php @@ -333,6 +333,12 @@ class CI_DB_forge { foreach ($field as $k => $v) { + // If no name provided, use the current name + if ( ! isset($field[$k]['name'])) + { + $field[$k]['name'] = $k; + } + $this->add_field(array($k => $field[$k])); if (count($this->fields) == 0) diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php new file mode 100644 index 000000000..ea3194237 --- /dev/null +++ b/system/libraries/Cache/Cache.php @@ -0,0 +1,216 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 4.3.2 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2006 - 2010 EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * CodeIgniter Caching Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Core + * @author ExpressionEngine Dev Team + * @link + */ +class Cache extends CI_Driver_Library { + + protected $valid_drivers = array( + 'cache_apc', 'cache_file', 'cache_memcached', 'cache_dummy' + ); + + protected $_cache_path = NULL; // Path of cache files (if file-based cache) + protected $_adapter = 'dummy'; + protected $_backup_driver; + + // ------------------------------------------------------------------------ + + /** + * Constructor + * + * @param array + */ + public function __construct($config = array()) + { + if ( ! empty($config)) + { + $this->_initialize($config); + } + } + + // ------------------------------------------------------------------------ + + /** + * Get + * + * Look for a value in the cache. If it exists, return the data + * if not, return FALSE + * + * @param string + * @return mixed value that is stored/FALSE on failure + */ + public function get($id) + { + return $this->{$this->_adapter}->get($id); + } + + // ------------------------------------------------------------------------ + + /** + * Cache Save + * + * @param string Unique Key + * @param mixed Data to store + * @param int Length of time (in seconds) to cache the data + * + * @return boolean true on success/false on failure + */ + public function save($id, $data, $ttl = 60) + { + return $this->{$this->_adapter}->save($id, $data, $ttl); + } + + // ------------------------------------------------------------------------ + + /** + * Delete from Cache + * + * @param mixed unique identifier of the item in the cache + * @return boolean true on success/false on failure + */ + public function delete($id) + { + return $this->{$this->_adapter}->delete($id); + } + + // ------------------------------------------------------------------------ + + /** + * Clean the cache + * + * @return boolean false on failure/true on success + */ + public function clean() + { + return $this->{$this->_adapter}->clean(); + } + + // ------------------------------------------------------------------------ + + /** + * Cache Info + * + * @param string user/filehits + * @return mixed array on success, false on failure + */ + public function cache_info($type = 'user') + { + return $this->{$this->_adapter}->cache_info($type); + } + + // ------------------------------------------------------------------------ + + /** + * Get Cache Metadata + * + * @param mixed key to get cache metadata on + * @return mixed return value from child method + */ + public function get_metadata($id) + { + return $this->{$this->_adapter}->get_metadata($id); + } + + // ------------------------------------------------------------------------ + + /** + * Initialize + * + * Initialize class properties based on the configuration array. + * + * @param array + * @return void + */ + private function _initialize($config) + { + $default_config = array( + 'adapter', + 'memcached' + ); + + foreach ($default_config as $key) + { + if (isset($config[$key])) + { + $param = '_'.$key; + + $this->{$param} = $config[$key]; + } + } + + if (isset($config['backup'])) + { + if (in_array('cache_'.$config['backup'], $this->valid_drivers)) + { + $this->_backup_driver = $config['backup']; + } + } + } + + // ------------------------------------------------------------------------ + + /** + * Is the requested driver supported in this environment? + * + * @param string The driver to test. + * @return array + */ + public function is_supported($driver) + { + static $support = array(); + + if ( ! isset($support[$driver])) + { + $support[$driver] = $this->{$driver}->is_supported(); + } + + return $support[$driver]; + } + + // ------------------------------------------------------------------------ + + /** + * __get() + * + * @param child + * @return object + */ + public function __get($child) + { + $obj = parent::__get($child); + + if ( ! $this->is_supported($child)) + { + $this->_adapter = $this->_backup_driver; + } + + return $obj; + } + + // ------------------------------------------------------------------------ +} +// End Class + +/* End of file Cache.php */ +/* Location: ./system/libraries/Cache/Cache.php */
\ No newline at end of file diff --git a/system/libraries/Cache/drivers/Cache_apc.php b/system/libraries/Cache/drivers/Cache_apc.php new file mode 100644 index 000000000..9c716a971 --- /dev/null +++ b/system/libraries/Cache/drivers/Cache_apc.php @@ -0,0 +1,151 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 5.1.6 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2006 - 2010 EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * CodeIgniter APC Caching Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Core + * @author ExpressionEngine Dev Team + * @link + */ + +class Cache_apc extends CI_Driver { + + /** + * Get + * + * Look for a value in the cache. If it exists, return the data + * if not, return FALSE + * + * @param string + * @return mixed value that is stored/FALSE on failure + */ + public function get($id) + { + $data = apc_fetch($id); + + return (is_array($data)) ? $data[0] : FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Cache Save + * + * @param string Unique Key + * @param mixed Data to store + * @param int Length of time (in seconds) to cache the data + * + * @return boolean true on success/false on failure + */ + public function save($id, $data, $ttl = 60) + { + return apc_store($id, array($data, time(), $ttl), $ttl); + } + + // ------------------------------------------------------------------------ + + /** + * Delete from Cache + * + * @param mixed unique identifier of the item in the cache + * @param boolean true on success/false on failure + */ + public function delete($id) + { + return apc_delete($id); + } + + // ------------------------------------------------------------------------ + + /** + * Clean the cache + * + * @return boolean false on failure/true on success + */ + public function clean() + { + return apc_clear_cache('user'); + } + + // ------------------------------------------------------------------------ + + /** + * Cache Info + * + * @param string user/filehits + * @return mixed array on success, false on failure + */ + public function cache_info($type = NULL) + { + return apc_cache_info($type); + } + + // ------------------------------------------------------------------------ + + /** + * Get Cache Metadata + * + * @param mixed key to get cache metadata on + * @return mixed array on success/false on failure + */ + public function get_metadata($id) + { + $stored = apc_fetch($id); + + if (count($stored) !== 3) + { + return FALSE; + } + + list($value, $time, $ttl) = $stored; + + return array( + 'expire' => $time + $ttl, + 'mtime' => $time, + 'data' => $data + ); + } + + // ------------------------------------------------------------------------ + + /** + * is_supported() + * + * Check to see if APC is available on this system, bail if it isn't. + */ + public function is_supported() + { + if ( ! extension_loaded('apc') OR ! function_exists('apc_store')) + { + log_message('error', 'The APC PHP extension must be loaded to use APC Cache.'); + return FALSE; + } + + return TRUE; + } + + // ------------------------------------------------------------------------ + + +} +// End Class + +/* End of file Cache_apc.php */ +/* Location: ./system/libraries/Cache/drivers/Cache_apc.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 new file mode 100644 index 000000000..13c1f5cde --- /dev/null +++ b/system/libraries/Cache/drivers/Cache_dummy.php @@ -0,0 +1,129 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 4.3.2 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2006 - 2010 EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * CodeIgniter Dummy Caching Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Core + * @author ExpressionEngine Dev Team + * @link + */ + +class Cache_dummy extends CI_Driver { + + /** + * Get + * + * Since this is the dummy class, it's always going to return FALSE. + * + * @param string + * @return Boolean FALSE + */ + public function get($id) + { + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Cache Save + * + * @param string Unique Key + * @param mixed Data to store + * @param int Length of time (in seconds) to cache the data + * + * @return boolean TRUE, Simulating success + */ + public function save($id, $data, $ttl = 60) + { + return TRUE; + } + + // ------------------------------------------------------------------------ + + /** + * Delete from Cache + * + * @param mixed unique identifier of the item in the cache + * @param boolean TRUE, simulating success + */ + public function delete($id) + { + return TRUE; + } + + // ------------------------------------------------------------------------ + + /** + * Clean the cache + * + * @return boolean TRUE, simulating success + */ + public function clean() + { + return TRUE; + } + + // ------------------------------------------------------------------------ + + /** + * Cache Info + * + * @param string user/filehits + * @return boolean FALSE + */ + public function cache_info($type = NULL) + { + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Get Cache Metadata + * + * @param mixed key to get cache metadata on + * @return boolean FALSE + */ + public function get_metadata($id) + { + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Is this caching driver supported on the system? + * Of course this one is. + * + * @return TRUE; + */ + public function is_supported() + { + return TRUE; + } + + // ------------------------------------------------------------------------ + +} +// End Class + +/* End of file Cache_apc.php */ +/* Location: ./system/libraries/Cache/drivers/Cache_apc.php */
\ No newline at end of file diff --git a/system/libraries/Cache/drivers/Cache_file.php b/system/libraries/Cache/drivers/Cache_file.php new file mode 100644 index 000000000..bedbfaff8 --- /dev/null +++ b/system/libraries/Cache/drivers/Cache_file.php @@ -0,0 +1,196 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 4.3.2 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2006 - 2010 EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * CodeIgniter Memcached Caching Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Core + * @author ExpressionEngine Dev Team + * @link + */ + +class Cache_file extends CI_Driver { + + protected $_cache_path; + + /** + * Constructor + */ + public function __construct() + { + $CI =& get_instance(); + $CI->load->helper('file'); + + $path = $CI->config->item('cache_path'); + + $this->_cache_path = ($path == '') ? BASEPATH.'cache/' : $path; + } + + // ------------------------------------------------------------------------ + + /** + * Fetch from cache + * + * @param mixed unique key id + * @return mixed data on success/false on failure + */ + public function get($id) + { + if ( ! file_exists($this->_cache_path.$id)) + { + return FALSE; + } + + $data = read_file($this->_cache_path.$id); + $data = unserialize($data); + + if (time() > $data['time'] + $data['ttl']) + { + unlink($this->_cache_path.$id); + return FALSE; + } + + return $data['data']; + } + + // ------------------------------------------------------------------------ + + /** + * Save into cache + * + * @param string unique key + * @param mixed data to store + * @param int length of time (in seconds) the cache is valid + * - Default is 60 seconds + * @return boolean true on success/false on failure + */ + public function save($id, $data, $ttl = 60) + { + $contents = array( + 'time' => time(), + 'ttl' => $ttl, + 'data' => $data + ); + + if (write_file($this->_cache_path.$id, serialize($contents))) + { + @chmod($this->_cache_path.$id, 0777); + return TRUE; + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Delete from Cache + * + * @param mixed unique identifier of item in cache + * @return boolean true on success/false on failure + */ + public function delete($id) + { + return unlink($this->_cache_path.$id); + } + + // ------------------------------------------------------------------------ + + /** + * Clean the Cache + * + * @return boolean false on failure/true on success + */ + public function clean() + { + return delete_files($this->_cache_path); + } + + // ------------------------------------------------------------------------ + + /** + * Cache Info + * + * Not supported by file-based caching + * + * @param string user/filehits + * @return mixed FALSE + */ + public function cache_info($type = NULL) + { + return get_dir_file_info($this->_cache_path); + } + + // ------------------------------------------------------------------------ + + /** + * Get Cache Metadata + * + * @param mixed key to get cache metadata on + * @return mixed FALSE on failure, array on success. + */ + public function get_metadata($id) + { + if ( ! file_exists($this->_cache_path.$id)) + { + return FALSE; + } + + $data = read_file($this->_cache_path.$id); + $data = unserialize($data); + + if (is_array($data)) + { + $data = $data['data']; + $mtime = filemtime($this->_cache_path.$id); + + if ( ! isset($data['ttl'])) + { + return FALSE; + } + + return array( + 'expire' => $mtime + $data['ttl'], + 'mtime' => $mtime + ); + } + + return FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Is supported + * + * In the file driver, check to see that the cache directory is indeed writable + * + * @return boolean + */ + public function is_supported() + { + return is_really_writable($this->_cache_path); + } + + // ------------------------------------------------------------------------ +} +// End Class + +/* End of file Cache_file.php */ +/* Location: ./system/libraries/Cache/drivers/Cache_file.php */
\ No newline at end of file diff --git a/system/libraries/Cache/drivers/Cache_memcached.php b/system/libraries/Cache/drivers/Cache_memcached.php new file mode 100644 index 000000000..adc7fbf44 --- /dev/null +++ b/system/libraries/Cache/drivers/Cache_memcached.php @@ -0,0 +1,209 @@ +<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); +/** + * CodeIgniter + * + * An open source application development framework for PHP 4.3.2 or newer + * + * @package CodeIgniter + * @author ExpressionEngine Dev Team + * @copyright Copyright (c) 2006 - 2010 EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 2.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * CodeIgniter Memcached Caching Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Core + * @author ExpressionEngine Dev Team + * @link + */ + +class Cache_memcached extends CI_Driver { + + private $_memcached; // Holds the memcached object + + protected $_memcache_conf = array( + 'default' => array( + 'default_host' => '127.0.0.1', + 'default_port' => 11211, + 'default_weight' => 1 + ) + ); + + // ------------------------------------------------------------------------ + + /** + * Fetch from cache + * + * @param mixed unique key id + * @return mixed data on success/false on failure + */ + public function get($id) + { + $data = $this->_memcached->get($id); + + return (is_array($data)) ? $data[0] : FALSE; + } + + // ------------------------------------------------------------------------ + + /** + * Save + * + * @param string unique identifier + * @param mixed data being cached + * @param int time to live + * @return boolean true on success, false on failure + */ + public function save($id, $data, $ttl = 60) + { + return $this->_memcached->add($id, array($data, time(), $ttl), $ttl); + } + + // ------------------------------------------------------------------------ + + /** + * Delete from Cache + * + * @param mixed key to be deleted. + * @return boolean true on success, false on failure + */ + public function delete($id) + { + return $this->_memcached->delete($id); + } + + // ------------------------------------------------------------------------ + + /** + * Clean the Cache + * + * @return boolean false on failure/true on success + */ + public function clean() + { + return $this->_memcached->flush(); + } + + // ------------------------------------------------------------------------ + + /** + * Cache Info + * + * @param null type not supported in memcached + * @return mixed array on success, false on failure + */ + public function cache_info($type = NULL) + { + return $this->_memcached->getStats(); + } + + // ------------------------------------------------------------------------ + + /** + * Get Cache Metadata + * + * @param mixed key to get cache metadata on + * @return mixed FALSE on failure, array on success. + */ + public function get_metadata($id) + { + $stored = $this->_memcached->get($id); + + if (count($stored) !== 3) + { + return FALSE; + } + + list($value, $time, $ttl) = $stored; + + return array( + 'expire' => $time + $ttl, + 'mtime' => $time, + 'data' => $data + ); + } + + // ------------------------------------------------------------------------ + + /** + * Setup memcached. + */ + private function _setup_memcached() + { + // Try to load memcached server info from the config file. + $CI =& get_instance(); + if ($CI->config->load('memcached', TRUE, TRUE)) + { + if (is_array($CI->config->config['memcached'])) + { + $this->_memcache_conf = NULL; + + foreach ($CI->config->config['memcached'] as $name => $conf) + { + $this->_memcache_conf[$name] = $conf; + } + } + } + + $this->_memcached = new Memcached(); + + foreach ($this->_memcache_conf as $name => $cache_server) + { + if ( ! array_key_exists('hostname', $cache_server)) + { + $cache_server['hostname'] = $this->_default_options['default_host']; + } + + if ( ! array_key_exists('port', $cache_server)) + { + $cache_server['port'] = $this->_default_options['default_port']; + } + + if ( ! array_key_exists('weight', $cache_server)) + { + $cache_server['weight'] = $this->_default_options['default_weight']; + } + + $this->_memcached->addServer( + $cache_server['hostname'], $cache_server['port'], $cache_server['weight'] + ); + } + } + + // ------------------------------------------------------------------------ + + + /** + * Is supported + * + * Returns FALSE if memcached is not supported on the system. + * If it is, we setup the memcached object & return TRUE + */ + public function is_supported() + { + if ( ! extension_loaded('memcached')) + { + log_message('error', 'The Memcached Extension must be loaded to use Memcached Cache.'); + + return FALSE; + } + + $this->_setup_memcached(); + return TRUE; + } + + // ------------------------------------------------------------------------ + +} +// End Class + +/* End of file Cache_memcached.php */ +/* Location: ./system/libraries/Cache/drivers/Cache_memcached.php */
\ No newline at end of file diff --git a/system/libraries/Table.php b/system/libraries/Table.php index a57781c29..b4c6d366e 100644 --- a/system/libraries/Table.php +++ b/system/libraries/Table.php @@ -346,7 +346,7 @@ class CI_Table { { if ($function !== FALSE && is_callable($function)) { - $out .= $function($cell); + $out .= call_user_func($function, $cell); } else { diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index 4ccbdde90..b0e1f4c6c 100644 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -212,7 +212,18 @@ class CI_Upload { if ($this->_file_name_override != '') { $this->file_name = $this->_prep_filename($this->_file_name_override); - $this->file_ext = $this->get_extension($this->file_name); + + // If no extension was provided in the file_name config item, use the uploaded one + if(strpos($this->_file_name_override, '.') === FALSE) + { + $this->file_name .= $this->file_ext; + } + + // An extension was provided, lets have it! + else + { + $this->file_ext = $this->get_extension($this->_file_name_override); + } if ( ! $this->is_allowed_filetype(TRUE)) { diff --git a/user_guide/changelog.html b/user_guide/changelog.html index c3693e5f9..30734a835 100644 --- a/user_guide/changelog.html +++ b/user_guide/changelog.html @@ -76,6 +76,10 @@ Hg Tag: </p> <li>In-development code is now hosted at <a href="http://bitbucket.org/ellislab/codeigniter/">BitBucket</a>.</li> <li>Removed the deprecated Validation Class.</li> <li>Added CI_ Prefix to all core classes.</li> + <li>Package paths can now be set in application/config/autoload.php.</li> + <li>Upload library file_name can now be set without an extension, the extension will be taken from the uploaded file instead of the given name.</li> + <li>Name can be omitted from $this->dbforge->modify_column()'s 2nd param if you aren't changing the name.</li> + <li><kbd>$config['base_url']</kbd> is now empty by default and will guess what it should be.</li> </ul> <li>Libraries <ul> diff --git a/user_guide/database/forge.html b/user_guide/database/forge.html index 28b32d96a..b9e04428c 100644 --- a/user_guide/database/forge.html +++ b/user_guide/database/forge.html @@ -205,7 +205,7 @@ $this->dbforge->add_column('table_name', $fields);<br /> <p>Used to remove a column from a table. </p> <p><code>$this->dbforge->drop_column('table_name', 'column_to_drop');</code></p> <h2>$this->dbforge->modify_column()</h2> -<p>The usage of this function is identical to add_column(), except it alters an existing column rather than adding a new one. In order to use it you must add a "name" key into the field defining array.</p> +<p>The usage of this function is identical to add_column(), except it alters an existing column rather than adding a new one. In order to change the name you can add a "name" key into the field defining array.</p> <p><code>$fields = array(<br /> 'old_name' => array(<br /> 'name' => 'new_name',<br /> diff --git a/user_guide/libraries/caching.html b/user_guide/libraries/caching.html new file mode 100644 index 000000000..e4651dc4a --- /dev/null +++ b/user_guide/libraries/caching.html @@ -0,0 +1,193 @@ +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> +<head> + +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<title>Caching Driver : CodeIgniter User Guide</title> + +<style type='text/css' media='all'>@import url('../userguide.css');</style> +<link rel='stylesheet' type='text/css' media='all' href='../userguide.css' /> + +<script type="text/javascript" src="../nav/nav.js"></script> +<script type="text/javascript" src="../nav/prototype.lite.js"></script> +<script type="text/javascript" src="../nav/moo.fx.js"></script> +<script type="text/javascript" src="../nav/user_guide_menu.js"></script> + +<meta http-equiv='expires' content='-1' /> +<meta http-equiv= 'pragma' content='no-cache' /> +<meta name='robots' content='all' /> +<meta name='author' content='ExpressionEngine Dev Team' /> +<meta name='description' content='CodeIgniter User Guide' /> + +</head> +<body> + +<!-- START NAVIGATION --> +<div id="nav"><div id="nav_inner"><script type="text/javascript">create_menu('../');</script></div></div> +<div id="nav2"><a name="top"></a><a href="javascript:void(0);" onclick="myHeight.toggle();"><img src="../images/nav_toggle_darker.jpg" width="154" height="43" border="0" title="Toggle Table of Contents" alt="Toggle Table of Contents" /></a></div> +<div id="masthead"> +<table cellpadding="0" cellspacing="0" border="0" style="width:100%"> +<tr> +<td><h1>CodeIgniter User Guide Version 2.0.0</h1></td> +<td id="breadcrumb_right"><a href="../toc.html">Table of Contents Page</a></td> +</tr> +</table> +</div> +<!-- END NAVIGATION --> + + +<!-- START BREADCRUMB --> +<table cellpadding="0" cellspacing="0" border="0" style="width:100%"> +<tr> +<td id="breadcrumb"> +<a href="http://codeigniter.com/">CodeIgniter Home</a> › +<a href="../index.html">User Guide Home</a> › +<a href="../general/drivers.html">Drivers</a> › +Caching Driver +</td> +<td id="searchbox"><form method="get" action="http://www.google.com/search"><input type="hidden" name="as_sitesearch" id="as_sitesearch" value="codeigniter.com/user_guide/" />Search User Guide <input type="text" class="input" style="width:200px;" name="q" id="q" size="31" maxlength="255" value="" /> <input type="submit" class="submit" name="sa" value="Go" /></form></td> +</tr> +</table> +<!-- END BREADCRUMB --> + +<br clear="all" /> + + +<!-- START CONTENT --> +<div id="content"> + +<h1>Caching Driver</h1> + +<p>CodeIgniter features wrappers around some of the most popular forms of fast and dynamic caching. All but file-based caching require specific server requirements, and a Fatal Exception will be thrown if server requirements are not met.</p> + +<h2>Table of Contents</h2> +<ul> + <li><a href="#example_usage" title="Example Usage">Example Usage</a></li> + <li><a href="#function_reference" title="Function Reference">Function Reference</a></li> +</ul> + +<h3>Available Drivers</h3> +<ul> + <li><a href="#apc" title="APC Cache">Alternative PHP Cache (APC) Caching</a></li> + <li><a href="#file" title="File Caching">File-based Caching</a></li> + <li><a href="#memcached" title="Memcached">Memcached Caching</a></li> + <li><a href="#dummy" title="Dummy Caching">Dummy Cache</a></li> +</ul> + +<h2 id="example_usage">Example Usage</h2> + +<p>The following example will load the cache driver, specify <a href="#apc" title="APC">APC</a> as the driver to use, and fall back to file-based caching if APC is not available in the hosting environment.</p> + +<code> +$this->load->driver('cache', array('adapter' => 'apc', 'backup' => 'file'));<br /> +<br /> +if ( ! $foo = $this->cache->get('foo'))<br /> +{<br /> + echo 'Saving to the cache!<br />';<br /> + $foo = 'foobarbaz!';<br /> +<br /> + // Save into the cache for 5 minutes<br /> + $this->cache->save('foo', $foo, 300);<br /> +}<br /> +<br /> +echo $foo; +</code> + +<h1 id="function_reference">Function Reference</h1> + +<h2>is_supported(<var>driver</var>['string'])</h2> + +<p>This function is automatically called when accessing drivers via <samp>$this->cache->get()</samp>. However, if the individual drivers are used, make sure to call this function to ensure the driver is supported in the hosting environment.</p> + +<code> +if ($this->cache->apc->is_supported())<br /> +{<br /> + if ($data = $this->cache->apc->get('my_cache'))<br /> + {<br /> + // do things.<br /> + }<br /> +} +</code> + +<h2>get(<var>id</var>['string'])</h2> + +<p>This function will attempt to fetch an item from the cache store. If the item does not exist, the function will return <samp>FALSE</samp>.</p> +<code>$foo = $this->cache->get('my_cached_item');</code> + +<h2>save(<var>id</var>['string'], <var>data</var>['mixed'], <var>ttl</var>['int'])</h2> + +<p>This function will save an item to the cache store. If saving fails, the function will return <samp>FALSE</samp>.</p> +<p>The optional third parameter (Time To Live) defaults to 60 seconds.</p> +<code>$this->cache->save('cache_item_id', 'data_to_cache');</code> + +<h2>delete(<var>id</var>['string'])</h2> + +<p>This function will delete a specific item from the cache store. If item deletion fails, the function will return <samp>FALSE</samp>.</p> +<code>$this->cache->delete('cache_item_id');</code> + +<h2>clean()</h2> + +<p>This function will 'clean' the entire cache. If the deletion of the cache files fails, the function will return <samp>FALSE</samp>.</p> + +<code>$this->cache->clean();</code> + +<h2>cache_info()</h2> + +<p>This function will return information on the entire cache.</p> + +<code>var_dump($this->cache->cache_info());</code> + +<h2>get_metadata(<var>id</var>['string'])</h2> + +<p>This function will return detailed information on a specific item in the cache.</p> + +<code>var_dump($this->cache->get_metadata('my_cached_item'));</code> + +<h1>Drivers</h1> + +<h2 id="apc">Alternative PHP Cache (APC) Caching</h2> + +<p>All of the functions listed above can be accessed without passing a specific adapter to the driver loader as follows:</p> +<code>$this->load->driver('cache');<br /> + $this->cache->apc->save('foo', 'bar', 10);</code> +<p>For more information on APC, please see <a href="http://php.net/apc">http://php.net/apc</a></p> + +<h2 id="file">File-based Caching</h2> + +<p>Unlike caching from the Output Class, the driver file-based caching allows for pieces of view files to be cached. Use this with care, and make sure to benchmark your application, as a point can come where disk I/O will negate positive gains by caching.</p> + +<p>All of the functions listed above can be accessed without passing a specific adapter to the driver loader as follows:</p> +<code>$this->load->driver('cache');<br /> + $this->cache->file->save('foo', 'bar', 10);</code> + +<h2 id="memcached">Memcached Caching</h2> + +<p>Multiple Memcached servers can be specified in the memcached.php configuration file, located in the <samp>application/config/</samp> directory. + +<p>All of the functions listed above can be accessed without passing a specific adapter to the driver loader as follows:</p> +<code>$this->load->driver('cache');<br /> + $this->cache->memcached->save('foo', 'bar', 10);</code> + +<p>For more information on Memcached, please see <a href="http://php.net/memcached">http://php.net/memcached</a></p> + +<h2 id="dummy">Dummy Cache</h2> + +<p>This is a caching backend that will always 'miss.' It stores no data, but lets you keep your caching code in place in environments that don't support your chosen cache.</p> + +</div> +<!-- END CONTENT --> + + +<div id="footer"> +<p> +Previous Topic: <a href="errors.html">Error Handling</a> + · +<a href="#top">Top of Page</a> · +<a href="../index.html">User Guide Home</a> · +Next Topic: <a href="profiling.html">Profiling Your Application</a> +</p> +<p><a href="http://codeigniter.com">CodeIgniter</a> · Copyright © 2006-2010 · <a href="http://ellislab.com/">EllisLab, Inc.</a></p> +</div> + +</body> +</html>
\ No newline at end of file |