diff options
Diffstat (limited to 'system/libraries')
45 files changed, 6347 insertions, 7399 deletions
diff --git a/system/libraries/Benchmark.php b/system/libraries/Benchmark.php deleted file mode 100644 index d485ee21d..000000000 --- a/system/libraries/Benchmark.php +++ /dev/null @@ -1,113 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * CodeIgniter Benchmark Class - * - * This class enables you to mark points and calculate the time difference - * between them. Memory consumption can also be displayed. - * - * @package CodeIgniter - * @subpackage Libraries - * @category Libraries - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/benchmark.html - */ -class CI_Benchmark { - - var $marker = array(); - - // -------------------------------------------------------------------- - - /** - * Set a benchmark marker - * - * Multiple calls to this function can be made so that several - * execution points can be timed - * - * @access public - * @param string $name name of the marker - * @return void - */ - function mark($name) - { - $this->marker[$name] = microtime(); - } - - // -------------------------------------------------------------------- - - /** - * Calculates the time difference between two marked points. - * - * If the first parameter is empty this function instead returns the - * {elapsed_time} pseudo-variable. This permits the full system - * execution time to be shown in a template. The output class will - * swap the real value for this variable. - * - * @access public - * @param string a particular marked point - * @param string a particular marked point - * @param integer the number of decimal places - * @return mixed - */ - function elapsed_time($point1 = '', $point2 = '', $decimals = 4) - { - if ($point1 == '') - { - return '{elapsed_time}'; - } - - if ( ! isset($this->marker[$point1])) - { - return ''; - } - - if ( ! isset($this->marker[$point2])) - { - $this->marker[$point2] = microtime(); - } - - list($sm, $ss) = explode(' ', $this->marker[$point1]); - list($em, $es) = explode(' ', $this->marker[$point2]); - - return number_format(($em + $es) - ($sm + $ss), $decimals); - } - - // -------------------------------------------------------------------- - - /** - * Memory Usage - * - * This function returns the {memory_usage} pseudo-variable. - * This permits it to be put it anywhere in a template - * without the memory being calculated until the end. - * The output class will swap the real value for this variable. - * - * @access public - * @return string - */ - function memory_usage() - { - return '{memory_usage}'; - } - -} - -// END CI_Benchmark class - -/* End of file Benchmark.php */ -/* Location: ./system/libraries/Benchmark.php */
\ No newline at end of file diff --git a/system/libraries/Cache/Cache.php b/system/libraries/Cache/Cache.php new file mode 100755 index 000000000..d3f6105ea --- /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 - 2011 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 100755 index 000000000..e82e8e1f5 --- /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 - 2011 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 100755 index 000000000..74f689241 --- /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 - 2011 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 100755 index 000000000..3ed357f2f --- /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 - 2011 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 100755 index 000000000..a7efdc5de --- /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 - 2011 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/Calendar.php b/system/libraries/Calendar.php index 275bf2451..72d228e73 100644..100755 --- a/system/libraries/Calendar.php +++ b/system/libraries/Calendar.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -33,7 +33,7 @@ class CI_Calendar { var $local_time; var $template = ''; var $start_day = 'sunday'; - var $month_type = 'long'; + var $month_type = 'long'; var $day_type = 'abr'; var $show_next_prev = FALSE; var $next_prev_url = ''; @@ -42,30 +42,28 @@ class CI_Calendar { * Constructor * * Loads the calendar language file and sets the default time reference - * - * @access public */ - function CI_Calendar($config = array()) - { + public function __construct($config = array()) + { $this->CI =& get_instance(); - + if ( ! in_array('calendar_lang'.EXT, $this->CI->lang->is_loaded, TRUE)) { $this->CI->lang->load('calendar'); } $this->local_time = time(); - + if (count($config) > 0) { $this->initialize($config); } - + log_message('debug', "Calendar Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Initialize the user preferences * @@ -74,7 +72,7 @@ class CI_Calendar { * @access public * @param array config preferences * @return void - */ + */ function initialize($config = array()) { foreach ($config as $key => $val) @@ -85,7 +83,7 @@ class CI_Calendar { } } } - + // -------------------------------------------------------------------- /** @@ -102,66 +100,66 @@ class CI_Calendar { // Set and validate the supplied month/year if ($year == '') $year = date("Y", $this->local_time); - + if ($month == '') $month = date("m", $this->local_time); - - if (strlen($year) == 1) + + if (strlen($year) == 1) $year = '200'.$year; - - if (strlen($year) == 2) + + if (strlen($year) == 2) $year = '20'.$year; - if (strlen($month) == 1) + if (strlen($month) == 1) $month = '0'.$month; - + $adjusted_date = $this->adjust_date($month, $year); - + $month = $adjusted_date['month']; $year = $adjusted_date['year']; - + // Determine the total days in the month $total_days = $this->get_total_days($month, $year); - + // Set the starting day of the week $start_days = array('sunday' => 0, 'monday' => 1, 'tuesday' => 2, 'wednesday' => 3, 'thursday' => 4, 'friday' => 5, 'saturday' => 6); $start_day = ( ! isset($start_days[$this->start_day])) ? 0 : $start_days[$this->start_day]; - + // Set the starting day number $local_date = mktime(12, 0, 0, $month, 1, $year); $date = getdate($local_date); $day = $start_day + 1 - $date["wday"]; - + while ($day > 1) { $day -= 7; } - + // Set the current month/year/day // We use this to determine the "today" date $cur_year = date("Y", $this->local_time); $cur_month = date("m", $this->local_time); $cur_day = date("j", $this->local_time); - + $is_current_month = ($cur_year == $year AND $cur_month == $month) ? TRUE : FALSE; - + // Generate the template data array $this->parse_template(); - - // Begin building the calendar output + + // Begin building the calendar output $out = $this->temp['table_open']; - $out .= "\n"; + $out .= "\n"; - $out .= "\n"; + $out .= "\n"; $out .= $this->temp['heading_row_start']; $out .= "\n"; - + // "previous" month link if ($this->show_next_prev == TRUE) { // Add a trailing slash to the URL if needed $this->next_prev_url = preg_replace("/(.+?)\/*$/", "\\1/", $this->next_prev_url); - + $adjusted_date = $this->adjust_date($month - 1, $year); $out .= str_replace('{previous_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_previous_cell']); $out .= "\n"; @@ -169,26 +167,26 @@ class CI_Calendar { // Heading containing the month/year $colspan = ($this->show_next_prev == TRUE) ? 5 : 7; - + $this->temp['heading_title_cell'] = str_replace('{colspan}', $colspan, $this->temp['heading_title_cell']); $this->temp['heading_title_cell'] = str_replace('{heading}', $this->get_month_name($month)." ".$year, $this->temp['heading_title_cell']); - + $out .= $this->temp['heading_title_cell']; $out .= "\n"; // "next" month link if ($this->show_next_prev == TRUE) - { + { $adjusted_date = $this->adjust_date($month + 1, $year); $out .= str_replace('{next_url}', $this->next_prev_url.$adjusted_date['year'].'/'.$adjusted_date['month'], $this->temp['heading_next_cell']); } - $out .= "\n"; + $out .= "\n"; $out .= $this->temp['heading_row_end']; $out .= "\n"; // Write the cells containing the days of the week - $out .= "\n"; + $out .= "\n"; $out .= $this->temp['week_row_start']; $out .= "\n"; @@ -213,11 +211,11 @@ class CI_Calendar { for ($i = 0; $i < 7; $i++) { $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_start_today'] : $this->temp['cal_cell_start']; - + if ($day > 0 AND $day <= $total_days) - { + { if (isset($data[$day])) - { + { // Cells with content $temp = ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_content_today'] : $this->temp['cal_cell_content']; $out .= str_replace('{day}', $day, str_replace('{content}', $data[$day], $temp)); @@ -234,22 +232,22 @@ class CI_Calendar { // Blank cells $out .= $this->temp['cal_cell_blank']; } - - $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end']; + + $out .= ($is_current_month == TRUE AND $day == $cur_day) ? $this->temp['cal_cell_end_today'] : $this->temp['cal_cell_end']; $day++; } - - $out .= "\n"; + + $out .= "\n"; $out .= $this->temp['cal_row_end']; - $out .= "\n"; + $out .= "\n"; } - $out .= "\n"; + $out .= "\n"; $out .= $this->temp['table_close']; return $out; } - + // -------------------------------------------------------------------- /** @@ -272,9 +270,9 @@ class CI_Calendar { { $month_names = array('01' => 'cal_january', '02' => 'cal_february', '03' => 'cal_march', '04' => 'cal_april', '05' => 'cal_mayl', '06' => 'cal_june', '07' => 'cal_july', '08' => 'cal_august', '09' => 'cal_september', '10' => 'cal_october', '11' => 'cal_november', '12' => 'cal_december'); } - + $month = $month_names[$month]; - + if ($this->CI->lang->line($month) === FALSE) { return ucfirst(str_replace('cal_', '', $month)); @@ -282,7 +280,7 @@ class CI_Calendar { return $this->CI->lang->line($month); } - + // -------------------------------------------------------------------- /** @@ -299,7 +297,7 @@ class CI_Calendar { { if ($day_type != '') $this->day_type = $day_type; - + if ($this->day_type == 'long') { $day_names = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'); @@ -312,16 +310,16 @@ class CI_Calendar { { $day_names = array('su', 'mo', 'tu', 'we', 'th', 'fr', 'sa'); } - + $days = array(); foreach ($day_names as $val) - { + { $days[] = ($this->CI->lang->line('cal_'.$val) === FALSE) ? ucfirst($val) : $this->CI->lang->line('cal_'.$val); } - + return $days; } - + // -------------------------------------------------------------------- /** @@ -362,7 +360,7 @@ class CI_Calendar { return $date; } - + // -------------------------------------------------------------------- /** @@ -393,7 +391,7 @@ class CI_Calendar { return $days_in_month[$month - 1]; } - + // -------------------------------------------------------------------- /** @@ -407,17 +405,17 @@ class CI_Calendar { function default_template() { return array ( - 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', - 'heading_row_start' => '<tr>', + 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', + 'heading_row_start' => '<tr>', 'heading_previous_cell' => '<th><a href="{previous_url}"><<</a></th>', - 'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>', - 'heading_next_cell' => '<th><a href="{next_url}">>></a></th>', - 'heading_row_end' => '</tr>', - 'week_row_start' => '<tr>', - 'week_day_cell' => '<td>{week_day}</td>', - 'week_row_end' => '</tr>', - 'cal_row_start' => '<tr>', - 'cal_cell_start' => '<td>', + 'heading_title_cell' => '<th colspan="{colspan}">{heading}</th>', + 'heading_next_cell' => '<th><a href="{next_url}">>></a></th>', + 'heading_row_end' => '</tr>', + 'week_row_start' => '<tr>', + 'week_day_cell' => '<td>{week_day}</td>', + 'week_row_end' => '</tr>', + 'cal_row_start' => '<tr>', + 'cal_cell_start' => '<td>', 'cal_cell_start_today' => '<td>', 'cal_cell_content' => '<a href="{content}">{day}</a>', 'cal_cell_content_today' => '<a href="{content}"><strong>{day}</strong></a>', @@ -428,9 +426,9 @@ class CI_Calendar { 'cal_cell_end_today' => '</td>', 'cal_row_end' => '</tr>', 'table_close' => '</table>' - ); + ); } - + // -------------------------------------------------------------------- /** @@ -442,17 +440,17 @@ class CI_Calendar { * @access public * @return void */ - function parse_template() - { + function parse_template() + { $this->temp = $this->default_template(); - - if ($this->template == '') - { - return; - } - + + if ($this->template == '') + { + return; + } + $today = array('cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today'); - + foreach (array('table_open', 'table_close', 'heading_row_start', 'heading_previous_cell', 'heading_title_cell', 'heading_next_cell', 'heading_row_end', 'week_row_start', 'week_day_cell', 'week_row_end', 'cal_row_start', 'cal_cell_start', 'cal_cell_content', 'cal_cell_no_content', 'cal_cell_blank', 'cal_cell_end', 'cal_row_end', 'cal_cell_start_today', 'cal_cell_content_today', 'cal_cell_no_content_today', 'cal_cell_end_today') as $val) { if (preg_match("/\{".$val."\}(.*?)\{\/".$val."\}/si", $this->template, $match)) @@ -466,8 +464,8 @@ class CI_Calendar { $this->temp[$val] = $this->temp[str_replace('_today', '', $val)]; } } - } - } + } + } } diff --git a/system/libraries/Cart.php b/system/libraries/Cart.php index 643d2eca4..7f65b48b9 100644..100755 --- a/system/libraries/Cart.php +++ b/system/libraries/Cart.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * 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. + * @copyright Copyright (c) 2006 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -29,7 +29,7 @@ class CI_Cart { // These are the regular expression rules that we use to validate the product ID and product name var $product_id_rules = '\.a-z0-9_-'; // alpha-numeric, dashes, underscores, or periods var $product_name_rules = '\.\:\-_ a-z0-9'; // alpha-numeric, dashes, underscores, colons or periods - + // Private variables. Do not change! var $CI; var $_cart_contents = array(); @@ -39,12 +39,12 @@ class CI_Cart { * Shopping Class Constructor * * The constructor loads the Session class, used to store the shopping cart contents. - */ - function CI_Cart($params = array()) - { + */ + public function __construct($params = array()) + { // Set the super object to a local variable for use later $this->CI =& get_instance(); - + // Are any config settings being passed manually? If so, set them $config = array(); if (count($params) > 0) @@ -54,10 +54,10 @@ class CI_Cart { $config[$key] = $val; } } - + // Load the Sessions class $this->CI->load->library('session', $config); - + // Grab the shopping cart array from the session table, if it exists if ($this->CI->session->userdata('cart_contents') !== FALSE) { @@ -66,15 +66,15 @@ class CI_Cart { else { // No cart exists so we'll set some base values - $this->_cart_contents['cart_total'] = 0; - $this->_cart_contents['total_items'] = 0; + $this->_cart_contents['cart_total'] = 0; + $this->_cart_contents['total_items'] = 0; } - + log_message('debug', "Cart Class Initialized"); } // -------------------------------------------------------------------- - + /** * Insert items into the cart and save it to the session table * @@ -90,15 +90,15 @@ class CI_Cart { log_message('error', 'The insert method must be passed an array containing data.'); return FALSE; } - - // You can either insert a single product using a one-dimensional array, + + // You can either insert a single product using a one-dimensional array, // or multiple products using a multi-dimensional one. The way we // determine the array type is by looking for a required array key named "id" // at the top level. If it's not found, we will assume it's a multi-dimensional array. - - $save_cart = FALSE; + + $save_cart = FALSE; if (isset($items['id'])) - { + { if ($this->_insert($items) == TRUE) { $save_cart = TRUE; @@ -114,7 +114,7 @@ class CI_Cart { { $save_cart = TRUE; } - } + } } } @@ -129,7 +129,7 @@ class CI_Cart { } // -------------------------------------------------------------------- - + /** * Insert * @@ -145,9 +145,9 @@ class CI_Cart { log_message('error', 'The insert method must be passed an array containing data.'); return FALSE; } - + // -------------------------------------------------------------------- - + // Does the $items array contain an id, quantity, price, and name? These are required if ( ! isset($items['id']) OR ! isset($items['qty']) OR ! isset($items['price']) OR ! isset($items['name'])) { @@ -156,7 +156,7 @@ class CI_Cart { } // -------------------------------------------------------------------- - + // Prep the quantity. It can only be a number. Duh... $items['qty'] = trim(preg_replace('/([^0-9])/i', '', $items['qty'])); // Trim any leading zeros @@ -167,9 +167,9 @@ class CI_Cart { { return FALSE; } - + // -------------------------------------------------------------------- - + // Validate the product ID. It can only be alpha-numeric, dashes, underscores or periods // Not totally sure we should impose this rule, but it seems prudent to standardize IDs. // Note: These can be user-specified by setting the $this->product_id_rules variable. @@ -180,7 +180,7 @@ class CI_Cart { } // -------------------------------------------------------------------- - + // Validate the product name. It can only be alpha-numeric, dashes, underscores, colons or periods. // Note: These can be user-specified by setting the $this->product_name_rules variable. if ( ! preg_match("/^[".$this->product_name_rules."]+$/i", $items['name'])) @@ -195,7 +195,7 @@ class CI_Cart { $items['price'] = trim(preg_replace('/([^0-9\.])/i', '', $items['price'])); // Trim any leading zeros $items['price'] = trim(preg_replace('/(^[0]+)/i', '', $items['price'])); - + // Is the price a valid number? if ( ! is_numeric($items['price'])) { @@ -204,13 +204,13 @@ class CI_Cart { } // -------------------------------------------------------------------- - + // We now need to create a unique identifier for the item being inserted into the cart. - // Every time something is added to the cart it is stored in the master cart array. - // Each row in the cart array, however, must have a unique index that identifies not only - // a particular product, but makes it possible to store identical products with different options. - // For example, what if someone buys two identical t-shirts (same product ID), but in - // different sizes? The product ID (and other attributes, like the name) will be identical for + // Every time something is added to the cart it is stored in the master cart array. + // Each row in the cart array, however, must have a unique index that identifies not only + // a particular product, but makes it possible to store identical products with different options. + // For example, what if someone buys two identical t-shirts (same product ID), but in + // different sizes? The product ID (and other attributes, like the name) will be identical for // both sizes because it's the same shirt. The only difference will be the size. // Internally, we need to treat identical submissions, but with different options, as a unique product. // Our solution is to convert the options array to a string and MD5 it along with the product ID. @@ -225,19 +225,19 @@ class CI_Cart { // Technically, we don't need to MD5 the ID in this case, but it makes // sense to standardize the format of array indexes for both conditions $rowid = md5($items['id']); - } + } // -------------------------------------------------------------------- // Now that we have our unique "row ID", we'll add our cart items to the master array - + // let's unset this first, just to make sure our index contains only the data from this submission - unset($this->_cart_contents[$rowid]); - + unset($this->_cart_contents[$rowid]); + // Create a new index with our new row ID $this->_cart_contents[$rowid]['rowid'] = $rowid; - - // And add the new items to the cart array + + // And add the new items to the cart array foreach ($items as $key => $val) { $this->_cart_contents[$rowid][$key] = $val; @@ -248,11 +248,11 @@ class CI_Cart { } // -------------------------------------------------------------------- - + /** * Update the cart * - * This function permits the quantity of a given item to be changed. + * This function permits the quantity of a given item to be changed. * Typically it is called from the "view cart" page if a user makes * changes to the quantity before checkout. That array must contain the * product ID and quantity for each item. @@ -269,8 +269,8 @@ class CI_Cart { { return FALSE; } - - // You can either update a single product using a one-dimensional array, + + // You can either update a single product using a one-dimensional array, // or multiple products using a multi-dimensional one. The way we // determine the array type is by looking for a required array key named "id". // If it's not found we assume it's a multi-dimensional array @@ -292,7 +292,7 @@ class CI_Cart { { $save_cart = TRUE; } - } + } } } @@ -307,11 +307,11 @@ class CI_Cart { } // -------------------------------------------------------------------- - + /** * Update the cart * - * This function permits the quantity of a given item to be changed. + * This function permits the quantity of a given item to be changed. * Typically it is called from the "view cart" page if a user makes * changes to the quantity before checkout. That array must contain the * product ID and quantity for each item. @@ -319,7 +319,7 @@ class CI_Cart { * @access private * @param array * @return bool - */ + */ function _update($items = array()) { // Without these array indexes there is nothing we can do @@ -327,7 +327,7 @@ class CI_Cart { { return FALSE; } - + // Prep the quantity $items['qty'] = preg_replace('/([^0-9])/i', '', $items['qty']); @@ -336,7 +336,7 @@ class CI_Cart { { return FALSE; } - + // Is the new quantity different than what is already saved in the cart? // If it's the same there's nothing to do if ($this->_cart_contents[$items['rowid']]['qty'] == $items['qty']) @@ -348,18 +348,18 @@ class CI_Cart { // If the quantity is greater than zero we are updating if ($items['qty'] == 0) { - unset($this->_cart_contents[$items['rowid']]); + unset($this->_cart_contents[$items['rowid']]); } else { $this->_cart_contents[$items['rowid']]['qty'] = $items['qty']; } - + return TRUE; } // -------------------------------------------------------------------- - + /** * Save the cart array to the session DB * @@ -383,20 +383,20 @@ class CI_Cart { } $total += ($val['price'] * $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'] = count($this->_cart_contents); $this->_cart_contents['cart_total'] = $total; - + // Is our cart empty? If so we delete it from the session if (count($this->_cart_contents) <= 2) { $this->CI->session->unset_userdata('cart_contents'); - + // Nothing more to do... coffee time! return FALSE; } @@ -406,11 +406,11 @@ class CI_Cart { $this->CI->session->set_userdata(array('cart_contents' => $this->_cart_contents)); // Woot! - return TRUE; + return TRUE; } // -------------------------------------------------------------------- - + /** * Cart Total * @@ -423,7 +423,7 @@ class CI_Cart { } // -------------------------------------------------------------------- - + /** * Total Items * @@ -438,7 +438,7 @@ class CI_Cart { } // -------------------------------------------------------------------- - + /** * Cart Contents * @@ -450,16 +450,16 @@ class CI_Cart { function contents() { $cart = $this->_cart_contents; - + // Remove these so they don't create a problem when showing the cart table unset($cart['total_items']); unset($cart['cart_total']); - + return $cart; } // -------------------------------------------------------------------- - + /** * Has options * @@ -475,12 +475,12 @@ class CI_Cart { { return FALSE; } - + return TRUE; } // -------------------------------------------------------------------- - + /** * Product options * @@ -500,7 +500,7 @@ class CI_Cart { } // -------------------------------------------------------------------- - + /** * Format Number * @@ -515,15 +515,15 @@ class CI_Cart { { return ''; } - + // Remove anything that isn't a number or decimal point. $n = trim(preg_replace('/([^0-9\.])/i', '', $n)); - + return number_format($n, 2, '.', ','); } - + // -------------------------------------------------------------------- - + /** * Destroy the cart * @@ -535,9 +535,9 @@ class CI_Cart { function destroy() { unset($this->_cart_contents); - - $this->_cart_contents['cart_total'] = 0; - $this->_cart_contents['total_items'] = 0; + + $this->_cart_contents['cart_total'] = 0; + $this->_cart_contents['total_items'] = 0; $this->CI->session->unset_userdata('cart_contents'); } diff --git a/system/libraries/Config.php b/system/libraries/Config.php deleted file mode 100644 index 760120779..000000000 --- a/system/libraries/Config.php +++ /dev/null @@ -1,244 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * CodeIgniter Config Class - * - * This class contains functions that enable config files to be managed - * - * @package CodeIgniter - * @subpackage Libraries - * @category Libraries - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/config.html - */ -class CI_Config { - - var $config = array(); - var $is_loaded = array(); - - /** - * Constructor - * - * Sets the $config data from the primary config.php file as a class variable - * - * @access public - * @param string the config file name - * @param boolean if configuration values should be loaded into their own section - * @param boolean true if errors should just return false, false if an error message should be displayed - * @return boolean if the file was successfully loaded or not - */ - function CI_Config() - { - $this->config =& get_config(); - log_message('debug', "Config Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Load Config File - * - * @access public - * @param string the config file name - * @return boolean if the file was loaded correctly - */ - function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) - { - $file = ($file == '') ? 'config' : str_replace(EXT, '', $file); - - if (in_array($file, $this->is_loaded, TRUE)) - { - return TRUE; - } - - if ( ! file_exists(APPPATH.'config/'.$file.EXT)) - { - if ($fail_gracefully === TRUE) - { - return FALSE; - } - show_error('The configuration file '.$file.EXT.' does not exist.'); - } - - include(APPPATH.'config/'.$file.EXT); - - if ( ! isset($config) OR ! is_array($config)) - { - if ($fail_gracefully === TRUE) - { - return FALSE; - } - show_error('Your '.$file.EXT.' file does not appear to contain a valid configuration array.'); - } - - if ($use_sections === TRUE) - { - if (isset($this->config[$file])) - { - $this->config[$file] = array_merge($this->config[$file], $config); - } - else - { - $this->config[$file] = $config; - } - } - else - { - $this->config = array_merge($this->config, $config); - } - - $this->is_loaded[] = $file; - unset($config); - - log_message('debug', 'Config file loaded: config/'.$file.EXT); - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Fetch a config file item - * - * - * @access public - * @param string the config item name - * @param string the index name - * @param bool - * @return string - */ - function item($item, $index = '') - { - if ($index == '') - { - if ( ! isset($this->config[$item])) - { - return FALSE; - } - - $pref = $this->config[$item]; - } - else - { - if ( ! isset($this->config[$index])) - { - return FALSE; - } - - if ( ! isset($this->config[$index][$item])) - { - return FALSE; - } - - $pref = $this->config[$index][$item]; - } - - return $pref; - } - - // -------------------------------------------------------------------- - - /** - * 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. - * - * @access public - * @param string the config item name - * @param bool - * @return string - */ - function slash_item($item) - { - if ( ! isset($this->config[$item])) - { - return FALSE; - } - - $pref = $this->config[$item]; - - if ($pref != '' && substr($pref, -1) != '/') - { - $pref .= '/'; - } - - return $pref; - } - - // -------------------------------------------------------------------- - - /** - * Site URL - * - * @access public - * @param string the URI string - * @return string - */ - function site_url($uri = '') - { - if (is_array($uri)) - { - $uri = implode('/', $uri); - } - - if ($uri == '') - { - return $this->slash_item('base_url').$this->item('index_page'); - } - else - { - $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix'); - return $this->slash_item('base_url').$this->slash_item('index_page').trim($uri, '/').$suffix; - } - } - - // -------------------------------------------------------------------- - - /** - * System URL - * - * @access public - * @return string - */ - function system_url() - { - $x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH)); - return $this->slash_item('base_url').end($x).'/'; - } - - // -------------------------------------------------------------------- - - /** - * Set a config file item - * - * @access public - * @param string the config item key - * @param string the config item value - * @return void - */ - function set_item($item, $value) - { - $this->config[$item] = $value; - } - -} - -// END CI_Config class - -/* End of file Config.php */ -/* Location: ./system/libraries/Config.php */
\ No newline at end of file diff --git a/system/libraries/Controller.php b/system/libraries/Controller.php deleted file mode 100644 index c5637c951..000000000 --- a/system/libraries/Controller.php +++ /dev/null @@ -1,127 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * CodeIgniter Application Controller Class - * - * This class object is the super class that every library in - * CodeIgniter will be assigned to. - * - * @package CodeIgniter - * @subpackage Libraries - * @category Libraries - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/general/controllers.html - */ -class Controller extends CI_Base { - - var $_ci_scaffolding = FALSE; - var $_ci_scaff_table = FALSE; - - /** - * Constructor - * - * Calls the initialize() function - */ - function Controller() - { - parent::CI_Base(); - $this->_ci_initialize(); - log_message('debug', "Controller Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Initialize - * - * Assigns all the bases classes loaded by the front controller to - * variables in this class. Also calls the autoload routine. - * - * @access private - * @return void - */ - function _ci_initialize() - { - // Assign all the class objects that were instantiated by the - // front controller to local class variables so that CI can be - // run as one big super object. - $classes = array( - 'config' => 'Config', - 'input' => 'Input', - 'benchmark' => 'Benchmark', - 'uri' => 'URI', - 'output' => 'Output', - 'lang' => 'Language', - 'router' => 'Router' - ); - - foreach ($classes as $var => $class) - { - $this->$var =& load_class($class); - } - - // In PHP 5 the Loader class is run as a discreet - // class. In PHP 4 it extends the Controller - if (floor(phpversion()) >= 5) - { - $this->load =& load_class('Loader'); - $this->load->_ci_autoloader(); - } - else - { - $this->_ci_autoloader(); - - // sync up the objects since PHP4 was working from a copy - foreach (array_keys(get_object_vars($this)) as $attribute) - { - if (is_object($this->$attribute)) - { - $this->load->$attribute =& $this->$attribute; - } - } - } - } - - // -------------------------------------------------------------------- - - /** - * Run Scaffolding - * - * @access private - * @return void - */ - function _ci_scaffolding() - { - if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE) - { - show_404('Scaffolding unavailable'); - } - - $method = ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE)) ? 'view' : $this->uri->segment(3); - - require_once(BASEPATH.'scaffolding/Scaffolding'.EXT); - $scaff = new Scaffolding($this->_ci_scaff_table); - $scaff->$method(); - } - - -} -// END _Controller class - -/* End of file Controller.php */ -/* Location: ./system/libraries/Controller.php */
\ No newline at end of file diff --git a/system/libraries/Driver.php b/system/libraries/Driver.php new file mode 100755 index 000000000..15fc3da26 --- /dev/null +++ b/system/libraries/Driver.php @@ -0,0 +1,229 @@ +<?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 EllisLab Dev Team + * @copyright Copyright (c) 2006 - 2011, EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * CodeIgniter Driver Library Class + * + * This class enables you to create "Driver" libraries that add runtime ability + * to extend the capabilities of a class via additional driver objects + * + * @package CodeIgniter + * @subpackage Libraries + * @category Libraries + * @author EllisLab Dev Team + * @link + */ +class CI_Driver_Library { + + protected $valid_drivers = array(); + protected static $lib_name; + + // The first time a child is used it won't exist, so we instantiate it + // subsequents calls will go straight to the proper child. + function __get($child) + { + if (! isset($this->lib_name)) + { + $this->lib_name = get_class($this); + } + + // The class will be prefixed with the parent lib + $child_class = $this->lib_name.'_'.$child; + + if (in_array(strtolower($child_class), array_map('strtolower', $this->valid_drivers))) + { + // check and see if the driver is in a separate file + if ( ! class_exists($child_class)) + { + // check application path first + foreach (array(APPPATH, BASEPATH) as $path) + { + // and check for case sensitivity of both the parent and child libs + foreach (array(ucfirst($this->lib_name), strtolower($this->lib_name)) as $lib) + { + // loves me some nesting! + foreach (array(ucfirst($child_class), strtolower($child_class)) as $class) + { + $filepath = $path.'libraries/'.$this->lib_name.'/drivers/'.$child_class.EXT; + + if (file_exists($filepath)) + { + include_once $filepath; + break; + } + } + } + } + + // it's a valid driver, but the file simply can't be found + if ( ! class_exists($child_class)) + { + log_message('error', "Unable to load the requested driver: ".$child_class); + show_error("Unable to load the requested driver: ".$child_class); + } + } + + $obj = new $child_class; + $obj->decorate($this); + $this->$child = $obj; + return $this->$child; + } + + // The requested driver isn't valid! + log_message('error', "Invalid driver requested: ".$child_class); + show_error("Invalid driver requested: ".$child_class); + } + + // -------------------------------------------------------------------- + +} +// END CI_Driver_Library CLASS + + +/** + * CodeIgniter Driver Class + * + * This class enables you to create drivers for a Library based on the Driver Library. + * It handles the drivers' access to the parent library + * + * @package CodeIgniter + * @subpackage Libraries + * @category Libraries + * @author EllisLab Dev Team + * @link + */ +class CI_Driver { + protected $parent; + + private $methods = array(); + private $properties = array(); + + private static $reflections = array(); + + /** + * Decorate + * + * Decorates the child with the parent driver lib's methods and properties + * + * @param object + * @return void + */ + public function decorate($parent) + { + $this->parent = $parent; + + // Lock down attributes to what is defined in the class + // and speed up references in magic methods + + $class_name = get_class($parent); + + if ( ! isset(self::$reflections[$class_name])) + { + $r = new ReflectionObject($parent); + + foreach ($r->getMethods() as $method) + { + if ($method->isPublic()) + { + $this->methods[] = $method->getName(); + } + } + + foreach($r->getProperties() as $prop) + { + if ($prop->isPublic()) + { + $this->properties[] = $prop->getName(); + } + } + + self::$reflections[$class_name] = array($this->methods, $this->properties); + } + else + { + list($this->methods, $this->properties) = self::$reflections[$class_name]; + } + } + + // -------------------------------------------------------------------- + + /** + * __call magic method + * + * Handles access to the parent driver library's methods + * + * @access public + * @param string + * @param array + * @return mixed + */ + public function __call($method, $args = array()) + { + if (in_array($method, $this->methods)) + { + return call_user_func_array(array($this->parent, $method), $args); + } + + $trace = debug_backtrace(); + _exception_handler(E_ERROR, "No such method '{$method}'", $trace[1]['file'], $trace[1]['line']); + exit; + } + + // -------------------------------------------------------------------- + + /** + * __get magic method + * + * Handles reading of the parent driver library's properties + * + * @param string + * @return mixed + */ + public function __get($var) + { + if (in_array($var, $this->properties)) + { + return $this->parent->$var; + } + } + + // -------------------------------------------------------------------- + + /** + * __set magic method + * + * Handles writing to the parent driver library's properties + * + * @param string + * @param array + * @return mixed + */ + public function __set($var, $val) + { + if (in_array($var, $this->properties)) + { + $this->parent->$var = $val; + } + } + + // -------------------------------------------------------------------- + +} +// END CI_Driver CLASS + +/* End of file Driver.php */ +/* Location: ./system/libraries/Driver.php */
\ No newline at end of file diff --git a/system/libraries/Email.php b/system/libraries/Email.php index d0f2ea9a5..e5af38f45 100644..100755 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -82,7 +82,7 @@ class CI_Email { * * The constructor can be passed an array of config values */ - function CI_Email($config = array()) + public function __construct($config = array()) { if (count($config) > 0) { @@ -106,9 +106,8 @@ class CI_Email { * @param array * @return void */ - function initialize($config = array()) + public function initialize($config = array()) { - $this->clear(); foreach ($config as $key => $val) { if (isset($this->$key)) @@ -125,11 +124,14 @@ class CI_Email { } } } + $this->clear(); $this->_smtp_auth = ($this->smtp_user == '' AND $this->smtp_pass == '') ? FALSE : TRUE; $this->_safe_mode = ((boolean)@ini_get("safe_mode") === FALSE) ? FALSE : TRUE; + + return $this; } - + // -------------------------------------------------------------------- /** @@ -138,7 +140,7 @@ class CI_Email { * @access public * @return void */ - function clear($clear_attachments = FALSE) + public function clear($clear_attachments = FALSE) { $this->_subject = ""; $this->_body = ""; @@ -146,6 +148,8 @@ class CI_Email { $this->_header_str = ""; $this->_replyto_flag = FALSE; $this->_recipients = array(); + $this->_cc_array = array(); + $this->_bcc_array = array(); $this->_headers = array(); $this->_debug_msg = array(); @@ -158,8 +162,10 @@ class CI_Email { $this->_attach_type = array(); $this->_attach_disp = array(); } + + return $this; } - + // -------------------------------------------------------------------- /** @@ -170,7 +176,7 @@ class CI_Email { * @param string * @return void */ - function from($from, $name = '') + public function from($from, $name = '') { if (preg_match( '/\<(.*)\>/', $from, $match)) { @@ -199,8 +205,10 @@ class CI_Email { $this->_set_header('From', $name.' <'.$from.'>'); $this->_set_header('Return-Path', '<'.$from.'>'); + + return $this; } - + // -------------------------------------------------------------------- /** @@ -211,7 +219,7 @@ class CI_Email { * @param string * @return void */ - function reply_to($replyto, $name = '') + public function reply_to($replyto, $name = '') { if (preg_match( '/\<(.*)\>/', $replyto, $match)) { @@ -235,8 +243,10 @@ class CI_Email { $this->_set_header('Reply-To', $name.' <'.$replyto.'>'); $this->_replyto_flag = TRUE; + + return $this; } - + // -------------------------------------------------------------------- /** @@ -246,7 +256,7 @@ class CI_Email { * @param string * @return void */ - function to($to) + public function to($to) { $to = $this->_str_to_array($to); $to = $this->clean_email($to); @@ -263,15 +273,18 @@ class CI_Email { switch ($this->_get_protocol()) { - case 'smtp' : $this->_recipients = $to; - break; - case 'sendmail' : $this->_recipients = implode(", ", $to); + case 'smtp' : + $this->_recipients = $to; break; - case 'mail' : $this->_recipients = implode(", ", $to); + case 'sendmail' : + case 'mail' : + $this->_recipients = implode(", ", $to); break; } + + return $this; } - + // -------------------------------------------------------------------- /** @@ -281,7 +294,7 @@ class CI_Email { * @param string * @return void */ - function cc($cc) + public function cc($cc) { $cc = $this->_str_to_array($cc); $cc = $this->clean_email($cc); @@ -297,8 +310,10 @@ class CI_Email { { $this->_cc_array = $cc; } + + return $this; } - + // -------------------------------------------------------------------- /** @@ -309,7 +324,7 @@ class CI_Email { * @param string * @return void */ - function bcc($bcc, $limit = '') + public function bcc($bcc, $limit = '') { if ($limit != '' && is_numeric($limit)) { @@ -333,8 +348,10 @@ class CI_Email { { $this->_set_header('Bcc', implode(", ", $bcc)); } + + return $this; } - + // -------------------------------------------------------------------- /** @@ -344,12 +361,13 @@ class CI_Email { * @param string * @return void */ - function subject($subject) + public function subject($subject) { $subject = $this->_prep_q_encoding($subject); $this->_set_header('Subject', $subject); + return $this; } - + // -------------------------------------------------------------------- /** @@ -359,11 +377,12 @@ class CI_Email { * @param string * @return void */ - function message($body) + public function message($body) { $this->_body = stripslashes(rtrim(str_replace("\r", "", $body))); + return $this; } - + // -------------------------------------------------------------------- /** @@ -373,11 +392,12 @@ class CI_Email { * @param string * @return void */ - function attach($filename, $disposition = 'attachment') + public function attach($filename, $disposition = 'attachment') { $this->_attach_name[] = $filename; $this->_attach_type[] = $this->_mime_types(next(explode('.', basename($filename)))); $this->_attach_disp[] = $disposition; // Can also be 'inline' Not sure if it matters + return $this; } // -------------------------------------------------------------------- @@ -390,11 +410,11 @@ class CI_Email { * @param string * @return void */ - function _set_header($header, $value) + private function _set_header($header, $value) { $this->_headers[$header] = $value; } - + // -------------------------------------------------------------------- /** @@ -404,7 +424,7 @@ class CI_Email { * @param string * @return array */ - function _str_to_array($email) + private function _str_to_array($email) { if ( ! is_array($email)) { @@ -420,7 +440,7 @@ class CI_Email { } return $email; } - + // -------------------------------------------------------------------- /** @@ -430,11 +450,12 @@ class CI_Email { * @param string * @return void */ - function set_alt_message($str = '') + public function set_alt_message($str = '') { $this->alt_message = ($str == '') ? '' : $str; + return $this; } - + // -------------------------------------------------------------------- /** @@ -444,11 +465,12 @@ class CI_Email { * @param string * @return void */ - function set_mailtype($type = 'text') + public function set_mailtype($type = 'text') { $this->mailtype = ($type == 'html') ? 'html' : 'text'; + return $this; } - + // -------------------------------------------------------------------- /** @@ -458,11 +480,12 @@ class CI_Email { * @param string * @return void */ - function set_wordwrap($wordwrap = TRUE) + public function set_wordwrap($wordwrap = TRUE) { $this->wordwrap = ($wordwrap === FALSE) ? FALSE : TRUE; + return $this; } - + // -------------------------------------------------------------------- /** @@ -472,11 +495,12 @@ class CI_Email { * @param string * @return void */ - function set_protocol($protocol = 'mail') + public function set_protocol($protocol = 'mail') { $this->protocol = ( ! in_array($protocol, $this->_protocols, TRUE)) ? 'mail' : strtolower($protocol); + return $this; } - + // -------------------------------------------------------------------- /** @@ -486,7 +510,7 @@ class CI_Email { * @param integer * @return void */ - function set_priority($n = 3) + public function set_priority($n = 3) { if ( ! is_numeric($n)) { @@ -501,8 +525,9 @@ class CI_Email { } $this->priority = $n; + return $this; } - + // -------------------------------------------------------------------- /** @@ -512,7 +537,7 @@ class CI_Email { * @param string * @return void */ - function set_newline($newline = "\n") + public function set_newline($newline = "\n") { if ($newline != "\n" AND $newline != "\r\n" AND $newline != "\r") { @@ -521,8 +546,10 @@ class CI_Email { } $this->newline = $newline; + + return $this; } - + // -------------------------------------------------------------------- /** @@ -532,7 +559,7 @@ class CI_Email { * @param string * @return void */ - function set_crlf($crlf = "\n") + public function set_crlf($crlf = "\n") { if ($crlf != "\n" AND $crlf != "\r\n" AND $crlf != "\r") { @@ -541,8 +568,10 @@ class CI_Email { } $this->crlf = $crlf; + + return $this; } - + // -------------------------------------------------------------------- /** @@ -551,12 +580,12 @@ class CI_Email { * @access private * @return void */ - function _set_boundaries() + private function _set_boundaries() { $this->_alt_boundary = "B_ALT_".uniqid(''); // multipart/alternative $this->_atc_boundary = "B_ATC_".uniqid(''); // attachment boundary } - + // -------------------------------------------------------------------- /** @@ -565,7 +594,7 @@ class CI_Email { * @access private * @return string */ - function _get_message_id() + private function _get_message_id() { $from = $this->_headers['Return-Path']; $from = str_replace(">", "", $from); @@ -573,7 +602,7 @@ class CI_Email { return "<".uniqid('').strstr($from, '@').">"; } - + // -------------------------------------------------------------------- /** @@ -583,7 +612,7 @@ class CI_Email { * @param bool * @return string */ - function _get_protocol($return = TRUE) + private function _get_protocol($return = TRUE) { $this->protocol = strtolower($this->protocol); $this->protocol = ( ! in_array($this->protocol, $this->_protocols, TRUE)) ? 'mail' : $this->protocol; @@ -593,7 +622,7 @@ class CI_Email { return $this->protocol; } } - + // -------------------------------------------------------------------- /** @@ -603,7 +632,7 @@ class CI_Email { * @param bool * @return string */ - function _get_encoding($return = TRUE) + private function _get_encoding($return = TRUE) { $this->_encoding = ( ! in_array($this->_encoding, $this->_bit_depths)) ? '8bit' : $this->_encoding; @@ -629,7 +658,7 @@ class CI_Email { * @access private * @return string */ - function _get_content_type() + private function _get_content_type() { if ($this->mailtype == 'html' && count($this->_attach_name) == 0) { @@ -648,7 +677,7 @@ class CI_Email { return 'plain'; } } - + // -------------------------------------------------------------------- /** @@ -657,7 +686,7 @@ class CI_Email { * @access private * @return string */ - function _set_date() + private function _set_date() { $timezone = date("Z"); $operator = (strncmp($timezone, '-', 1) == 0) ? '-' : '+'; @@ -666,7 +695,7 @@ class CI_Email { return sprintf("%s %s%04d", date("D, j M Y H:i:s"), $operator, $timezone); } - + // -------------------------------------------------------------------- /** @@ -675,11 +704,11 @@ class CI_Email { * @access private * @return string */ - function _get_mime_message() + private function _get_mime_message() { return "This is a multi-part message in MIME format.".$this->newline."Your email application may not support this format."; } - + // -------------------------------------------------------------------- /** @@ -689,7 +718,7 @@ class CI_Email { * @param string * @return bool */ - function validate_email($email) + public function validate_email($email) { if ( ! is_array($email)) { @@ -708,7 +737,7 @@ class CI_Email { return TRUE; } - + // -------------------------------------------------------------------- /** @@ -718,11 +747,11 @@ class CI_Email { * @param string * @return bool */ - function valid_email($address) + public function valid_email($address) { return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- /** @@ -732,17 +761,17 @@ class CI_Email { * @param string * @return string */ - function clean_email($email) + public function clean_email($email) { if ( ! is_array($email)) { if (preg_match('/\<(.*)\>/', $email, $match)) { - return $match['1']; + return $match['1']; } - else + else { - return $email; + return $email; } } @@ -752,23 +781,23 @@ class CI_Email { { if (preg_match( '/\<(.*)\>/', $addy, $match)) { - $clean_email[] = $match['1']; + $clean_email[] = $match['1']; } - else + else { - $clean_email[] = $addy; + $clean_email[] = $addy; } } return $clean_email; } - + // -------------------------------------------------------------------- /** * Build alternative plain text message * - * This function provides the raw message for use + * This public function provides the raw message for use * in plain-text headers of HTML-formatted emails. * If the user hasn't specified his own alternative message * it creates one by stripping the HTML @@ -776,7 +805,7 @@ class CI_Email { * @access private * @return string */ - function _get_alt_message() + private function _get_alt_message() { if ($this->alt_message != "") { @@ -802,7 +831,7 @@ class CI_Email { for ($x = 1; $x <= $i; $x ++) { - $n .= "\n"; + $n .= "\n"; } $body = str_replace($n, "\n\n", $body); @@ -810,7 +839,7 @@ class CI_Email { return $this->word_wrap($body, '76'); } - + // -------------------------------------------------------------------- /** @@ -821,7 +850,7 @@ class CI_Email { * @param integer * @return string */ - function word_wrap($str, $charlim = '') + public function word_wrap($str, $charlim = '') { // Se the character limit if ($charlim == '') @@ -850,7 +879,7 @@ class CI_Email { } } - // Use PHP's native function to do the initial wordwrap. + // Use PHP's native public function to do the initial wordwrap. // We set the cut flag to FALSE so that any individual words that are // too long get left alone. In the next step we'll deal with them. $str = wordwrap($str, $charlim, "\n", FALSE); @@ -906,7 +935,7 @@ class CI_Email { return $output; } - + // -------------------------------------------------------------------- /** @@ -916,7 +945,7 @@ class CI_Email { * @param string * @return string */ - function _build_headers() + private function _build_headers() { $this->_set_header('X-Sender', $this->clean_email($this->_headers['From'])); $this->_set_header('X-Mailer', $this->useragent); @@ -924,7 +953,7 @@ class CI_Email { $this->_set_header('Message-ID', $this->_get_message_id()); $this->_set_header('Mime-Version', '1.0'); } - + // -------------------------------------------------------------------- /** @@ -933,7 +962,7 @@ class CI_Email { * @access private * @return void */ - function _write_headers() + private function _write_headers() { if ($this->protocol == 'mail') { @@ -959,7 +988,7 @@ class CI_Email { $this->_header_str = rtrim($this->_header_str); } } - + // -------------------------------------------------------------------- /** @@ -968,7 +997,7 @@ class CI_Email { * @access private * @return void */ - function _build_message() + private function _build_message() { if ($this->wordwrap === TRUE AND $this->mailtype != 'html') { @@ -979,6 +1008,7 @@ class CI_Email { $this->_write_headers(); $hdr = ($this->_get_protocol() == 'mail') ? $this->newline : ''; + $body = ''; switch ($this->_get_content_type()) { @@ -991,13 +1021,12 @@ class CI_Email { { $this->_header_str .= $hdr; $this->_finalbody = $this->_body; - - return; + } + else + { + $this->_finalbody = $hdr . $this->newline . $this->newline . $this->_body; } - $hdr .= $this->newline . $this->newline . $this->_body; - - $this->_finalbody = $hdr; return; break; @@ -1011,93 +1040,81 @@ class CI_Email { else { $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline . $this->newline; - $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; - $hdr .= "--" . $this->_alt_boundary . $this->newline; - $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; - $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; - $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; + $body .= $this->_get_mime_message() . $this->newline . $this->newline; + $body .= "--" . $this->_alt_boundary . $this->newline; - $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; - $hdr .= "Content-Transfer-Encoding: quoted-printable"; + $body .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; + $body .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; + $body .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; + + $body .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; + $body .= "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline; } - $this->_body = $this->_prep_quoted_printable($this->_body); + $this->_finalbody = $body . $this->_prep_quoted_printable($this->_body) . $this->newline . $this->newline; + if ($this->_get_protocol() == 'mail') { $this->_header_str .= $hdr; - $this->_finalbody = $this->_body . $this->newline . $this->newline; - - if ($this->send_multipart !== FALSE) - { - $this->_finalbody .= "--" . $this->_alt_boundary . "--"; - } - - return; + } + else + { + $this->_finalbody = $hdr . $this->_finalbody; } - $hdr .= $this->newline . $this->newline; - $hdr .= $this->_body . $this->newline . $this->newline; if ($this->send_multipart !== FALSE) { - $hdr .= "--" . $this->_alt_boundary . "--"; + $this->_finalbody .= "--" . $this->_alt_boundary . "--"; } - $this->_finalbody = $hdr; return; break; case 'plain-attach' : $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline . $this->newline; - $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; - $hdr .= "--" . $this->_atc_boundary . $this->newline; - - $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; - $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding(); if ($this->_get_protocol() == 'mail') { $this->_header_str .= $hdr; - - $body = $this->_body . $this->newline . $this->newline; } - $hdr .= $this->newline . $this->newline; - $hdr .= $this->_body . $this->newline . $this->newline; + $body .= $this->_get_mime_message() . $this->newline . $this->newline; + $body .= "--" . $this->_atc_boundary . $this->newline; + + $body .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; + $body .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; + + $body .= $this->_body . $this->newline . $this->newline; break; case 'html-attach' : $hdr .= "Content-Type: multipart/".$this->multipart."; boundary=\"" . $this->_atc_boundary."\"" . $this->newline . $this->newline; - $hdr .= $this->_get_mime_message() . $this->newline . $this->newline; - $hdr .= "--" . $this->_atc_boundary . $this->newline; - - $hdr .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline; - $hdr .= "--" . $this->_alt_boundary . $this->newline; - - $hdr .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; - $hdr .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; - $hdr .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; - - $hdr .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; - $hdr .= "Content-Transfer-Encoding: quoted-printable"; - - $this->_body = $this->_prep_quoted_printable($this->_body); if ($this->_get_protocol() == 'mail') { $this->_header_str .= $hdr; - - $body = $this->_body . $this->newline . $this->newline; - $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline; } - $hdr .= $this->newline . $this->newline; - $hdr .= $this->_body . $this->newline . $this->newline; - $hdr .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline; + $body .= $this->_get_mime_message() . $this->newline . $this->newline; + $body .= "--" . $this->_atc_boundary . $this->newline; + + $body .= "Content-Type: multipart/alternative; boundary=\"" . $this->_alt_boundary . "\"" . $this->newline .$this->newline; + $body .= "--" . $this->_alt_boundary . $this->newline; + + $body .= "Content-Type: text/plain; charset=" . $this->charset . $this->newline; + $body .= "Content-Transfer-Encoding: " . $this->_get_encoding() . $this->newline . $this->newline; + $body .= $this->_get_alt_message() . $this->newline . $this->newline . "--" . $this->_alt_boundary . $this->newline; + + $body .= "Content-Type: text/html; charset=" . $this->charset . $this->newline; + $body .= "Content-Transfer-Encoding: quoted-printable" . $this->newline . $this->newline; + + $body .= $this->_prep_quoted_printable($this->_body) . $this->newline . $this->newline; + $body .= "--" . $this->_alt_boundary . "--" . $this->newline . $this->newline; break; } @@ -1137,18 +1154,21 @@ class CI_Email { fclose($fp); } + $body .= implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; + + if ($this->_get_protocol() == 'mail') { - $this->_finalbody = $body . implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; - - return; + $this->_finalbody = $body; + } + else + { + $this->_finalbody = $hdr . $body; } - - $this->_finalbody = $hdr.implode($this->newline, $attachment).$this->newline."--".$this->_atc_boundary."--"; return; } - + // -------------------------------------------------------------------- /** @@ -1162,7 +1182,7 @@ class CI_Email { * @param integer * @return string */ - function _prep_quoted_printable($str, $charlim = '') + private function _prep_quoted_printable($str, $charlim = '') { // Set the character limit // Don't allow over 76, as that will make servers and MUAs barf @@ -1243,7 +1263,7 @@ class CI_Email { } // -------------------------------------------------------------------- - + /** * Prep Q Encoding * @@ -1255,7 +1275,7 @@ class CI_Email { * @param bool // set to TRUE for processing From: headers * @return str */ - function _prep_q_encoding($str, $from = FALSE) + private function _prep_q_encoding($str, $from = FALSE) { $str = str_replace(array("\r", "\n"), array('', ''), $str); @@ -1315,14 +1335,14 @@ class CI_Email { } // -------------------------------------------------------------------- - + /** * Send Email * * @access public * @return bool */ - function send() + public function send() { if ($this->_replyto_flag == FALSE) { @@ -1356,7 +1376,7 @@ class CI_Email { return TRUE; } } - + // -------------------------------------------------------------------- /** @@ -1365,7 +1385,7 @@ class CI_Email { * @access public * @return bool */ - function batch_bcc_send() + public function batch_bcc_send() { $float = $this->bcc_batch_size -1; @@ -1414,7 +1434,7 @@ class CI_Email { $this->_spool_email(); } } - + // -------------------------------------------------------------------- /** @@ -1423,11 +1443,11 @@ class CI_Email { * @access private * @return void */ - function _unwrap_specials() + private function _unwrap_specials() { $this->_finalbody = preg_replace_callback("/\{unwrap\}(.*?)\{\/unwrap\}/si", array($this, '_remove_nl_callback'), $this->_finalbody); } - + // -------------------------------------------------------------------- /** @@ -1436,7 +1456,7 @@ class CI_Email { * @access private * @return string */ - function _remove_nl_callback($matches) + private function _remove_nl_callback($matches) { if (strpos($matches[1], "\r") !== FALSE OR strpos($matches[1], "\n") !== FALSE) { @@ -1445,7 +1465,7 @@ class CI_Email { return $matches[1]; } - + // -------------------------------------------------------------------- /** @@ -1454,7 +1474,7 @@ class CI_Email { * @access private * @return bool */ - function _spool_email() + private function _spool_email() { $this->_unwrap_specials(); @@ -1490,7 +1510,7 @@ class CI_Email { $this->_set_error_message('email_sent', $this->_get_protocol()); return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1499,7 +1519,7 @@ class CI_Email { * @access private * @return bool */ - function _send_with_mail() + private function _send_with_mail() { if ($this->_safe_mode == TRUE) { @@ -1516,6 +1536,7 @@ class CI_Email { { // most documentation of sendmail using the "-f" flag lacks a space after it, however // we've encountered servers that seem to require it to be in place. + if ( ! mail($this->_recipients, $this->_subject, $this->_finalbody, $this->_header_str, "-f ".$this->clean_email($this->_headers['From']))) { return FALSE; @@ -1526,7 +1547,7 @@ class CI_Email { } } } - + // -------------------------------------------------------------------- /** @@ -1535,7 +1556,7 @@ class CI_Email { * @access private * @return bool */ - function _send_with_sendmail() + private function _send_with_sendmail() { $fp = @popen($this->mailpath . " -oi -f ".$this->clean_email($this->_headers['From'])." -t", 'w'); @@ -1544,17 +1565,17 @@ class CI_Email { // server probably has popen disabled, so nothing we can do to get a verbose error. return FALSE; } - + fputs($fp, $this->_header_str); fputs($fp, $this->_finalbody); - $status = pclose($fp); - + $status = pclose($fp); + if (version_compare(PHP_VERSION, '4.2.3') == -1) { $status = $status >> 8 & 0xFF; - } - + } + if ($status != 0) { $this->_set_error_message('email_exit_status', $status); @@ -1564,7 +1585,7 @@ class CI_Email { return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1573,7 +1594,7 @@ class CI_Email { * @access private * @return bool */ - function _send_with_smtp() + private function _send_with_smtp() { if ($this->smtp_host == '') { @@ -1633,7 +1654,7 @@ class CI_Email { $this->_send_command('quit'); return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1643,7 +1664,7 @@ class CI_Email { * @param string * @return string */ - function _smtp_connect() + private function _smtp_connect() { $this->_smtp_connect = fsockopen($this->smtp_host, $this->smtp_port, @@ -1660,7 +1681,7 @@ class CI_Email { $this->_set_error_message($this->_get_smtp_data()); return $this->_send_command('hello'); } - + // -------------------------------------------------------------------- /** @@ -1671,7 +1692,7 @@ class CI_Email { * @param string * @return string */ - function _send_command($cmd, $data = '') + private function _send_command($cmd, $data = '') { switch ($cmd) { @@ -1727,7 +1748,7 @@ class CI_Email { return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1736,7 +1757,7 @@ class CI_Email { * @access private * @return bool */ - function _smtp_authenticate() + private function _smtp_authenticate() { if ( ! $this->_smtp_auth) { @@ -1781,7 +1802,7 @@ class CI_Email { return TRUE; } - + // -------------------------------------------------------------------- /** @@ -1790,7 +1811,7 @@ class CI_Email { * @access private * @return bool */ - function _send_data($data) + private function _send_data($data) { if ( ! fwrite($this->_smtp_connect, $data . $this->newline)) { @@ -1802,7 +1823,7 @@ class CI_Email { return TRUE; } } - + // -------------------------------------------------------------------- /** @@ -1811,7 +1832,7 @@ class CI_Email { * @access private * @return string */ - function _get_smtp_data() + private function _get_smtp_data() { $data = ""; @@ -1827,7 +1848,7 @@ class CI_Email { return $data; } - + // -------------------------------------------------------------------- /** @@ -1836,11 +1857,11 @@ class CI_Email { * @access private * @return string */ - function _get_hostname() + private function _get_hostname() { return (isset($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : 'localhost.localdomain'; } - + // -------------------------------------------------------------------- /** @@ -1849,7 +1870,7 @@ class CI_Email { * @access private * @return string */ - function _get_ip() + private function _get_ip() { if ($this->_IP !== FALSE) { @@ -1860,12 +1881,12 @@ class CI_Email { $rip = (isset($_SERVER['REMOTE_ADDR']) AND $_SERVER['REMOTE_ADDR'] != "") ? $_SERVER['REMOTE_ADDR'] : FALSE; $fip = (isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND $_SERVER['HTTP_X_FORWARDED_FOR'] != "") ? $_SERVER['HTTP_X_FORWARDED_FOR'] : FALSE; - if ($cip && $rip) $this->_IP = $cip; + if ($cip && $rip) $this->_IP = $cip; elseif ($rip) $this->_IP = $rip; elseif ($cip) $this->_IP = $cip; elseif ($fip) $this->_IP = $fip; - if (strstr($this->_IP, ',')) + if (strpos($this->_IP, ',') !== FALSE) { $x = explode(',', $this->_IP); $this->_IP = end($x); @@ -1882,7 +1903,7 @@ class CI_Email { return $this->_IP; } - + // -------------------------------------------------------------------- /** @@ -1891,7 +1912,7 @@ class CI_Email { * @access public * @return string */ - function print_debugger() + public function print_debugger() { $msg = ''; @@ -1906,7 +1927,7 @@ class CI_Email { $msg .= "<pre>".$this->_header_str."\n".htmlspecialchars($this->_subject)."\n".htmlspecialchars($this->_finalbody).'</pre>'; return $msg; } - + // -------------------------------------------------------------------- /** @@ -1916,7 +1937,7 @@ class CI_Email { * @param string * @return string */ - function _set_error_message($msg, $val = '') + private function _set_error_message($msg, $val = '') { $CI =& get_instance(); $CI->lang->load('email'); @@ -1930,7 +1951,7 @@ class CI_Email { $this->_debug_msg[] = str_replace('%s', $val, $line)."<br />"; } } - + // -------------------------------------------------------------------- /** @@ -1940,7 +1961,7 @@ class CI_Email { * @param string * @return string */ - function _mime_types($ext = "") + private function _mime_types($ext = "") { $mimes = array( 'hqx' => 'application/mac-binhex40', 'cpt' => 'application/mac-compactpro', diff --git a/system/libraries/Encrypt.php b/system/libraries/Encrypt.php index c893fbf9e..e5f65878a 100644..100755 --- a/system/libraries/Encrypt.php +++ b/system/libraries/Encrypt.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -41,7 +41,7 @@ class CI_Encrypt { * Simply determines whether the mcrypt library exists. * */ - function CI_Encrypt() + public function __construct() { $this->CI =& get_instance(); $this->_mcrypt_exists = ( ! function_exists('mcrypt_encrypt')) ? FALSE : TRUE; @@ -72,7 +72,7 @@ class CI_Encrypt { $CI =& get_instance(); $key = $CI->config->item('encryption_key'); - if ($key === FALSE) + if ($key == FALSE) { show_error('In order to use the encryption class requires that you set an encryption key in your config file.'); } @@ -116,12 +116,16 @@ class CI_Encrypt { function encode($string, $key = '') { $key = $this->get_key($key); - $enc = $this->_xor_encode($string, $key); - + if ($this->_mcrypt_exists === TRUE) { - $enc = $this->mcrypt_encode($enc, $key); + $enc = $this->mcrypt_encode($string, $key); + } + else + { + $enc = $this->_xor_encode($string, $key); } + return base64_encode($enc); } @@ -140,7 +144,7 @@ class CI_Encrypt { function decode($string, $key = '') { $key = $this->get_key($key); - + if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string)) { return FALSE; @@ -155,8 +159,67 @@ class CI_Encrypt { return FALSE; } } + else + { + $dec = $this->_xor_decode($dec, $key); + } - return $this->_xor_decode($dec, $key); + return $dec; + } + + // -------------------------------------------------------------------- + + /** + * Encode from Legacy + * + * Takes an encoded string from the original Encryption class algorithms and + * returns a newly encoded string using the improved method added in 2.0.0 + * This allows for backwards compatibility and a method to transition to the + * new encryption algorithms. + * + * For more details, see http://codeigniter.com/user_guide/installation/upgrade_200.html#encryption + * + * @access public + * @param string + * @param int (mcrypt mode constant) + * @param string + * @return string + */ + function encode_from_legacy($string, $legacy_mode = MCRYPT_MODE_ECB, $key = '') + { + if ($this->_mcrypt_exists === FALSE) + { + log_message('error', 'Encoding from legacy is available only when Mcrypt is in use.'); + return FALSE; + } + + // decode it first + // set mode temporarily to what it was when string was encoded with the legacy + // algorithm - typically MCRYPT_MODE_ECB + $current_mode = $this->_get_mode(); + $this->set_mode($legacy_mode); + + $key = $this->get_key($key); + + if (preg_match('/[^a-zA-Z0-9\/\+=]/', $string)) + { + return FALSE; + } + + $dec = base64_decode($string); + + if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE) + { + return FALSE; + } + + $dec = $this->_xor_decode($dec, $key); + + // set the mcrypt mode back to what it should be, typically MCRYPT_MODE_CBC + $this->set_mode($current_mode); + + // and re-encode + return base64_encode($this->mcrypt_encode($dec, $key)); } // -------------------------------------------------------------------- @@ -184,7 +247,7 @@ class CI_Encrypt { $enc = ''; for ($i = 0; $i < strlen($string); $i++) - { + { $enc .= substr($rand, ($i % strlen($rand)), 1).(substr($rand, ($i % strlen($rand)), 1) ^ substr($string, $i, 1)); } @@ -347,7 +410,7 @@ class CI_Encrypt { { $temp = $temp + 256; } - + $str .= chr($temp); } @@ -355,7 +418,7 @@ class CI_Encrypt { } // -------------------------------------------------------------------- - + /** * Set the Mcrypt Cipher * @@ -412,9 +475,9 @@ class CI_Encrypt { { if ($this->_mcrypt_mode == '') { - $this->_mcrypt_mode = MCRYPT_MODE_ECB; + $this->_mcrypt_mode = MCRYPT_MODE_CBC; } - + return $this->_mcrypt_mode; } @@ -440,7 +503,7 @@ class CI_Encrypt { * @access public * @param string * @return string - */ + */ function hash($str) { return ($this->_hash_type == 'sha1') ? $this->sha1($str) : md5($str); diff --git a/system/libraries/Exceptions.php b/system/libraries/Exceptions.php deleted file mode 100644 index bd567ccdc..000000000 --- a/system/libraries/Exceptions.php +++ /dev/null @@ -1,174 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * Exceptions Class - * - * @package CodeIgniter - * @subpackage Libraries - * @category Exceptions - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/exceptions.html - */ -class CI_Exceptions { - var $action; - var $severity; - var $message; - var $filename; - var $line; - var $ob_level; - - var $levels = array( - E_ERROR => 'Error', - E_WARNING => 'Warning', - E_PARSE => 'Parsing Error', - E_NOTICE => 'Notice', - E_CORE_ERROR => 'Core Error', - E_CORE_WARNING => 'Core Warning', - E_COMPILE_ERROR => 'Compile Error', - E_COMPILE_WARNING => 'Compile Warning', - E_USER_ERROR => 'User Error', - E_USER_WARNING => 'User Warning', - E_USER_NOTICE => 'User Notice', - E_STRICT => 'Runtime Notice' - ); - - - /** - * Constructor - * - */ - function CI_Exceptions() - { - $this->ob_level = ob_get_level(); - // Note: Do not log messages from this constructor. - } - - // -------------------------------------------------------------------- - - /** - * Exception Logger - * - * This function logs PHP generated error messages - * - * @access private - * @param string the error severity - * @param string the error string - * @param string the error filepath - * @param string the error line number - * @return string - */ - function log_exception($severity, $message, $filepath, $line) - { - $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity]; - - log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE); - } - - // -------------------------------------------------------------------- - - /** - * 404 Page Not Found Handler - * - * @access private - * @param string - * @return string - */ - function show_404($page = '') - { - $heading = "404 Page Not Found"; - $message = "The page you requested was not found."; - - log_message('error', '404 Page Not Found --> '.$page); - echo $this->show_error($heading, $message, 'error_404', 404); - exit; - } - - // -------------------------------------------------------------------- - - /** - * General Error Page - * - * This function takes an error message as input - * (either as a string or an array) and displays - * it using the specified template. - * - * @access private - * @param string the heading - * @param string the message - * @param string the template name - * @return string - */ - function show_error($heading, $message, $template = 'error_general', $status_code = 500) - { - set_status_header($status_code); - - $message = '<p>'.implode('</p><p>', ( ! is_array($message)) ? array($message) : $message).'</p>'; - - if (ob_get_level() > $this->ob_level + 1) - { - ob_end_flush(); - } - ob_start(); - include(APPPATH.'errors/'.$template.EXT); - $buffer = ob_get_contents(); - ob_end_clean(); - return $buffer; - } - - // -------------------------------------------------------------------- - - /** - * Native PHP error handler - * - * @access private - * @param string the error severity - * @param string the error string - * @param string the error filepath - * @param string the error line number - * @return string - */ - function show_php_error($severity, $message, $filepath, $line) - { - $severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity]; - - $filepath = str_replace("\\", "/", $filepath); - - // For safety reasons we do not show the full file path - if (FALSE !== strpos($filepath, '/')) - { - $x = explode('/', $filepath); - $filepath = $x[count($x)-2].'/'.end($x); - } - - if (ob_get_level() > $this->ob_level + 1) - { - ob_end_flush(); - } - ob_start(); - include(APPPATH.'errors/error_php'.EXT); - $buffer = ob_get_contents(); - ob_end_clean(); - echo $buffer; - } - - -} -// END Exceptions Class - -/* End of file Exceptions.php */ -/* Location: ./system/libraries/Exceptions.php */
\ No newline at end of file diff --git a/system/libraries/Form_validation.php b/system/libraries/Form_validation.php index 640bf9180..fc5b82ee3 100644..100755 --- a/system/libraries/Form_validation.php +++ b/system/libraries/Form_validation.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -25,29 +25,28 @@ * @link http://codeigniter.com/user_guide/libraries/form_validation.html */ class CI_Form_validation { - + var $CI; - var $_field_data = array(); + var $_field_data = array(); var $_config_rules = array(); var $_error_array = array(); - var $_error_messages = array(); + var $_error_messages = array(); var $_error_prefix = '<p>'; var $_error_suffix = '</p>'; var $error_string = ''; - var $_safe_form_data = FALSE; + var $_safe_form_data = FALSE; /** * Constructor - * - */ - function CI_Form_validation($rules = array()) - { + */ + public function __construct($rules = array()) + { $this->CI =& get_instance(); - + // Validation rules can be stored in a config file. $this->_config_rules = $rules; - + // Automatically load the form helper $this->CI->load->helper('form'); @@ -56,12 +55,12 @@ class CI_Form_validation { { mb_internal_encoding($this->CI->config->item('charset')); } - + log_message('debug', "Form Validation Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Set Rules * @@ -78,9 +77,9 @@ class CI_Form_validation { // No reason to set rules if we have no POST data if (count($_POST) == 0) { - return; + return $this; } - + // If an array was passed via the first parameter instead of indidual string // values we cycle through it and recursively call this function. if (is_array($field)) @@ -99,13 +98,13 @@ class CI_Form_validation { // Here we go! $this->set_rules($row['field'], $label, $row['rules']); } - return; + return $this; } - + // No fields? Nothing to do... if ( ! is_string($field) OR ! is_string($rules) OR $field == '') { - return; + return $this; } // If the field label wasn't passed we use the field name @@ -113,9 +112,9 @@ class CI_Form_validation { // Is the field name an array? We test for the existence of a bracket "[" in // the field name to determine this. If it is an array, we break it apart - // into its components so that we can fetch the corresponding POST data later + // into its components so that we can fetch the corresponding POST data later if (strpos($field, '[') !== FALSE AND preg_match_all('/\[(.*?)\]/', $field, $matches)) - { + { // Note: Due to a bug in current() that affects some versions // of PHP we can not pass function call directly into it $x = explode('[', $field); @@ -128,29 +127,31 @@ class CI_Form_validation { $indexes[] = $matches['1'][$i]; } } - + $is_array = TRUE; } else { - $indexes = array(); - $is_array = FALSE; + $indexes = array(); + $is_array = FALSE; } - - // Build our master array + + // Build our master array $this->_field_data[$field] = array( - 'field' => $field, - 'label' => $label, + 'field' => $field, + 'label' => $label, 'rules' => $rules, 'is_array' => $is_array, 'keys' => $indexes, 'postdata' => NULL, 'error' => '' ); + + return $this; } // -------------------------------------------------------------------- - + /** * Set Error Message * @@ -168,12 +169,14 @@ class CI_Form_validation { { $lang = array($lang => $val); } - + $this->_error_messages = array_merge($this->_error_messages, $lang); + + return $this; } - + // -------------------------------------------------------------------- - + /** * Set The Error Delimiter * @@ -183,15 +186,17 @@ class CI_Form_validation { * @param string * @param string * @return void - */ + */ function set_error_delimiters($prefix = '<p>', $suffix = '</p>') { $this->_error_prefix = $prefix; $this->_error_suffix = $suffix; + + return $this; } // -------------------------------------------------------------------- - + /** * Get Error Message * @@ -200,14 +205,14 @@ class CI_Form_validation { * @access public * @param string the field name * @return void - */ + */ function error($field = '', $prefix = '', $suffix = '') - { + { if ( ! isset($this->_field_data[$field]['error']) OR $this->_field_data[$field]['error'] == '') { return ''; } - + if ($prefix == '') { $prefix = $this->_error_prefix; @@ -222,7 +227,7 @@ class CI_Form_validation { } // -------------------------------------------------------------------- - + /** * Error String * @@ -232,7 +237,7 @@ class CI_Form_validation { * @param string * @param string * @return str - */ + */ function error_string($prefix = '', $suffix = '') { // No errrors, validation passes! @@ -240,7 +245,7 @@ class CI_Form_validation { { return ''; } - + if ($prefix == '') { $prefix = $this->_error_prefix; @@ -250,7 +255,7 @@ class CI_Form_validation { { $suffix = $this->_error_suffix; } - + // Generate the error string $str = ''; foreach ($this->_error_array as $val) @@ -260,12 +265,12 @@ class CI_Form_validation { $str .= $prefix.$val.$suffix."\n"; } } - + return $str; } // -------------------------------------------------------------------- - + /** * Run the Validator * @@ -273,7 +278,7 @@ class CI_Form_validation { * * @access public * @return bool - */ + */ function run($group = '') { // Do we even have any data to process? Mm? @@ -281,7 +286,7 @@ class CI_Form_validation { { return FALSE; } - + // Does the _field_data array containing the validation rules exist? // If not, we look to see if they were assigned via a config file if (count($this->_field_data) == 0) @@ -291,10 +296,10 @@ class CI_Form_validation { { return FALSE; } - + // Is there a validation rule for the particular URI being accessed? $uri = ($group == '') ? trim($this->CI->uri->ruri_string(), '/') : $group; - + if ($uri != '' AND isset($this->_config_rules[$uri])) { $this->set_rules($this->_config_rules[$uri]); @@ -303,7 +308,7 @@ class CI_Form_validation { { $this->set_rules($this->_config_rules); } - + // We're we able to set the rules correctly? if (count($this->_field_data) == 0) { @@ -311,17 +316,17 @@ class CI_Form_validation { return FALSE; } } - + // Load the language file containing error messages $this->CI->lang->load('form_validation'); - - // Cycle through the rules for each field, match the + + // Cycle through the rules for each field, match the // corresponding $_POST item and test for errors foreach ($this->_field_data as $field => $row) - { + { // Fetch the data from the corresponding $_POST array and cache it in the _field_data array. // Depending on whether the field name is an array or a string will determine where we get it from. - + if ($row['is_array'] == TRUE) { $this->_field_data[$field]['postdata'] = $this->_reduce_array($_POST, $row['keys']); @@ -333,8 +338,8 @@ class CI_Form_validation { $this->_field_data[$field]['postdata'] = $_POST[$field]; } } - - $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']); + + $this->_execute($row, explode('|', $row['rules']), $this->_field_data[$field]['postdata']); } // Did we end up with any errors? @@ -347,7 +352,7 @@ class CI_Form_validation { // Now we need to re-set the POST data with the new, processed data $this->_reset_post_array(); - + // No errors, validation passes! if ($total_errors == 0) { @@ -359,7 +364,7 @@ class CI_Form_validation { } // -------------------------------------------------------------------- - + /** * Traverse a multidimensional $_POST array index until the data is found * @@ -368,7 +373,7 @@ class CI_Form_validation { * @param array * @param integer * @return mixed - */ + */ function _reduce_array($array, $keys, $i = 0) { if (is_array($array)) @@ -389,18 +394,18 @@ class CI_Form_validation { return $array; } } - + return $array; } // -------------------------------------------------------------------- - + /** * Re-populate the _POST array with our finalized and processed data * * @access private * @return null - */ + */ function _reset_post_array() { foreach ($this->_field_data as $field => $row) @@ -418,7 +423,7 @@ class CI_Form_validation { { // start with a reference $post_ref =& $_POST; - + // before we assign values, make a reference to the right POST key if (count($row['keys']) == 1) { @@ -452,7 +457,7 @@ class CI_Form_validation { } // -------------------------------------------------------------------- - + /** * Executes the Validation routines * @@ -462,21 +467,21 @@ class CI_Form_validation { * @param mixed * @param integer * @return mixed - */ + */ function _execute($row, $rules, $postdata = NULL, $cycles = 0) { // If the $_POST data is an array we will run a recursive call if (is_array($postdata)) - { + { foreach ($postdata as $key => $val) { $this->_execute($row, $rules, $val, $cycles); $cycles++; } - + return; } - + // -------------------------------------------------------------------- // If the field is blank, but NOT required, no further tests are necessary @@ -496,7 +501,7 @@ class CI_Form_validation { } // -------------------------------------------------------------------- - + // Isset Test. Typically this rule will only apply to checkboxes. if (is_null($postdata) AND $callback == FALSE) { @@ -504,31 +509,31 @@ class CI_Form_validation { { // Set the message type $type = (in_array('required', $rules)) ? 'required' : 'isset'; - + if ( ! isset($this->_error_messages[$type])) { if (FALSE === ($line = $this->CI->lang->line($type))) { $line = 'The field was not set'; - } + } } else { $line = $this->_error_messages[$type]; } - + // Build the error message $message = sprintf($line, $this->_translate_fieldname($row['label'])); // Save the error message $this->_field_data[$row['field']]['error'] = $message; - + if ( ! isset($this->_error_array[$row['field']])) { $this->_error_array[$row['field']] = $message; } } - + return; } @@ -538,7 +543,7 @@ class CI_Form_validation { foreach ($rules As $rule) { $_in_array = FALSE; - + // We set the $postdata variable with the current data in our master array so that // each cycle of the loop is dealing with the processed data from the last cycle if ($row['is_array'] == TRUE AND is_array($this->_field_data[$row['field']]['postdata'])) @@ -549,7 +554,7 @@ class CI_Form_validation { { continue; } - + $postdata = $this->_field_data[$row['field']]['postdata'][$cycles]; $_in_array = TRUE; } @@ -559,32 +564,32 @@ class CI_Form_validation { } // -------------------------------------------------------------------- - - // Is the rule a callback? + + // Is the rule a callback? $callback = FALSE; if (substr($rule, 0, 9) == 'callback_') { $rule = substr($rule, 9); $callback = TRUE; } - + // Strip the parameter (if exists) from the rule // Rules can contain a parameter: max_length[5] $param = FALSE; - if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match)) + if (preg_match("/(.*?)\[(.*)\]/", $rule, $match)) { $rule = $match[1]; $param = $match[2]; } - + // Call the function that corresponds to the rule if ($callback === TRUE) { if ( ! method_exists($this->CI, $rule)) - { + { continue; } - + // Run the function and grab the result $result = $this->CI->$rule($postdata, $param); @@ -597,7 +602,7 @@ class CI_Form_validation { { $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result; } - + // If the field isn't required and we just processed a callback we'll move on... if ( ! in_array('required', $rules, TRUE) AND $result !== FALSE) { @@ -605,15 +610,15 @@ class CI_Form_validation { } } else - { + { if ( ! method_exists($this, $rule)) { - // If our own wrapper function doesn't exist we see if a native PHP function does. + // If our own wrapper function doesn't exist we see if a native PHP function does. // Users can use any native PHP function call that has one param. if (function_exists($rule)) { $result = $rule($postdata); - + if ($_in_array == TRUE) { $this->_field_data[$row['field']]['postdata'][$cycles] = (is_bool($result)) ? $postdata : $result; @@ -623,7 +628,7 @@ class CI_Form_validation { $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result; } } - + continue; } @@ -638,54 +643,54 @@ class CI_Form_validation { $this->_field_data[$row['field']]['postdata'] = (is_bool($result)) ? $postdata : $result; } } - + // Did the rule test negatively? If so, grab the error. if ($result === FALSE) - { + { if ( ! isset($this->_error_messages[$rule])) { if (FALSE === ($line = $this->CI->lang->line($rule))) { $line = 'Unable to access an error message corresponding to your field name.'; - } + } } else { $line = $this->_error_messages[$rule]; } - + // Is the parameter we are inserting into the error message the name // of another field? If so we need to grab its "field label" if (isset($this->_field_data[$param]) AND isset($this->_field_data[$param]['label'])) { - $param = $this->_field_data[$param]['label']; + $param = $this->_translate_fieldname($this->_field_data[$param]['label']); } - + // Build the error message $message = sprintf($line, $this->_translate_fieldname($row['label']), $param); // Save the error message $this->_field_data[$row['field']]['error'] = $message; - + if ( ! isset($this->_error_array[$row['field']])) { $this->_error_array[$row['field']] = $message; } - + return; } } } // -------------------------------------------------------------------- - + /** * Translate a field name * * @access private * @param string the field name * @return string - */ + */ function _translate_fieldname($fieldname) { // Do we need to translate the field name? @@ -693,8 +698,8 @@ class CI_Form_validation { if (substr($fieldname, 0, 5) == 'lang:') { // Grab the variable - $line = substr($fieldname, 5); - + $line = substr($fieldname, 5); + // Were we able to translate the field name? If not we use $line if (FALSE === ($fieldname = $this->CI->lang->line($line))) { @@ -706,7 +711,7 @@ class CI_Form_validation { } // -------------------------------------------------------------------- - + /** * Get the value from a form * @@ -717,19 +722,26 @@ class CI_Form_validation { * @param string the field name * @param string * @return void - */ + */ function set_value($field = '', $default = '') { if ( ! isset($this->_field_data[$field])) { return $default; } - + + // If the data is an array output them one at a time. + // E.g: form_input('name[]', set_value('name[]'); + if (is_array($this->_field_data[$field]['postdata'])) + { + return array_shift($this->_field_data[$field]['postdata']); + } + return $this->_field_data[$field]['postdata']; } - + // -------------------------------------------------------------------- - + /** * Set Select * @@ -740,9 +752,9 @@ class CI_Form_validation { * @param string * @param string * @return string - */ + */ function set_select($field = '', $value = '', $default = FALSE) - { + { if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata'])) { if ($default === TRUE AND count($this->_field_data) === 0) @@ -751,9 +763,9 @@ class CI_Form_validation { } return ''; } - + $field = $this->_field_data[$field]['postdata']; - + if (is_array($field)) { if ( ! in_array($value, $field)) @@ -768,12 +780,12 @@ class CI_Form_validation { return ''; } } - + return ' selected="selected"'; } - + // -------------------------------------------------------------------- - + /** * Set Radio * @@ -784,7 +796,7 @@ class CI_Form_validation { * @param string * @param string * @return string - */ + */ function set_radio($field = '', $value = '', $default = FALSE) { if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata'])) @@ -795,9 +807,9 @@ class CI_Form_validation { } return ''; } - + $field = $this->_field_data[$field]['postdata']; - + if (is_array($field)) { if ( ! in_array($value, $field)) @@ -812,12 +824,12 @@ class CI_Form_validation { return ''; } } - + return ' checked="checked"'; } - + // -------------------------------------------------------------------- - + /** * Set Checkbox * @@ -828,7 +840,7 @@ class CI_Form_validation { * @param string * @param string * @return string - */ + */ function set_checkbox($field = '', $value = '', $default = FALSE) { if ( ! isset($this->_field_data[$field]) OR ! isset($this->_field_data[$field]['postdata'])) @@ -839,9 +851,9 @@ class CI_Form_validation { } return ''; } - + $field = $this->_field_data[$field]['postdata']; - + if (is_array($field)) { if ( ! in_array($value, $field)) @@ -856,12 +868,12 @@ class CI_Form_validation { return ''; } } - + return ' checked="checked"'; } - + // -------------------------------------------------------------------- - + /** * Required * @@ -880,9 +892,29 @@ class CI_Form_validation { return ( ! empty($str)); } } - + + // -------------------------------------------------------------------- + + /** + * Performs a Regular Expression match test. + * + * @access public + * @param string + * @param regex + * @return bool + */ + function regex_match($str, $regex) + { + if ( ! preg_match($regex, $str)) + { + return FALSE; + } + + return TRUE; + } + // -------------------------------------------------------------------- - + /** * Match one field to another * @@ -895,16 +927,16 @@ class CI_Form_validation { { if ( ! isset($_POST[$field])) { - return FALSE; + return FALSE; } - + $field = $_POST[$field]; return ($str !== $field) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Minimum Length * @@ -912,7 +944,7 @@ class CI_Form_validation { * @param string * @param value * @return bool - */ + */ function min_length($str, $val) { if (preg_match("/[^0-9]/", $val)) @@ -922,14 +954,14 @@ class CI_Form_validation { if (function_exists('mb_strlen')) { - return (mb_strlen($str) < $val) ? FALSE : TRUE; + return (mb_strlen($str) < $val) ? FALSE : TRUE; } - + return (strlen($str) < $val) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Max Length * @@ -937,7 +969,7 @@ class CI_Form_validation { * @param string * @param value * @return bool - */ + */ function max_length($str, $val) { if (preg_match("/[^0-9]/", $val)) @@ -947,14 +979,14 @@ class CI_Form_validation { if (function_exists('mb_strlen')) { - return (mb_strlen($str) > $val) ? FALSE : TRUE; + return (mb_strlen($str) > $val) ? FALSE : TRUE; } - + return (strlen($str) > $val) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Exact Length * @@ -962,7 +994,7 @@ class CI_Form_validation { * @param string * @param value * @return bool - */ + */ function exact_length($str, $val) { if (preg_match("/[^0-9]/", $val)) @@ -972,42 +1004,42 @@ class CI_Form_validation { if (function_exists('mb_strlen')) { - return (mb_strlen($str) != $val) ? FALSE : TRUE; + return (mb_strlen($str) != $val) ? FALSE : TRUE; } - + return (strlen($str) != $val) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Valid Email * * @access public * @param string * @return bool - */ + */ function valid_email($str) { return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE; } // -------------------------------------------------------------------- - + /** * Valid Emails * * @access public * @param string * @return bool - */ + */ function valid_emails($str) { if (strpos($str, ',') === FALSE) { return $this->valid_email(trim($str)); } - + foreach(explode(',', $str) as $email) { if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE) @@ -1015,12 +1047,12 @@ class CI_Form_validation { return FALSE; } } - + return TRUE; } // -------------------------------------------------------------------- - + /** * Validate IP Address * @@ -1034,56 +1066,56 @@ class CI_Form_validation { } // -------------------------------------------------------------------- - + /** * Alpha * * @access public * @param string * @return bool - */ + */ function alpha($str) { return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Alpha-numeric * * @access public * @param string * @return bool - */ + */ function alpha_numeric($str) { return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Alpha-numeric with underscores and dashes * * @access public * @param string * @return bool - */ + */ function alpha_dash($str) { return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Numeric * * @access public * @param string * @return bool - */ + */ function numeric($str) { return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str); @@ -1092,72 +1124,72 @@ class CI_Form_validation { // -------------------------------------------------------------------- - /** - * Is Numeric - * - * @access public - * @param string - * @return bool - */ - function is_numeric($str) - { - return ( ! is_numeric($str)) ? FALSE : TRUE; - } + /** + * Is Numeric + * + * @access public + * @param string + * @return bool + */ + function is_numeric($str) + { + return ( ! is_numeric($str)) ? FALSE : TRUE; + } // -------------------------------------------------------------------- - + /** * Integer * * @access public * @param string * @return bool - */ + */ function integer($str) { return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str); } - + // -------------------------------------------------------------------- - /** - * Is a Natural number (0,1,2,3, etc.) - * - * @access public - * @param string - * @return bool - */ - function is_natural($str) - { - return (bool)preg_match( '/^[0-9]+$/', $str); - } + /** + * Is a Natural number (0,1,2,3, etc.) + * + * @access public + * @param string + * @return bool + */ + function is_natural($str) + { + return (bool)preg_match( '/^[0-9]+$/', $str); + } // -------------------------------------------------------------------- - /** - * Is a Natural number, but not a zero (1,2,3, etc.) - * - * @access public - * @param string - * @return bool - */ + /** + * Is a Natural number, but not a zero (1,2,3, etc.) + * + * @access public + * @param string + * @return bool + */ function is_natural_no_zero($str) - { - if ( ! preg_match( '/^[0-9]+$/', $str)) - { - return FALSE; - } - - if ($str == 0) - { - return FALSE; - } - - return TRUE; - } - + { + if ( ! preg_match( '/^[0-9]+$/', $str)) + { + return FALSE; + } + + if ($str == 0) + { + return FALSE; + } + + return TRUE; + } + // -------------------------------------------------------------------- - + /** * Valid Base64 * @@ -1172,9 +1204,9 @@ class CI_Form_validation { { return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str); } - + // -------------------------------------------------------------------- - + /** * Prep data for form * @@ -1193,10 +1225,10 @@ class CI_Form_validation { { $data[$key] = $this->prep_for_form($val); } - + return $data; } - + if ($this->_safe_form_data == FALSE OR $data === '') { return $data; @@ -1204,68 +1236,73 @@ class CI_Form_validation { return str_replace(array("'", '"', '<', '>'), array("'", """, '<', '>'), stripslashes($data)); } - + // -------------------------------------------------------------------- - + /** * Prep URL * * @access public * @param string * @return string - */ + */ function prep_url($str = '') { if ($str == 'http://' OR $str == '') { return ''; } - + if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://') { $str = 'http://'.$str; } - + return $str; } - + // -------------------------------------------------------------------- - + /** * Strip Image Tags * * @access public * @param string * @return string - */ + */ function strip_image_tags($str) { return $this->CI->input->strip_image_tags($str); } - + // -------------------------------------------------------------------- - + /** * XSS Clean * * @access public * @param string * @return string - */ + */ function xss_clean($str) { - return $this->CI->input->xss_clean($str); + if ( ! isset($this->CI->security)) + { + $this->CI->load->library('security'); + } + + return $this->CI->security->xss_clean($str); } - + // -------------------------------------------------------------------- - + /** * Convert PHP tags to entities * * @access public * @param string * @return string - */ + */ function encode_php_tags($str) { return str_replace(array('<?php', '<?PHP', '<?', '?>'), array('<?php', '<?PHP', '<?', '?>'), $str); diff --git a/system/libraries/Ftp.php b/system/libraries/Ftp.php index 16ad9ad43..d7a8b3b02 100644..100755 --- a/system/libraries/Ftp.php +++ b/system/libraries/Ftp.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -40,7 +40,7 @@ class CI_FTP { * * The constructor can be passed an array of config values */ - function CI_FTP($config = array()) + public function __construct($config = array()) { if (count($config) > 0) { @@ -281,6 +281,48 @@ class CI_FTP { // -------------------------------------------------------------------- /** + * Download a file from a remote server to the local server + * + * @access public + * @param string + * @param string + * @param string + * @return bool + */ + function download($rempath, $locpath, $mode = 'auto') + { + if ( ! $this->_is_conn()) + { + return FALSE; + } + + // Set the mode if not specified + if ($mode == 'auto') + { + // Get the file extension so we can set the upload type + $ext = $this->_getext($rempath); + $mode = $this->_settype($ext); + } + + $mode = ($mode == 'ascii') ? FTP_ASCII : FTP_BINARY; + + $result = @ftp_get($this->conn_id, $locpath, $rempath, $mode); + + if ($result === FALSE) + { + if ($this->debug == TRUE) + { + $this->_error('ftp_unable_to_download'); + } + return FALSE; + } + + return TRUE; + } + + // -------------------------------------------------------------------- + + /** * Rename (or move) a file * * @access public @@ -412,7 +454,7 @@ class CI_FTP { * Set file permissions * * @access public - * @param string the file path + * @param string the file path * @param string the permissions * @return bool */ diff --git a/system/libraries/Hooks.php b/system/libraries/Hooks.php deleted file mode 100644 index 6d736c3f6..000000000 --- a/system/libraries/Hooks.php +++ /dev/null @@ -1,226 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * CodeIgniter Hooks Class - * - * Provides a mechanism to extend the base system without hacking. Most of - * this class is borrowed from Paul's Extension class in ExpressionEngine. - * - * @package CodeIgniter - * @subpackage Libraries - * @category Libraries - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/encryption.html - */ -class CI_Hooks { - - var $enabled = FALSE; - var $hooks = array(); - var $in_progress = FALSE; - - /** - * Constructor - * - */ - function CI_Hooks() - { - $this->_initialize(); - log_message('debug', "Hooks Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Initialize the Hooks Preferences - * - * @access private - * @return void - */ - function _initialize() - { - $CFG =& load_class('Config'); - - // If hooks are not enabled in the config file - // there is nothing else to do - - if ($CFG->item('enable_hooks') == FALSE) - { - return; - } - - // Grab the "hooks" definition file. - // If there are no hooks, we're done. - - @include(APPPATH.'config/hooks'.EXT); - - if ( ! isset($hook) OR ! is_array($hook)) - { - return; - } - - $this->hooks =& $hook; - $this->enabled = TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Call Hook - * - * Calls a particular hook - * - * @access private - * @param string the hook name - * @return mixed - */ - function _call_hook($which = '') - { - if ( ! $this->enabled OR ! isset($this->hooks[$which])) - { - return FALSE; - } - - if (isset($this->hooks[$which][0]) AND is_array($this->hooks[$which][0])) - { - foreach ($this->hooks[$which] as $val) - { - $this->_run_hook($val); - } - } - else - { - $this->_run_hook($this->hooks[$which]); - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Run Hook - * - * Runs a particular hook - * - * @access private - * @param array the hook details - * @return bool - */ - function _run_hook($data) - { - if ( ! is_array($data)) - { - return FALSE; - } - - // ----------------------------------- - // Safety - Prevents run-away loops - // ----------------------------------- - - // If the script being called happens to have the same - // hook call within it a loop can happen - - if ($this->in_progress == TRUE) - { - return; - } - - // ----------------------------------- - // Set file path - // ----------------------------------- - - if ( ! isset($data['filepath']) OR ! isset($data['filename'])) - { - return FALSE; - } - - $filepath = APPPATH.$data['filepath'].'/'.$data['filename']; - - if ( ! file_exists($filepath)) - { - return FALSE; - } - - // ----------------------------------- - // Set class/function name - // ----------------------------------- - - $class = FALSE; - $function = FALSE; - $params = ''; - - if (isset($data['class']) AND $data['class'] != '') - { - $class = $data['class']; - } - - if (isset($data['function'])) - { - $function = $data['function']; - } - - if (isset($data['params'])) - { - $params = $data['params']; - } - - if ($class === FALSE AND $function === FALSE) - { - return FALSE; - } - - // ----------------------------------- - // Set the in_progress flag - // ----------------------------------- - - $this->in_progress = TRUE; - - // ----------------------------------- - // Call the requested class and/or function - // ----------------------------------- - - if ($class !== FALSE) - { - if ( ! class_exists($class)) - { - require($filepath); - } - - $HOOK = new $class; - $HOOK->$function($params); - } - else - { - if ( ! function_exists($function)) - { - require($filepath); - } - - $function($params); - } - - $this->in_progress = FALSE; - return TRUE; - } - -} - -// END CI_Hooks class - -/* End of file Hooks.php */ -/* Location: ./system/libraries/Hooks.php */
\ No newline at end of file diff --git a/system/libraries/Image_lib.php b/system/libraries/Image_lib.php index 0b29c1fbd..41f9ad393 100644..100755 --- a/system/libraries/Image_lib.php +++ b/system/libraries/Image_lib.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -26,7 +26,7 @@ */ class CI_Image_lib { - var $image_library = 'gd2'; // Can be: imagemagick, netpbm, gd, gd2 + var $image_library = 'gd2'; // Can be: imagemagick, netpbm, gd, gd2 var $library_path = ''; var $dynamic_output = FALSE; // Whether to send to browser or write to disk var $source_image = ''; @@ -36,7 +36,7 @@ class CI_Image_lib { var $quality = '90'; var $create_thumb = FALSE; var $thumb_marker = '_thumb'; - var $maintain_ratio = TRUE; // Whether to maintain aspect ratio when resizing or use hard values + var $maintain_ratio = TRUE; // Whether to maintain aspect ratio when resizing or use hard values var $master_dim = 'auto'; // auto, height, or width. Determines what to use as the master dimension var $rotation_angle = ''; var $x_axis = ''; @@ -54,11 +54,11 @@ class CI_Image_lib { var $wm_hor_alignment = 'C'; // Horizontal alignment: L R C var $wm_padding = 0; // Padding around text var $wm_hor_offset = 0; // Lets you push text to the right - var $wm_vrt_offset = 0; // Lets you push text down + var $wm_vrt_offset = 0; // Lets you push text down var $wm_font_color = '#ffffff'; // Text color var $wm_shadow_color = ''; // Dropshadow color var $wm_shadow_distance = 2; // Dropshadow distance - var $wm_opacity = 50; // Image opacity: 1 - 100 Only works with image + var $wm_opacity = 50; // Image opacity: 1 - 100 Only works with image // Private Vars var $source_folder = ''; @@ -79,11 +79,10 @@ class CI_Image_lib { /** * Constructor * - * @access public * @param string * @return void */ - function CI_Image_lib($props = array()) + public function __construct($props = array()) { if (count($props) > 0) { @@ -147,7 +146,7 @@ class CI_Image_lib { if ($this->source_image == '') { $this->set_error('imglib_source_image_required'); - return FALSE; + return FALSE; } /* @@ -190,7 +189,7 @@ class CI_Image_lib { // Set the Image Properties if ( ! $this->get_image_properties($this->source_folder.$this->source_image)) { - return FALSE; + return FALSE; } /* @@ -400,7 +399,7 @@ class CI_Image_lib { if ($this->rotation_angle == '' OR ! in_array($this->rotation_angle, $degs)) { $this->set_error('imglib_rotation_angle_required'); - return FALSE; + return FALSE; } // Reassign the width and height @@ -455,11 +454,11 @@ class CI_Image_lib { { if ($this->orig_width == $this->width AND $this->orig_height == $this->height) { - if ($this->source_image != $this->new_image) - { + if ($this->source_image != $this->new_image) + { if (@copy($this->full_src_path, $this->full_dst_path)) { - @chmod($this->full_dst_path, DIR_WRITE_MODE); + @chmod($this->full_dst_path, FILE_WRITE_MODE); } } @@ -494,14 +493,14 @@ class CI_Image_lib { return FALSE; } - // Create The Image + // Create The Image // // old conditional which users report cause problems with shared GD libs who report themselves as "2.0 or greater" // it appears that this is no longer the issue that it was in 2004, so we've removed it, retaining it in the comment // below should that ever prove inaccurate. // // if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor') AND $v2_override == FALSE) - if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor')) + if ($this->image_library == 'gd2' AND function_exists('imagecreatetruecolor')) { $create = 'imagecreatetruecolor'; $copy = 'imagecopyresampled'; @@ -513,6 +512,13 @@ class CI_Image_lib { } $dst_img = $create($this->width, $this->height); + + if ($this->image_type == 3) // png we can actually preserve transparency + { + imagealphablending($dst_img, FALSE); + imagesavealpha($dst_img, TRUE); + } + $copy($dst_img, $src_img, 0, 0, $this->x_axis, $this->y_axis, $this->width, $this->height, $this->orig_width, $this->orig_height); // Show the image @@ -534,7 +540,7 @@ class CI_Image_lib { imagedestroy($src_img); // Set the file to 777 - @chmod($this->full_dst_path, DIR_WRITE_MODE); + @chmod($this->full_dst_path, FILE_WRITE_MODE); return TRUE; } @@ -577,9 +583,9 @@ class CI_Image_lib { { switch ($this->rotation_angle) { - case 'hor' : $angle = '-flop'; + case 'hor' : $angle = '-flop'; break; - case 'vrt' : $angle = '-flip'; + case 'vrt' : $angle = '-flip'; break; default : $angle = '-rotate '.$this->rotation_angle; break; @@ -604,7 +610,7 @@ class CI_Image_lib { } // Set the file to 777 - @chmod($this->full_dst_path, DIR_WRITE_MODE); + @chmod($this->full_dst_path, FILE_WRITE_MODE); return TRUE; } @@ -657,7 +663,7 @@ class CI_Image_lib { break; case 180 : $angle = 'r180'; break; - case 270 : $angle = 'r90'; + case 270 : $angle = 'r90'; break; case 'vrt' : $angle = 'tb'; break; @@ -690,7 +696,7 @@ class CI_Image_lib { // we have to rename the temp file. copy ($this->dest_folder.'netpbm.tmp', $this->full_dst_path); unlink ($this->dest_folder.'netpbm.tmp'); - @chmod($this->full_dst_path, DIR_WRITE_MODE); + @chmod($this->full_dst_path, FILE_WRITE_MODE); return TRUE; } @@ -705,14 +711,6 @@ class CI_Image_lib { */ function image_rotate_gd() { - // Is Image Rotation Supported? - // this function is only supported as of PHP 4.3 - if ( ! function_exists('imagerotate')) - { - $this->set_error('imglib_rotate_unsupported'); - return FALSE; - } - // Create the image handle if ( ! ($src_img = $this->image_create_gd())) { @@ -749,7 +747,7 @@ class CI_Image_lib { // Set the file to 777 - @chmod($this->full_dst_path, DIR_WRITE_MODE); + @chmod($this->full_dst_path, FILE_WRITE_MODE); return true; } @@ -833,7 +831,7 @@ class CI_Image_lib { imagedestroy($src_img); // Set the file to 777 - @chmod($this->full_dst_path, DIR_WRITE_MODE); + @chmod($this->full_dst_path, FILE_WRITE_MODE); return TRUE; } @@ -882,7 +880,7 @@ class CI_Image_lib { $this->get_image_properties(); // Fetch watermark image properties - $props = $this->get_image_properties($this->wm_overlay_path, TRUE); + $props = $this->get_image_properties($this->wm_overlay_path, TRUE); $wm_img_type = $props['image_type']; $wm_width = $props['width']; $wm_height = $props['height']; @@ -937,7 +935,7 @@ class CI_Image_lib { if ($wm_img_type == 3 AND function_exists('imagealphablending')) { @imagealphablending($src_img, TRUE); - } + } // Set RGB values for text and shadow $rgba = imagecolorat($wm_img, $this->wm_x_transp, $this->wm_y_transp); @@ -1208,11 +1206,6 @@ class CI_Image_lib { return FALSE; } - if (phpversion() == '4.4.1') - { - @touch($this->full_dst_path); // PHP 4.4.1 bug #35060 - workaround - } - if ( ! @imagejpeg($resource, $this->full_dst_path, $this->quality)) { $this->set_error('imglib_save_failed'); @@ -1259,7 +1252,7 @@ class CI_Image_lib { switch ($this->image_type) { - case 1 : imagegif($resource); + case 1 : imagegif($resource); break; case 2 : imagejpeg($resource, '', $this->quality); break; @@ -1377,8 +1370,8 @@ class CI_Image_lib { * new variable needs to be known * * $props = array( - * 'width' => $width, - * 'height' => $height, + * 'width' => $width, + * 'height' => $height, * 'new_width' => 40, * 'new_height' => '' * ); @@ -1439,7 +1432,7 @@ class CI_Image_lib { { $ext = strrchr($source_image, '.'); $name = ($ext === FALSE) ? $source_image : substr($source_image, 0, -strlen($ext)); - + return array('ext' => $ext, 'name' => $name); } diff --git a/system/libraries/Input.php b/system/libraries/Input.php deleted file mode 100644 index 396815194..000000000 --- a/system/libraries/Input.php +++ /dev/null @@ -1,1067 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * Input Class - * - * Pre-processes global input data for security - * - * @package CodeIgniter - * @subpackage Libraries - * @category Input - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/input.html - */ -class CI_Input { - var $use_xss_clean = FALSE; - var $xss_hash = ''; - var $ip_address = FALSE; - var $user_agent = FALSE; - var $allow_get_array = FALSE; - - /* never allowed, string replacement */ - var $never_allowed_str = array( - 'document.cookie' => '[removed]', - 'document.write' => '[removed]', - '.parentNode' => '[removed]', - '.innerHTML' => '[removed]', - 'window.location' => '[removed]', - '-moz-binding' => '[removed]', - '<!--' => '<!--', - '-->' => '-->', - '<![CDATA[' => '<![CDATA[' - ); - /* never allowed, regex replacement */ - var $never_allowed_regex = array( - "javascript\s*:" => '[removed]', - "expression\s*(\(|&\#40;)" => '[removed]', // CSS and IE - "vbscript\s*:" => '[removed]', // IE, surprise! - "Redirect\s+302" => '[removed]' - ); - - /** - * Constructor - * - * Sets whether to globally enable the XSS processing - * and whether to allow the $_GET array - * - * @access public - */ - function CI_Input() - { - log_message('debug', "Input Class Initialized"); - - $CFG =& load_class('Config'); - $this->use_xss_clean = ($CFG->item('global_xss_filtering') === TRUE) ? TRUE : FALSE; - $this->allow_get_array = ($CFG->item('enable_query_strings') === TRUE) ? TRUE : FALSE; - $this->_sanitize_globals(); - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Globals - * - * This function does the following: - * - * Unsets $_GET data (if query strings are not enabled) - * - * Unsets all globals if register_globals is enabled - * - * Standardizes newline characters to \n - * - * @access private - * @return void - */ - function _sanitize_globals() - { - // Would kind of be "wrong" to unset any of these GLOBALS - $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST', '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA', - 'system_folder', 'application_folder', 'BM', 'EXT', 'CFG', 'URI', 'RTR', 'OUT', 'IN'); - - // Unset globals for security. - // This is effectively the same as register_globals = off - foreach (array($_GET, $_POST, $_COOKIE, $_SERVER, $_FILES, $_ENV, (isset($_SESSION) && is_array($_SESSION)) ? $_SESSION : array()) as $global) - { - if ( ! is_array($global)) - { - if ( ! in_array($global, $protected)) - { - unset($GLOBALS[$global]); - } - } - else - { - foreach ($global as $key => $val) - { - if ( ! in_array($key, $protected)) - { - unset($GLOBALS[$key]); - } - - if (is_array($val)) - { - foreach($val as $k => $v) - { - if ( ! in_array($k, $protected)) - { - unset($GLOBALS[$k]); - } - } - } - } - } - } - - // Is $_GET data allowed? If not we'll set the $_GET to an empty array - if ($this->allow_get_array == FALSE) - { - $_GET = array(); - } - else - { - $_GET = $this->_clean_input_data($_GET); - } - - // Clean $_POST Data - $_POST = $this->_clean_input_data($_POST); - - // Clean $_COOKIE Data - // Also get rid of specially treated cookies that might be set by a server - // or silly application, that are of no use to a CI application anyway - // but that when present will trip our 'Disallowed Key Characters' alarm - // http://www.ietf.org/rfc/rfc2109.txt - // note that the key names below are single quoted strings, and are not PHP variables - unset($_COOKIE['$Version']); - unset($_COOKIE['$Path']); - unset($_COOKIE['$Domain']); - $_COOKIE = $this->_clean_input_data($_COOKIE); - - log_message('debug', "Global POST and COOKIE data sanitized"); - } - - // -------------------------------------------------------------------- - - /** - * Clean Input Data - * - * This is a helper function. It escapes data and - * standardizes newline characters to \n - * - * @access private - * @param string - * @return string - */ - function _clean_input_data($str) - { - if (is_array($str)) - { - $new_array = array(); - foreach ($str as $key => $val) - { - $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val); - } - return $new_array; - } - - // We strip slashes if magic quotes is on to keep things consistent - if (get_magic_quotes_gpc()) - { - $str = stripslashes($str); - } - - // Should we filter the input data? - if ($this->use_xss_clean === TRUE) - { - $str = $this->xss_clean($str); - } - - // Standardize newlines - if (strpos($str, "\r") !== FALSE) - { - $str = str_replace(array("\r\n", "\r"), "\n", $str); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Clean Keys - * - * This is a helper function. To prevent malicious users - * from trying to exploit keys we make sure that keys are - * only named with alpha-numeric text and a few other items. - * - * @access private - * @param string - * @return string - */ - function _clean_input_keys($str) - { - if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str)) - { - exit('Disallowed Key Characters.'); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Fetch from array - * - * This is a helper function to retrieve values from global arrays - * - * @access private - * @param array - * @param string - * @param bool - * @return string - */ - function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE) - { - if ( ! isset($array[$index])) - { - return FALSE; - } - - if ($xss_clean === TRUE) - { - return $this->xss_clean($array[$index]); - } - - return $array[$index]; - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the GET array - * - * @access public - * @param string - * @param bool - * @return string - */ - function get($index = '', $xss_clean = FALSE) - { - return $this->_fetch_from_array($_GET, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the POST array - * - * @access public - * @param string - * @param bool - * @return string - */ - function post($index = '', $xss_clean = FALSE) - { - return $this->_fetch_from_array($_POST, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from either the GET array or the POST - * - * @access public - * @param string The index key - * @param bool XSS cleaning - * @return string - */ - function get_post($index = '', $xss_clean = FALSE) - { - if ( ! isset($_POST[$index]) ) - { - return $this->get($index, $xss_clean); - } - else - { - return $this->post($index, $xss_clean); - } - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the COOKIE array - * - * @access public - * @param string - * @param bool - * @return string - */ - function cookie($index = '', $xss_clean = FALSE) - { - return $this->_fetch_from_array($_COOKIE, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch an item from the SERVER array - * - * @access public - * @param string - * @param bool - * @return string - */ - function server($index = '', $xss_clean = FALSE) - { - return $this->_fetch_from_array($_SERVER, $index, $xss_clean); - } - - // -------------------------------------------------------------------- - - /** - * Fetch the IP Address - * - * @access public - * @return string - */ - function ip_address() - { - if ($this->ip_address !== FALSE) - { - return $this->ip_address; - } - - if (config_item('proxy_ips') != '' && $this->server('HTTP_X_FORWARDED_FOR') && $this->server('REMOTE_ADDR')) - { - $proxies = preg_split('/[\s,]/', config_item('proxy_ips'), -1, PREG_SPLIT_NO_EMPTY); - $proxies = is_array($proxies) ? $proxies : array($proxies); - - $this->ip_address = in_array($_SERVER['REMOTE_ADDR'], $proxies) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']; - } - elseif ($this->server('REMOTE_ADDR') AND $this->server('HTTP_CLIENT_IP')) - { - $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; - } - elseif ($this->server('REMOTE_ADDR')) - { - $this->ip_address = $_SERVER['REMOTE_ADDR']; - } - elseif ($this->server('HTTP_CLIENT_IP')) - { - $this->ip_address = $_SERVER['HTTP_CLIENT_IP']; - } - elseif ($this->server('HTTP_X_FORWARDED_FOR')) - { - $this->ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; - } - - if ($this->ip_address === FALSE) - { - $this->ip_address = '0.0.0.0'; - return $this->ip_address; - } - - if (strstr($this->ip_address, ',')) - { - $x = explode(',', $this->ip_address); - $this->ip_address = trim(end($x)); - } - - if ( ! $this->valid_ip($this->ip_address)) - { - $this->ip_address = '0.0.0.0'; - } - - return $this->ip_address; - } - - // -------------------------------------------------------------------- - - /** - * Validate IP Address - * - * Updated version suggested by Geert De Deckere - * - * @access public - * @param string - * @return string - */ - function valid_ip($ip) - { - $ip_segments = explode('.', $ip); - - // Always 4 segments needed - if (count($ip_segments) != 4) - { - return FALSE; - } - // IP can not start with 0 - if ($ip_segments[0][0] == '0') - { - return FALSE; - } - // Check each segment - foreach ($ip_segments as $segment) - { - // IP segments must be digits and can not be - // longer than 3 digits or greater then 255 - if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3) - { - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * User Agent - * - * @access public - * @return string - */ - function user_agent() - { - if ($this->user_agent !== FALSE) - { - return $this->user_agent; - } - - $this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT']; - - return $this->user_agent; - } - - // -------------------------------------------------------------------- - - /** - * Filename Security - * - * @access public - * @param string - * @return string - */ - function filename_security($str) - { - $bad = array( - "../", - "./", - "<!--", - "-->", - "<", - ">", - "'", - '"', - '&', - '$', - '#', - '{', - '}', - '[', - ']', - '=', - ';', - '?', - "%20", - "%22", - "%3c", // < - "%253c", // < - "%3e", // > - "%0e", // > - "%28", // ( - "%29", // ) - "%2528", // ( - "%26", // & - "%24", // $ - "%3f", // ? - "%3b", // ; - "%3d" // = - ); - - return stripslashes(str_replace($bad, '', $str)); - } - - // -------------------------------------------------------------------- - - /** - * XSS Clean - * - * Sanitizes data so that Cross Site Scripting Hacks can be - * prevented. This function does a fair amount of work but - * it is extremely thorough, designed to prevent even the - * most obscure XSS attempts. Nothing is ever 100% foolproof, - * of course, but I haven't been able to get anything passed - * the filter. - * - * Note: This function should only be used to deal with data - * upon submission. It's not something that should - * be used for general runtime processing. - * - * This function was based in part on some code and ideas I - * got from Bitflux: http://blog.bitflux.ch/wiki/XSS_Prevention - * - * To help develop this script I used this great list of - * vulnerabilities along with a few other hacks I've - * harvested from examining vulnerabilities in other programs: - * http://ha.ckers.org/xss.html - * - * @access public - * @param string - * @return string - */ - function xss_clean($str, $is_image = FALSE) - { - /* - * Is the string an array? - * - */ - if (is_array($str)) - { - while (list($key) = each($str)) - { - $str[$key] = $this->xss_clean($str[$key]); - } - - return $str; - } - - /* - * Remove Invisible Characters - */ - $str = $this->_remove_invisible_characters($str); - - /* - * Protect GET variables in URLs - */ - - // 901119URL5918AMP18930PROTECT8198 - - $str = preg_replace('|\&([a-z\_0-9]+)\=([a-z\_0-9]+)|i', $this->xss_hash()."\\1=\\2", $str); - - /* - * Validate standard character entities - * - * Add a semicolon if missing. We do this to enable - * the conversion of entities to ASCII later. - * - */ - $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str); - - /* - * Validate UTF16 two byte encoding (x00) - * - * Just as above, adds a semicolon if missing. - * - */ - $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str); - - /* - * Un-Protect GET variables in URLs - */ - $str = str_replace($this->xss_hash(), '&', $str); - - /* - * URL Decode - * - * Just in case stuff like this is submitted: - * - * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a> - * - * Note: Use rawurldecode() so it does not remove plus signs - * - */ - $str = rawurldecode($str); - - /* - * Convert character entities to ASCII - * - * This permits our tests below to work reliably. - * We only convert entities that are within tags since - * these are the ones that will pose security problems. - * - */ - - $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str); - - $str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_html_entity_decode_callback'), $str); - - /* - * Remove Invisible Characters Again! - */ - $str = $this->_remove_invisible_characters($str); - - /* - * Convert all tabs to spaces - * - * This prevents strings like this: ja vascript - * NOTE: we deal with spaces between characters later. - * NOTE: preg_replace was found to be amazingly slow here on large blocks of data, - * so we use str_replace. - * - */ - - if (strpos($str, "\t") !== FALSE) - { - $str = str_replace("\t", ' ', $str); - } - - /* - * Capture converted string for later comparison - */ - $converted_string = $str; - - /* - * Not Allowed Under Any Conditions - */ - - foreach ($this->never_allowed_str as $key => $val) - { - $str = str_replace($key, $val, $str); - } - - foreach ($this->never_allowed_regex as $key => $val) - { - $str = preg_replace("#".$key."#i", $val, $str); - } - - /* - * Makes PHP tags safe - * - * Note: XML tags are inadvertently replaced too: - * - * <?xml - * - * But it doesn't seem to pose a problem. - * - */ - if ($is_image === TRUE) - { - // Images have a tendency to have the PHP short opening and closing tags every so often - // so we skip those and only do the long opening tags. - $str = preg_replace('/<\?(php)/i', "<?\\1", $str); - } - else - { - $str = str_replace(array('<?', '?'.'>'), array('<?', '?>'), $str); - } - - /* - * Compact any exploded words - * - * This corrects words like: j a v a s c r i p t - * These words are compacted back to their correct state. - * - */ - $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window'); - foreach ($words as $word) - { - $temp = ''; - - for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++) - { - $temp .= substr($word, $i, 1)."\s*"; - } - - // We only want to do this when it is followed by a non-word character - // That way valid stuff like "dealer to" does not become "dealerto" - $str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str); - } - - /* - * Remove disallowed Javascript in links or img tags - * We used to do some version comparisons and use of stripos for PHP5, but it is dog slow compared - * to these simplified non-capturing preg_match(), especially if the pattern exists in the string - */ - do - { - $original = $str; - - if (preg_match("/<a/i", $str)) - { - $str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str); - } - - if (preg_match("/<img/i", $str)) - { - $str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str); - } - - if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str)) - { - $str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str); - } - } - while($original != $str); - - unset($original); - - /* - * Remove JavaScript Event Handlers - * - * Note: This code is a little blunt. It removes - * the event handler and anything up to the closing >, - * but it's unlikely to be a problem. - * - */ - $event_handlers = array('[^a-z_\-]on\w*','xmlns'); - - if ($is_image === TRUE) - { - /* - * Adobe Photoshop puts XML metadata into JFIF images, including namespacing, - * so we have to allow this for images. -Paul - */ - unset($event_handlers[array_search('xmlns', $event_handlers)]); - } - - $str = preg_replace("#<([^><]+?)(".implode('|', $event_handlers).")(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str); - - /* - * Sanitize naughty HTML elements - * - * If a tag containing any of the words in the list - * below is found, the tag gets converted to entities. - * - * So this: <blink> - * Becomes: <blink> - * - */ - $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss'; - $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str); - - /* - * Sanitize naughty scripting elements - * - * Similar to above, only instead of looking for - * tags it looks for PHP and JavaScript commands - * that are disallowed. Rather than removing the - * code, it simply converts the parenthesis to entities - * rendering the code un-executable. - * - * For example: eval('some code') - * Becomes: eval('some code') - * - */ - $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str); - - /* - * Final clean up - * - * This adds a bit of extra precaution in case - * something got through the above filters - * - */ - foreach ($this->never_allowed_str as $key => $val) - { - $str = str_replace($key, $val, $str); - } - - foreach ($this->never_allowed_regex as $key => $val) - { - $str = preg_replace("#".$key."#i", $val, $str); - } - - /* - * Images are Handled in a Special Way - * - Essentially, we want to know that after all of the character conversion is done whether - * any unwanted, likely XSS, code was found. If not, we return TRUE, as the image is clean. - * However, if the string post-conversion does not matched the string post-removal of XSS, - * then it fails, as there was unwanted XSS code found and removed/changed during processing. - */ - - if ($is_image === TRUE) - { - if ($str == $converted_string) - { - return TRUE; - } - else - { - return FALSE; - } - } - - log_message('debug', "XSS Filtering completed"); - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Random Hash for protecting URLs - * - * @access public - * @return string - */ - function xss_hash() - { - if ($this->xss_hash == '') - { - if (phpversion() >= 4.2) - mt_srand(); - else - mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff); - - $this->xss_hash = md5(time() + mt_rand(0, 1999999999)); - } - - return $this->xss_hash; - } - - // -------------------------------------------------------------------- - - /** - * Remove Invisible Characters - * - * This prevents sandwiching null characters - * between ascii characters, like Java\0script. - * - * @access public - * @param string - * @return string - */ - function _remove_invisible_characters($str) - { - static $non_displayables; - - if ( ! isset($non_displayables)) - { - // every control character except newline (dec 10), carriage return (dec 13), and horizontal tab (dec 09), - $non_displayables = array( - '/%0[0-8bcef]/', // url encoded 00-08, 11, 12, 14, 15 - '/%1[0-9a-f]/', // url encoded 16-31 - '/[\x00-\x08]/', // 00-08 - '/\x0b/', '/\x0c/', // 11, 12 - '/[\x0e-\x1f]/' // 14-31 - ); - } - - do - { - $cleaned = $str; - $str = preg_replace($non_displayables, '', $str); - } - while ($cleaned != $str); - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Compact Exploded Words - * - * Callback function for xss_clean() to remove whitespace from - * things like j a v a s c r i p t - * - * @access public - * @param type - * @return type - */ - function _compact_exploded_words($matches) - { - return preg_replace('/\s+/s', '', $matches[1]).$matches[2]; - } - - // -------------------------------------------------------------------- - - /** - * Sanitize Naughty HTML - * - * Callback function for xss_clean() to remove naughty HTML elements - * - * @access private - * @param array - * @return string - */ - function _sanitize_naughty_html($matches) - { - // encode opening brace - $str = '<'.$matches[1].$matches[2].$matches[3]; - - // encode captured opening or closing brace to prevent recursive vectors - $str .= str_replace(array('>', '<'), array('>', '<'), $matches[4]); - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * JS Link Removal - * - * Callback function for xss_clean() to sanitize links - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on link-heavy strings - * - * @access private - * @param array - * @return string - */ - function _js_link_removal($match) - { - $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); - return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]); - } - - /** - * JS Image Removal - * - * Callback function for xss_clean() to sanitize image tags - * This limits the PCRE backtracks, making it more performance friendly - * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in - * PHP 5.2+ on image tag heavy strings - * - * @access private - * @param array - * @return string - */ - function _js_img_removal($match) - { - $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); - return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]); - } - - // -------------------------------------------------------------------- - - /** - * Attribute Conversion - * - * Used as a callback for XSS Clean - * - * @access public - * @param array - * @return string - */ - function _convert_attribute($match) - { - return str_replace(array('>', '<', '\\'), array('>', '<', '\\\\'), $match[0]); - } - - // -------------------------------------------------------------------- - - /** - * HTML Entity Decode Callback - * - * Used as a callback for XSS Clean - * - * @access public - * @param array - * @return string - */ - function _html_entity_decode_callback($match) - { - $CFG =& load_class('Config'); - $charset = $CFG->item('charset'); - - return $this->_html_entity_decode($match[0], strtoupper($charset)); - } - - // -------------------------------------------------------------------- - - /** - * HTML Entities Decode - * - * This function is a replacement for html_entity_decode() - * - * In some versions of PHP the native function does not work - * when UTF-8 is the specified character set, so this gives us - * a work-around. More info here: - * http://bugs.php.net/bug.php?id=25670 - * - * @access private - * @param string - * @param string - * @return string - */ - /* ------------------------------------------------- - /* Replacement for html_entity_decode() - /* -------------------------------------------------*/ - - /* - NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the - character set, and the PHP developers said they were not back porting the - fix to versions other than PHP 5.x. - */ - function _html_entity_decode($str, $charset='UTF-8') - { - if (stristr($str, '&') === FALSE) return $str; - - // The reason we are not using html_entity_decode() by itself is because - // while it is not technically correct to leave out the semicolon - // at the end of an entity most browsers will still interpret the entity - // correctly. html_entity_decode() does not convert entities without - // semicolons, so we are left with our own little solution here. Bummer. - - if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR version_compare(phpversion(), '5.0.0', '>='))) - { - $str = html_entity_decode($str, ENT_COMPAT, $charset); - $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str); - return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str); - } - - // Numeric Entities - $str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str); - $str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str); - - // Literal Entities - Slightly slow so we do another check - if (stristr($str, '&') === FALSE) - { - $str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES))); - } - - return $str; - } - - // -------------------------------------------------------------------- - - /** - * Filter Attributes - * - * Filters tag attributes for consistency and safety - * - * @access public - * @param string - * @return string - */ - function _filter_attributes($str) - { - $out = ''; - - if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches)) - { - foreach ($matches[0] as $match) - { - $out .= preg_replace("#/\*.*?\*/#s", '', $match); - } - } - - return $out; - } - - // -------------------------------------------------------------------- - -} -// END Input class - -/* End of file Input.php */ -/* Location: ./system/libraries/Input.php */
\ No newline at end of file diff --git a/system/libraries/Javascript.php b/system/libraries/Javascript.php new file mode 100755 index 000000000..167859abd --- /dev/null +++ b/system/libraries/Javascript.php @@ -0,0 +1,871 @@ +<?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) 2008 - 2011, EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * Javascript Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Javascript + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/javascript.html + */ +class CI_Javascript { + + var $_javascript_location = 'js'; + + public function __construct($params = array()) + { + $defaults = array('js_library_driver' => 'jquery', 'autoload' => TRUE); + + foreach ($defaults as $key => $val) + { + if (isset($params[$key]) && $params[$key] !== "") + { + $defaults[$key] = $params[$key]; + } + } + + extract($defaults); + + $this->CI =& get_instance(); + + // load the requested js library + $this->CI->load->library('javascript/'.$js_library_driver, array('autoload' => $autoload)); + // make js to refer to current library + $this->js =& $this->CI->$js_library_driver; + + log_message('debug', "Javascript Class Initialized and loaded. Driver used: $js_library_driver"); + } + + // -------------------------------------------------------------------- + // Event Code + // -------------------------------------------------------------------- + + /** + * Blur + * + * Outputs a javascript library blur event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function blur($element = 'this', $js = '') + { + return $this->js->_blur($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Change + * + * Outputs a javascript library change event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function change($element = 'this', $js = '') + { + return $this->js->_change($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Click + * + * Outputs a javascript library click event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @param boolean whether or not to return false + * @return string + */ + function click($element = 'this', $js = '', $ret_false = TRUE) + { + return $this->js->_click($element, $js, $ret_false); + } + + // -------------------------------------------------------------------- + + /** + * Double Click + * + * Outputs a javascript library dblclick event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function dblclick($element = 'this', $js = '') + { + return $this->js->_dblclick($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Error + * + * Outputs a javascript library error event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function error($element = 'this', $js = '') + { + return $this->js->_error($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Focus + * + * Outputs a javascript library focus event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function focus($element = 'this', $js = '') + { + return $this->js->__add_event($focus, $js); + } + + // -------------------------------------------------------------------- + + /** + * Hover + * + * Outputs a javascript library hover event + * + * @access public + * @param string - element + * @param string - Javascript code for mouse over + * @param string - Javascript code for mouse out + * @return string + */ + function hover($element = 'this', $over, $out) + { + return $this->js->__hover($element, $over, $out); + } + + // -------------------------------------------------------------------- + + /** + * Keydown + * + * Outputs a javascript library keydown event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function keydown($element = 'this', $js = '') + { + return $this->js->_keydown($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Keyup + * + * Outputs a javascript library keydown event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function keyup($element = 'this', $js = '') + { + return $this->js->_keyup($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Load + * + * Outputs a javascript library load event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function load($element = 'this', $js = '') + { + return $this->js->_load($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mousedown + * + * Outputs a javascript library mousedown event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function mousedown($element = 'this', $js = '') + { + return $this->js->_mousedown($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Out + * + * Outputs a javascript library mouseout event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function mouseout($element = 'this', $js = '') + { + return $this->js->_mouseout($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Over + * + * Outputs a javascript library mouseover event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function mouseover($element = 'this', $js = '') + { + return $this->js->_mouseover($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Mouseup + * + * Outputs a javascript library mouseup event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function mouseup($element = 'this', $js = '') + { + return $this->js->_mouseup($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Output + * + * Outputs the called javascript to the screen + * + * @access public + * @param string The code to output + * @return string + */ + function output($js) + { + return $this->js->_output($js); + } + + // -------------------------------------------------------------------- + + /** + * Ready + * + * Outputs a javascript library mouseup event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function ready($js) + { + return $this->js->_document_ready($js); + } + + // -------------------------------------------------------------------- + + /** + * Resize + * + * Outputs a javascript library resize event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function resize($element = 'this', $js = '') + { + return $this->js->_resize($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Scroll + * + * Outputs a javascript library scroll event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function scroll($element = 'this', $js = '') + { + return $this->js->_scroll($element, $js); + } + + // -------------------------------------------------------------------- + + /** + * Unload + * + * Outputs a javascript library unload event + * + * @access public + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function unload($element = 'this', $js = '') + { + return $this->js->_unload($element, $js); + } + + // -------------------------------------------------------------------- + // Effects + // -------------------------------------------------------------------- + + + /** + * Add Class + * + * Outputs a javascript library addClass event + * + * @access public + * @param string - element + * @param string - Class to add + * @return string + */ + function addClass($element = 'this', $class = '') + { + return $this->js->_addClass($element, $class); + } + + // -------------------------------------------------------------------- + + /** + * Animate + * + * Outputs a javascript library animate event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function animate($element = 'this', $params = array(), $speed = '', $extra = '') + { + return $this->js->_animate($element, $params, $speed, $extra); + } + + // -------------------------------------------------------------------- + + /** + * Fade In + * + * Outputs a javascript library hide event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function fadeIn($element = 'this', $speed = '', $callback = '') + { + return $this->js->_fadeIn($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Fade Out + * + * Outputs a javascript library hide event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function fadeOut($element = 'this', $speed = '', $callback = '') + { + return $this->js->_fadeOut($element, $speed, $callback); + } + // -------------------------------------------------------------------- + + /** + * Slide Up + * + * Outputs a javascript library slideUp event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function slideUp($element = 'this', $speed = '', $callback = '') + { + return $this->js->_slideUp($element, $speed, $callback); + + } + + // -------------------------------------------------------------------- + + /** + * Remove Class + * + * Outputs a javascript library removeClass event + * + * @access public + * @param string - element + * @param string - Class to add + * @return string + */ + function removeClass($element = 'this', $class = '') + { + return $this->js->_removeClass($element, $class); + } + + // -------------------------------------------------------------------- + + /** + * Slide Down + * + * Outputs a javascript library slideDown event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function slideDown($element = 'this', $speed = '', $callback = '') + { + return $this->js->_slideDown($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Slide Toggle + * + * Outputs a javascript library slideToggle event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function slideToggle($element = 'this', $speed = '', $callback = '') + { + return $this->js->_slideToggle($element, $speed, $callback); + + } + + // -------------------------------------------------------------------- + + /** + * Hide + * + * Outputs a javascript library hide action + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function hide($element = 'this', $speed = '', $callback = '') + { + return $this->js->_hide($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Toggle + * + * Outputs a javascript library toggle event + * + * @access public + * @param string - element + * @return string + */ + function toggle($element = 'this') + { + return $this->js->_toggle($element); + + } + + // -------------------------------------------------------------------- + + /** + * Toggle Class + * + * Outputs a javascript library toggle class event + * + * @access public + * @param string - element + * @return string + */ + function toggleClass($element = 'this', $class='') + { + return $this->js->_toggleClass($element, $class); + } + + // -------------------------------------------------------------------- + + /** + * Show + * + * Outputs a javascript library show event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function show($element = 'this', $speed = '', $callback = '') + { + return $this->js->_show($element, $speed, $callback); + } + + + // -------------------------------------------------------------------- + + /** + * Compile + * + * gather together all script needing to be output + * + * @access public + * @param string The element to attach the event to + * @return string + */ + function compile($view_var = 'script_foot', $script_tags = TRUE) + { + $this->js->_compile($view_var, $script_tags); + } + + /** + * Clear Compile + * + * Clears any previous javascript collected for output + * + * @access public + * @return void + */ + function clear_compile() + { + $this->js->_clear_compile(); + } + + // -------------------------------------------------------------------- + + /** + * External + * + * Outputs a <script> tag with the source as an external js file + * + * @access public + * @param string The element to attach the event to + * @return string + */ + function external($external_file = '', $relative = FALSE) + { + if ($external_file !== '') + { + $this->_javascript_location = $external_file; + } + else + { + if ($this->CI->config->item('javascript_location') != '') + { + $this->_javascript_location = $this->CI->config->item('javascript_location'); + } + } + + if ($relative === TRUE OR strncmp($external_file, 'http://', 7) == 0 OR strncmp($external_file, 'https://', 8) == 0) + { + $str = $this->_open_script($external_file); + } + elseif (strpos($this->_javascript_location, 'http://') !== FALSE) + { + $str = $this->_open_script($this->_javascript_location.$external_file); + } + else + { + $str = $this->_open_script($this->CI->config->slash_item('base_url').$this->_javascript_location.$external_file); + } + + $str .= $this->_close_script(); + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Inline + * + * Outputs a <script> tag + * + * @access public + * @param string The element to attach the event to + * @param boolean If a CDATA section should be added + * @return string + */ + function inline($script, $cdata = TRUE) + { + $str = $this->_open_script(); + $str .= ($cdata) ? "\n// <![CDATA[\n{$script}\n// ]]>\n" : "\n{$script}\n"; + $str .= $this->_close_script(); + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Open Script + * + * Outputs an opening <script> + * + * @access private + * @param string + * @return string + */ + function _open_script($src = '') + { + $str = '<script type="text/javascript" charset="'.strtolower($this->CI->config->item('charset')).'"'; + $str .= ($src == '') ? '>' : ' src="'.$src.'">'; + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Close Script + * + * Outputs an closing </script> + * + * @access private + * @param string + * @return string + */ + function _close_script($extra = "\n") + { + return "</script>$extra"; + } + + + // -------------------------------------------------------------------- + // -------------------------------------------------------------------- + // AJAX-Y STUFF - still a testbed + // -------------------------------------------------------------------- + // -------------------------------------------------------------------- + + /** + * Update + * + * Outputs a javascript library slideDown event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function update($element = 'this', $speed = '', $callback = '') + { + return $this->js->_updater($element, $speed, $callback); + } + + // -------------------------------------------------------------------- + + /** + * Generate JSON + * + * Can be passed a database result or associative array and returns a JSON formatted string + * + * @param mixed result set or array + * @param bool match array types (defaults to objects) + * @return string a json formatted string + */ + function generate_json($result = NULL, $match_array_type = FALSE) + { + // JSON data can optionally be passed to this function + // either as a database result object or an array, or a user supplied array + if ( ! is_null($result)) + { + if (is_object($result)) + { + $json_result = $result->result_array(); + } + elseif (is_array($result)) + { + $json_result = $result; + } + else + { + return $this->_prep_args($result); + } + } + else + { + return 'null'; + } + + $json = array(); + $_is_assoc = TRUE; + + if ( ! is_array($json_result) AND empty($json_result)) + { + show_error("Generate JSON Failed - Illegal key, value pair."); + } + elseif ($match_array_type) + { + $_is_assoc = $this->_is_associative_array($json_result); + } + + foreach ($json_result as $k => $v) + { + if ($_is_assoc) + { + $json[] = $this->_prep_args($k, TRUE).':'.$this->generate_json($v, $match_array_type); + } + else + { + $json[] = $this->generate_json($v, $match_array_type); + } + } + + $json = implode(',', $json); + + return $_is_assoc ? "{".$json."}" : "[".$json."]"; + + } + + // -------------------------------------------------------------------- + + /** + * Is associative array + * + * Checks for an associative array + * + * @access public + * @param type + * @return type + */ + function _is_associative_array($arr) + { + foreach (array_keys($arr) as $key => $val) + { + if ($key !== $val) + { + return TRUE; + } + } + + return FALSE; + } + + // -------------------------------------------------------------------- + + /** + * Prep Args + * + * Ensures a standard json value and escapes values + * + * @access public + * @param type + * @return type + */ + function _prep_args($result, $is_key = FALSE) + { + if (is_null($result)) + { + return 'null'; + } + elseif (is_bool($result)) + { + return ($result === TRUE) ? 'true' : 'false'; + } + elseif (is_string($result) OR $is_key) + { + return '"'.str_replace(array('\\', "\t", "\n", "\r", '"'), array('\\\\', '\\t', '\\n', "\\r", '\"'), $result).'"'; + } + elseif (is_scalar($result)) + { + return $result; + } + } + + // -------------------------------------------------------------------- +} +// END Javascript Class + +/* End of file Javascript.php */ +/* Location: ./system/libraries/Javascript.php */
\ No newline at end of file diff --git a/system/libraries/Language.php b/system/libraries/Language.php deleted file mode 100644 index 515d04a40..000000000 --- a/system/libraries/Language.php +++ /dev/null @@ -1,123 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * Language Class - * - * @package CodeIgniter - * @subpackage Libraries - * @category Language - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/language.html - */ -class CI_Language { - - var $language = array(); - var $is_loaded = array(); - - /** - * Constructor - * - * @access public - */ - function CI_Language() - { - log_message('debug', "Language Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Load a language file - * - * @access public - * @param mixed the name of the language file to be loaded. Can be an array - * @param string the language (english, etc.) - * @return mixed - */ - function load($langfile = '', $idiom = '', $return = FALSE) - { - $langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT; - - if (in_array($langfile, $this->is_loaded, TRUE)) - { - return; - } - - if ($idiom == '') - { - $CI =& get_instance(); - $deft_lang = $CI->config->item('language'); - $idiom = ($deft_lang == '') ? 'english' : $deft_lang; - } - - // Determine where the language file is and load it - if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile)) - { - include(APPPATH.'language/'.$idiom.'/'.$langfile); - } - else - { - if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile)) - { - include(BASEPATH.'language/'.$idiom.'/'.$langfile); - } - else - { - show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile); - } - } - - if ( ! isset($lang)) - { - log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile); - return; - } - - if ($return == TRUE) - { - return $lang; - } - - $this->is_loaded[] = $langfile; - $this->language = array_merge($this->language, $lang); - unset($lang); - - log_message('debug', 'Language file loaded: language/'.$idiom.'/'.$langfile); - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Fetch a single line of text from the language array - * - * @access public - * @param string $line the language line - * @return string - */ - function line($line = '') - { - $line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line]; - return $line; - } - -} -// END Language Class - -/* End of file Language.php */ -/* Location: ./system/libraries/Language.php */
\ No newline at end of file diff --git a/system/libraries/Loader.php b/system/libraries/Loader.php deleted file mode 100644 index 4a03312c4..000000000 --- a/system/libraries/Loader.php +++ /dev/null @@ -1,1085 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * Loader Class - * - * Loads views and files - * - * @package CodeIgniter - * @subpackage Libraries - * @author ExpressionEngine Dev Team - * @category Loader - * @link http://codeigniter.com/user_guide/libraries/loader.html - */ -class CI_Loader { - - // All these are set automatically. Don't mess with them. - var $_ci_ob_level; - var $_ci_view_path = ''; - var $_ci_is_php5 = FALSE; - var $_ci_is_instance = FALSE; // Whether we should use $this or $CI =& get_instance() - var $_ci_cached_vars = array(); - var $_ci_classes = array(); - var $_ci_loaded_files = array(); - var $_ci_models = array(); - var $_ci_helpers = array(); - var $_ci_plugins = array(); - var $_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 CI_Loader() - { - $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE; - $this->_ci_view_path = APPPATH.'views/'; - $this->_ci_ob_level = ob_get_level(); - - log_message('debug', "Loader Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Class 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) - { - if ($library == '') - { - return FALSE; - } - - if ( ! is_null($params) AND ! is_array($params)) - { - $params = NULL; - } - - if (is_array($library)) - { - foreach ($library as $class) - { - $this->_ci_load_class($class, $params, $object_name); - } - } - else - { - $this->_ci_load_class($library, $params, $object_name); - } - - $this->_ci_assign_to_models(); - } - - // -------------------------------------------------------------------- - - /** - * Model 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) - { - if (is_array($model)) - { - foreach($model as $babe) - { - $this->model($babe); - } - return; - } - - if ($model == '') - { - return; - } - - // Is the model in a sub-folder? If so, parse out the filename and path. - if (strpos($model, '/') === FALSE) - { - $path = ''; - } - else - { - $x = explode('/', $model); - $model = end($x); - unset($x[count($x)-1]); - $path = implode('/', $x).'/'; - } - - if ($name == '') - { - $name = $model; - } - - if (in_array($name, $this->_ci_models, TRUE)) - { - return; - } - - $CI =& get_instance(); - if (isset($CI->$name)) - { - show_error('The model name you are loading is the name of a resource that is already being used: '.$name); - } - - $model = strtolower($model); - - if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT)) - { - show_error('Unable to locate the model you have specified: '.$model); - } - - if ($db_conn !== FALSE AND ! class_exists('CI_DB')) - { - if ($db_conn === TRUE) - $db_conn = ''; - - $CI->load->database($db_conn, FALSE, TRUE); - } - - if ( ! class_exists('Model')) - { - load_class('Model', FALSE); - } - - require_once(APPPATH.'models/'.$path.$model.EXT); - - $model = ucfirst($model); - - $CI->$name = new $model(); - $CI->$name->_assign_libraries(); - - $this->_ci_models[] = $name; - } - - // -------------------------------------------------------------------- - - /** - * 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 = FALSE) - { - // Grab the super object - $CI =& get_instance(); - - // Do we even need to load the database class? - if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db)) - { - return FALSE; - } - - require_once(BASEPATH.'database/DB'.EXT); - - if ($return === TRUE) - { - return DB($params, $active_record); - } - - // Initialize the db variable. Needed to prevent - // reference errors with some configurations - $CI->db = ''; - - // Load the DB class - $CI->db =& DB($params, $active_record); - - // Assign the DB object to any existing models - $this->_ci_assign_to_models(); - } - - // -------------------------------------------------------------------- - - /** - * Load the Utilities Class - * - * @access public - * @return string - */ - function dbutil() - { - if ( ! class_exists('CI_DB')) - { - $this->database(); - } - - $CI =& get_instance(); - - // for backwards compatibility, load dbforge so we can extend dbutils off it - // 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); - $class = 'CI_DB_'.$CI->db->dbdriver.'_utility'; - - $CI->dbutil =& instantiate_class(new $class()); - - $CI->load->_ci_assign_to_models(); - } - - // -------------------------------------------------------------------- - - /** - * Load the Database Forge Class - * - * @access public - * @return string - */ - function dbforge() - { - if ( ! class_exists('CI_DB')) - { - $this->database(); - } - - $CI =& get_instance(); - - require_once(BASEPATH.'database/DB_forge'.EXT); - require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT); - $class = 'CI_DB_'.$CI->db->dbdriver.'_forge'; - - $CI->dbforge = new $class(); - - $CI->load->_ci_assign_to_models(); - } - - // -------------------------------------------------------------------- - - /** - * Load View - * - * This function is used to load a "view" file. It has three parameters: - * - * 1. The name of the "view" file to be included. - * 2. An associative array of data to be extracted for use in the view. - * 3. TRUE/FALSE - whether to return the data or load it. In - * 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) - { - return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Load File - * - * This is a generic file loader - * - * @access public - * @param string - * @param bool - * @return string - */ - function file($path, $return = FALSE) - { - return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return)); - } - - // -------------------------------------------------------------------- - - /** - * Set Variables - * - * 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 = '') - { - if ($val != '' AND is_string($vars)) - { - $vars = array($vars => $val); - } - - $vars = $this->_ci_object_to_array($vars); - - if (is_array($vars) AND count($vars) > 0) - { - foreach ($vars as $key => $val) - { - $this->_ci_cached_vars[$key] = $val; - } - } - } - - // -------------------------------------------------------------------- - - /** - * Load Helper - * - * This function loads the specified helper file. - * - * @access public - * @param mixed - * @return void - */ - function helper($helpers = array()) - { - if ( ! is_array($helpers)) - { - $helpers = array($helpers); - } - - foreach ($helpers as $helper) - { - $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper'); - - if (isset($this->_ci_helpers[$helper])) - { - continue; - } - - $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT; - - // Is this a helper extension request? - if (file_exists($ext_helper)) - { - $base_helper = BASEPATH.'helpers/'.$helper.EXT; - - if ( ! file_exists($base_helper)) - { - show_error('Unable to load the requested file: helpers/'.$helper.EXT); - } - - include_once($ext_helper); - include_once($base_helper); - } - elseif (file_exists(APPPATH.'helpers/'.$helper.EXT)) - { - include_once(APPPATH.'helpers/'.$helper.EXT); - } - else - { - if (file_exists(BASEPATH.'helpers/'.$helper.EXT)) - { - include_once(BASEPATH.'helpers/'.$helper.EXT); - } - else - { - show_error('Unable to load the requested file: helpers/'.$helper.EXT); - } - } - - $this->_ci_helpers[$helper] = TRUE; - log_message('debug', 'Helper loaded: '.$helper); - } - } - - // -------------------------------------------------------------------- - - /** - * Load Helpers - * - * 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()) - { - $this->helper($helpers); - } - - // -------------------------------------------------------------------- - - /** - * Load Plugin - * - * This function loads the specified plugin. - * - * @access public - * @param array - * @return void - */ - function plugin($plugins = array()) - { - if ( ! is_array($plugins)) - { - $plugins = array($plugins); - } - - foreach ($plugins as $plugin) - { - $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi'); - - if (isset($this->_ci_plugins[$plugin])) - { - continue; - } - - if (file_exists(APPPATH.'plugins/'.$plugin.EXT)) - { - include_once(APPPATH.'plugins/'.$plugin.EXT); - } - else - { - if (file_exists(BASEPATH.'plugins/'.$plugin.EXT)) - { - include_once(BASEPATH.'plugins/'.$plugin.EXT); - } - else - { - show_error('Unable to load the requested file: plugins/'.$plugin.EXT); - } - } - - $this->_ci_plugins[$plugin] = TRUE; - log_message('debug', 'Plugin loaded: '.$plugin); - } - } - - // -------------------------------------------------------------------- - - /** - * Load Plugins - * - * 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 plugins($plugins = array()) - { - $this->plugin($plugins); - } - - // -------------------------------------------------------------------- - - /** - * Loads a language file - * - * @access public - * @param array - * @param string - * @return void - */ - function language($file = array(), $lang = '') - { - $CI =& get_instance(); - - if ( ! is_array($file)) - { - $file = array($file); - } - - foreach ($file as $langfile) - { - $CI->lang->load($langfile, $lang); - } - } - - /** - * Loads language files for scaffolding - * - * @access public - * @param string - * @return arra - */ - function scaffold_language($file = '', $lang = '', $return = FALSE) - { - $CI =& get_instance(); - return $CI->lang->load($file, $lang, $return); - } - - // -------------------------------------------------------------------- - - /** - * Loads a config file - * - * @access public - * @param string - * @return void - */ - function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE) - { - $CI =& get_instance(); - $CI->config->load($file, $use_sections, $fail_gracefully); - } - - // -------------------------------------------------------------------- - - /** - * Scaffolding Loader - * - * This initializing function works a bit different than the - * others. It doesn't load the class. Instead, it simply - * sets a flag indicating that scaffolding is allowed to be - * used. The actual scaffolding function below is - * called by the front controller based on whether the - * second segment of the URL matches the "secret" scaffolding - * word stored in the application/config/routes.php - * - * @access public - * @param string - * @return void - */ - function scaffolding($table = '') - { - if ($table === FALSE) - { - show_error('You must include the name of the table you would like to access when you initialize scaffolding'); - } - - $CI =& get_instance(); - $CI->_ci_scaffolding = TRUE; - $CI->_ci_scaff_table = $table; - } - - // -------------------------------------------------------------------- - - /** - * Loader - * - * This function is used to load views and files. - * 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) - { - // 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]; - } - - // 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 - { - $_ci_x = explode('/', $_ci_path); - $_ci_file = end($_ci_x); - } - - if ( ! file_exists($_ci_path)) - { - show_error('Unable to load the requested file: '.$_ci_file); - } - - // This allows anything loaded using $this->load (views, files, etc.) - // to become accessible from within the Controller and Model functions. - // Only needed when running PHP 5 - - if ($this->_ci_is_instance()) - { - $_ci_CI =& get_instance(); - foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var) - { - if ( ! isset($this->$_ci_key)) - { - $this->$_ci_key =& $_ci_CI->$_ci_key; - } - } - } - - /* - * Extract and cache variables - * - * You can either set variables using the dedicated $this->load_vars() - * function or via the second parameter of this function. We'll merge - * the two types and cache them so that views that are embedded within - * other views can have access to these variables. - */ - if (is_array($_ci_vars)) - { - $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars); - } - extract($this->_ci_cached_vars); - - /* - * Buffer the output - * - * We buffer the output for two reasons: - * 1. Speed. You get a significant speed boost. - * 2. So that the final rendered template can be - * post-processed by the output class. Why do we - * need post processing? For one thing, in order to - * show the elapsed page load time. Unless we - * can intercept the content right before it's sent to - * the browser and then stop the timer it won't be accurate. - */ - ob_start(); - - // If the PHP installation does not support short tags we'll - // do a little string replacement, changing the short tags - // to standard PHP echo statements. - - if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE) - { - echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path)))); - } - else - { - include($_ci_path); // include() vs include_once() allows for multiple views with the same name - } - - log_message('debug', 'File loaded: '.$_ci_path); - - // Return the file data if requested - if ($_ci_return === TRUE) - { - $buffer = ob_get_contents(); - @ob_end_clean(); - return $buffer; - } - - /* - * Flush the buffer... or buff the flusher? - * - * In order to permit views to be nested within - * other views, we need to flush the content back out whenever - * we are beyond the first level of output buffering so that - * it can be seen and included properly by the first included - * template and any subsequent ones. Oy! - * - */ - if (ob_get_level() > $this->_ci_ob_level + 1) - { - ob_end_flush(); - } - else - { - // PHP 4 requires that we use a global - global $OUT; - $OUT->append_output(ob_get_contents()); - @ob_end_clean(); - } - } - - // -------------------------------------------------------------------- - - /** - * Load class - * - * 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) - { - // 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, '/')); - - // Was the path included with the class name? - // We look for a slash to determine this - $subdir = ''; - if (strpos($class, '/') !== FALSE) - { - // explode the path so we can separate the filename from the path - $x = explode('/', $class); - - // Reset the $class variable now that we know the actual filename - $class = end($x); - - // Kill the filename from the array - unset($x[count($x)-1]); - - // Glue the path back together, sans filename - $subdir = implode($x, '/').'/'; - } - - // 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; - - // Is this a class extension request? - if (file_exists($subclass)) - { - $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT; - - if ( ! file_exists($baseclass)) - { - log_message('error', "Unable to load the requested class: ".$class); - show_error("Unable to load the requested class: ".$class); - } - - // Safety: Was the class already loaded by a previous call? - if (in_array($subclass, $this->_ci_loaded_files)) - { - // Before we deem this to be a duplicate request, let's see - // if a custom object name is being supplied. If so, we'll - // return a new instance of the object - if ( ! is_null($object_name)) - { - $CI =& get_instance(); - if ( ! isset($CI->$object_name)) - { - return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name); - } - } - - $is_duplicate = TRUE; - log_message('debug', $class." class already loaded. Second attempt ignored."); - return; - } - - include_once($baseclass); - include_once($subclass); - $this->_ci_loaded_files[] = $subclass; - - return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name); - } - - // Lets search for the requested library file and load it. - $is_duplicate = FALSE; - for ($i = 1; $i < 3; $i++) - { - $path = ($i % 2) ? APPPATH : BASEPATH; - $filepath = $path.'libraries/'.$subdir.$class.EXT; - - // Does the file exist? No? Bummer... - if ( ! file_exists($filepath)) - { - continue; - } - - // Safety: Was the class already loaded by a previous call? - if (in_array($filepath, $this->_ci_loaded_files)) - { - // Before we deem this to be a duplicate request, let's see - // if a custom object name is being supplied. If so, we'll - // return a new instance of the object - if ( ! is_null($object_name)) - { - $CI =& get_instance(); - if ( ! isset($CI->$object_name)) - { - return $this->_ci_init_class($class, '', $params, $object_name); - } - } - - $is_duplicate = TRUE; - log_message('debug', $class." class already loaded. Second attempt ignored."); - return; - } - - include_once($filepath); - $this->_ci_loaded_files[] = $filepath; - return $this->_ci_init_class($class, '', $params, $object_name); - } - } // END FOREACH - - // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified? - if ($subdir == '') - { - $path = strtolower($class).'/'.$class; - return $this->_ci_load_class($path, $params); - } - - // If we got this far we were unable to find the requested class. - // We do not issue errors if the load call failed due to a duplicate request - if ($is_duplicate == FALSE) - { - log_message('error', "Unable to load the requested class: ".$class); - show_error("Unable to load the requested class: ".$class); - } - } - - // -------------------------------------------------------------------- - - /** - * 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) - { - // Is there an associated config file for this class? - if ($config === NULL) - { - // We test for both uppercase and lowercase, for servers that - // are case-sensitive with regard to file names - if (file_exists(APPPATH.'config/'.strtolower($class).EXT)) - { - include_once(APPPATH.'config/'.strtolower($class).EXT); - } - elseif (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT)) - { - include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT); - } - } - - if ($prefix == '') - { - if (class_exists('CI_'.$class)) - { - $name = 'CI_'.$class; - } - elseif (class_exists(config_item('subclass_prefix').$class)) - { - $name = config_item('subclass_prefix').$class; - } - else - { - $name = $class; - } - } - else - { - $name = $prefix.$class; - } - - // Is the class name valid? - if ( ! class_exists($name)) - { - log_message('error', "Non-existent class: ".$name); - show_error("Non-existent class: ".$class); - } - - // Set the variable name we will assign the class to - // Was a custom class name supplied? If so we'll use it - $class = strtolower($class); - - if (is_null($object_name)) - { - $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class]; - } - else - { - $classvar = $object_name; - } - - // Save the class name and object name - $this->_ci_classes[$class] = $classvar; - - // Instantiate the class - $CI =& get_instance(); - if ($config !== NULL) - { - $CI->$classvar = new $name($config); - } - else - { - $CI->$classvar = new $name; - } - } - - // -------------------------------------------------------------------- - - /** - * Autoloader - * - * The config/autoload.php file contains an array that permits sub-systems, - * libraries, plugins, and helpers to be loaded automatically. - * - * @access private - * @param array - * @return void - */ - function _ci_autoloader() - { - include_once(APPPATH.'config/autoload'.EXT); - - if ( ! isset($autoload)) - { - return FALSE; - } - - // Load any custom config file - if (count($autoload['config']) > 0) - { - $CI =& get_instance(); - foreach ($autoload['config'] as $key => $val) - { - $CI->config->load($val); - } - } - - // Autoload plugins, helpers and languages - foreach (array('helper', 'plugin', 'language') as $type) - { - if (isset($autoload[$type]) AND count($autoload[$type]) > 0) - { - $this->$type($autoload[$type]); - } - } - - // A little tweak to remain backward compatible - // The $autoload['core'] item was deprecated - if ( ! isset($autoload['libraries'])) - { - $autoload['libraries'] = $autoload['core']; - } - - // Load libraries - if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0) - { - // Load the database driver. - if (in_array('database', $autoload['libraries'])) - { - $this->database(); - $autoload['libraries'] = array_diff($autoload['libraries'], array('database')); - } - - // Load scaffolding - if (in_array('scaffolding', $autoload['libraries'])) - { - $this->scaffolding(); - $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding')); - } - - // Load all other libraries - foreach ($autoload['libraries'] as $item) - { - $this->library($item); - } - } - - // Autoload models - if (isset($autoload['model'])) - { - $this->model($autoload['model']); - } - - } - - // -------------------------------------------------------------------- - - /** - * Assign to Models - * - * Makes sure that anything loaded by the loader class (libraries, plugins, etc.) - * will be available to models, if any exist. - * - * @access private - * @param object - * @return array - */ - function _ci_assign_to_models() - { - if (count($this->_ci_models) == 0) - { - return; - } - - if ($this->_ci_is_instance()) - { - $CI =& get_instance(); - foreach ($this->_ci_models as $model) - { - $CI->$model->_assign_libraries(); - } - } - else - { - foreach ($this->_ci_models as $model) - { - $this->$model->_assign_libraries(); - } - } - } - - // -------------------------------------------------------------------- - - /** - * Object to Array - * - * 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) - { - return (is_object($object)) ? get_object_vars($object) : $object; - } - - // -------------------------------------------------------------------- - - /** - * Determines whether we should use the CI instance or $this - * - * @access private - * @return bool - */ - function _ci_is_instance() - { - if ($this->_ci_is_php5 == TRUE) - { - return TRUE; - } - - global $CI; - return (is_object($CI)) ? TRUE : FALSE; - } - -} - -/* End of file Loader.php */ -/* Location: ./system/libraries/Loader.php */
\ No newline at end of file diff --git a/system/libraries/Log.php b/system/libraries/Log.php index 4e6b3bc39..fb2c5a49b 100644..100755 --- a/system/libraries/Log.php +++ b/system/libraries/Log.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -26,87 +26,84 @@ */ class CI_Log { - var $log_path; - var $_threshold = 1; - var $_date_fmt = 'Y-m-d H:i:s'; - var $_enabled = TRUE; - var $_levels = array('ERROR' => '1', 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4'); + protected $_log_path; + protected $_threshold = 1; + protected $_date_fmt = 'Y-m-d H:i:s'; + protected $_enabled = TRUE; + protected $_levels = array('ERROR' => '1', 'DEBUG' => '2', 'INFO' => '3', 'ALL' => '4'); /** * Constructor - * - * @access public */ - function CI_Log() + public function __construct() { $config =& get_config(); - - $this->log_path = ($config['log_path'] != '') ? $config['log_path'] : BASEPATH.'logs/'; - - if ( ! is_dir($this->log_path) OR ! is_really_writable($this->log_path)) + + $this->_log_path = ($config['log_path'] != '') ? $config['log_path'] : APPPATH.'logs/'; + + if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path)) { $this->_enabled = FALSE; } - + if (is_numeric($config['log_threshold'])) { $this->_threshold = $config['log_threshold']; } - + if ($config['log_date_format'] != '') { $this->_date_fmt = $config['log_date_format']; } } - + // -------------------------------------------------------------------- - + /** * Write Log File * * Generally this function will be called using the global log_message() function * - * @access public * @param string the error level * @param string the error message * @param bool whether the error is a native PHP error * @return bool - */ - function write_log($level = 'error', $msg, $php_error = FALSE) - { + */ + public function write_log($level = 'error', $msg, $php_error = FALSE) + { if ($this->_enabled === FALSE) { return FALSE; } - + $level = strtoupper($level); - + if ( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold)) { return FALSE; } - - $filepath = $this->log_path.'log-'.date('Y-m-d').EXT; + + $filepath = $this->_log_path.'log-'.date('Y-m-d').EXT; $message = ''; - + if ( ! file_exists($filepath)) { $message .= "<"."?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); ?".">\n\n"; } - + if ( ! $fp = @fopen($filepath, FOPEN_WRITE_CREATE)) { return FALSE; } $message .= $level.' '.(($level == 'INFO') ? ' -' : '-').' '.date($this->_date_fmt). ' --> '.$msg."\n"; - - flock($fp, LOCK_EX); + + flock($fp, LOCK_EX); fwrite($fp, $message); flock($fp, LOCK_UN); fclose($fp); - - @chmod($filepath, FILE_WRITE_MODE); + + @chmod($filepath, FILE_WRITE_MODE); return TRUE; } diff --git a/system/libraries/Model.php b/system/libraries/Model.php deleted file mode 100644 index e9c2d24d1..000000000 --- a/system/libraries/Model.php +++ /dev/null @@ -1,83 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * CodeIgniter Model Class - * - * @package CodeIgniter - * @subpackage Libraries - * @category Libraries - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/config.html - */ -class Model { - - var $_parent_name = ''; - - /** - * Constructor - * - * @access public - */ - function Model() - { - // If the magic __get() or __set() methods are used in a Model references can't be used. - $this->_assign_libraries( (method_exists($this, '__get') OR method_exists($this, '__set')) ? FALSE : TRUE ); - - // We don't want to assign the model object to itself when using the - // assign_libraries function below so we'll grab the name of the model parent - $this->_parent_name = ucfirst(get_class($this)); - - log_message('debug', "Model Class Initialized"); - } - - /** - * Assign Libraries - * - * Creates local references to all currently instantiated objects - * so that any syntax that can be legally used in a controller - * can be used within models. - * - * @access private - */ - function _assign_libraries($use_reference = TRUE) - { - $CI =& get_instance(); - foreach (array_keys(get_object_vars($CI)) as $key) - { - if ( ! isset($this->$key) AND $key != $this->_parent_name) - { - // In some cases using references can cause - // problems so we'll conditionally use them - if ($use_reference == TRUE) - { - $this->$key = NULL; // Needed to prevent reference errors with some configurations - $this->$key =& $CI->$key; - } - else - { - $this->$key = $CI->$key; - } - } - } - } - -} -// END Model Class - -/* End of file Model.php */ -/* Location: ./system/libraries/Model.php */
\ No newline at end of file diff --git a/system/libraries/Output.php b/system/libraries/Output.php deleted file mode 100644 index f320b4142..000000000 --- a/system/libraries/Output.php +++ /dev/null @@ -1,409 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * Output Class - * - * Responsible for sending final output to browser - * - * @package CodeIgniter - * @subpackage Libraries - * @category Output - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/output.html - */ -class CI_Output { - - var $final_output; - var $cache_expiration = 0; - var $headers = array(); - var $enable_profiler = FALSE; - - - function CI_Output() - { - log_message('debug', "Output Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Get Output - * - * Returns the current output string - * - * @access public - * @return string - */ - function get_output() - { - return $this->final_output; - } - - // -------------------------------------------------------------------- - - /** - * Set Output - * - * Sets the output string - * - * @access public - * @param string - * @return void - */ - function set_output($output) - { - $this->final_output = $output; - } - - // -------------------------------------------------------------------- - - /** - * Append Output - * - * Appends data onto the output string - * - * @access public - * @param string - * @return void - */ - function append_output($output) - { - if ($this->final_output == '') - { - $this->final_output = $output; - } - else - { - $this->final_output .= $output; - } - } - - // -------------------------------------------------------------------- - - /** - * Set Header - * - * Lets you set a server header which will be outputted with the final display. - * - * Note: If a file is cached, headers will not be sent. We need to figure out - * how to permit header data to be saved with the cache data... - * - * @access public - * @param string - * @return void - */ - function set_header($header, $replace = TRUE) - { - $this->headers[] = array($header, $replace); - } - - // -------------------------------------------------------------------- - - /** - * Set HTTP Status Header - * moved to Common procedural functions in 1.7.2 - * - * @access public - * @param int the status code - * @param string - * @return void - */ - function set_status_header($code = '200', $text = '') - { - set_status_header($code, $text); - } - - // -------------------------------------------------------------------- - - /** - * Enable/disable Profiler - * - * @access public - * @param bool - * @return void - */ - function enable_profiler($val = TRUE) - { - $this->enable_profiler = (is_bool($val)) ? $val : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Set Cache - * - * @access public - * @param integer - * @return void - */ - function cache($time) - { - $this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time; - } - - // -------------------------------------------------------------------- - - /** - * Display Output - * - * All "view" data is automatically put into this variable by the controller class: - * - * $this->final_output - * - * This function sends the finalized output data to the browser along - * with any server headers and profile data. It also stops the - * benchmark timer so the page rendering speed and memory usage can be shown. - * - * @access public - * @return mixed - */ - function _display($output = '') - { - // Note: We use globals because we can't use $CI =& get_instance() - // since this function is sometimes called by the caching mechanism, - // which happens before the CI super object is available. - global $BM, $CFG; - - // -------------------------------------------------------------------- - - // Set the output data - if ($output == '') - { - $output =& $this->final_output; - } - - // -------------------------------------------------------------------- - - // Do we need to write a cache file? - if ($this->cache_expiration > 0) - { - $this->_write_cache($output); - } - - // -------------------------------------------------------------------- - - // Parse out the elapsed time and memory usage, - // then swap the pseudo-variables with the data - - $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end'); - $output = str_replace('{elapsed_time}', $elapsed, $output); - - $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB'; - $output = str_replace('{memory_usage}', $memory, $output); - - // -------------------------------------------------------------------- - - // Is compression requested? - if ($CFG->item('compress_output') === TRUE) - { - if (extension_loaded('zlib')) - { - if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) AND strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) - { - ob_start('ob_gzhandler'); - } - } - } - - // -------------------------------------------------------------------- - - // Are there any server headers to send? - if (count($this->headers) > 0) - { - foreach ($this->headers as $header) - { - @header($header[0], $header[1]); - } - } - - // -------------------------------------------------------------------- - - // Does the get_instance() function exist? - // If not we know we are dealing with a cache file so we'll - // simply echo out the data and exit. - if ( ! function_exists('get_instance')) - { - echo $output; - log_message('debug', "Final output sent to browser"); - log_message('debug', "Total execution time: ".$elapsed); - return TRUE; - } - - // -------------------------------------------------------------------- - - // Grab the super object. We'll need it in a moment... - $CI =& get_instance(); - - // Do we need to generate profile data? - // If so, load the Profile class and run it. - if ($this->enable_profiler == TRUE) - { - $CI->load->library('profiler'); - - // If the output data contains closing </body> and </html> tags - // we will remove them and add them back after we insert the profile data - if (preg_match("|</body>.*?</html>|is", $output)) - { - $output = preg_replace("|</body>.*?</html>|is", '', $output); - $output .= $CI->profiler->run(); - $output .= '</body></html>'; - } - else - { - $output .= $CI->profiler->run(); - } - } - - // -------------------------------------------------------------------- - - // Does the controller contain a function named _output()? - // If so send the output there. Otherwise, echo it. - if (method_exists($CI, '_output')) - { - $CI->_output($output); - } - else - { - echo $output; // Send it to the browser! - } - - log_message('debug', "Final output sent to browser"); - log_message('debug', "Total execution time: ".$elapsed); - } - - // -------------------------------------------------------------------- - - /** - * Write a Cache File - * - * @access public - * @return void - */ - function _write_cache($output) - { - $CI =& get_instance(); - $path = $CI->config->item('cache_path'); - - $cache_path = ($path == '') ? BASEPATH.'cache/' : $path; - - if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) - { - return; - } - - $uri = $CI->config->item('base_url'). - $CI->config->item('index_page'). - $CI->uri->uri_string(); - - $cache_path .= md5($uri); - - if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE)) - { - log_message('error', "Unable to write cache file: ".$cache_path); - return; - } - - $expire = time() + ($this->cache_expiration * 60); - - if (flock($fp, LOCK_EX)) - { - fwrite($fp, $expire.'TS--->'.$output); - flock($fp, LOCK_UN); - } - else - { - log_message('error', "Unable to secure a file lock for file at: ".$cache_path); - return; - } - fclose($fp); - @chmod($cache_path, DIR_WRITE_MODE); - - log_message('debug', "Cache file written: ".$cache_path); - } - - // -------------------------------------------------------------------- - - /** - * Update/serve a cached file - * - * @access public - * @return void - */ - function _display_cache(&$CFG, &$URI) - { - $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path'); - - if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) - { - return FALSE; - } - - // Build the file path. The file name is an MD5 hash of the full URI - $uri = $CFG->item('base_url'). - $CFG->item('index_page'). - $URI->uri_string; - - $filepath = $cache_path.md5($uri); - - if ( ! @file_exists($filepath)) - { - return FALSE; - } - - if ( ! $fp = @fopen($filepath, FOPEN_READ)) - { - return FALSE; - } - - flock($fp, LOCK_SH); - - $cache = ''; - if (filesize($filepath) > 0) - { - $cache = fread($fp, filesize($filepath)); - } - - flock($fp, LOCK_UN); - fclose($fp); - - // Strip out the embedded timestamp - if ( ! preg_match("/(\d+TS--->)/", $cache, $match)) - { - return FALSE; - } - - // Has the file expired? If so we'll delete it. - if (time() >= trim(str_replace('TS--->', '', $match['1']))) - { - @unlink($filepath); - log_message('debug', "Cache file has expired. File deleted"); - return FALSE; - } - - // Display the cache - $this->_display(str_replace($match['0'], '', $cache)); - log_message('debug', "Cache file is current. Sending it to browser."); - return TRUE; - } - - -} -// END Output Class - -/* End of file Output.php */ -/* Location: ./system/libraries/Output.php */
\ No newline at end of file diff --git a/system/libraries/Pagination.php b/system/libraries/Pagination.php index d6321f41c..1113f862f 100644..100755 --- a/system/libraries/Pagination.php +++ b/system/libraries/Pagination.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -27,11 +27,14 @@ class CI_Pagination { var $base_url = ''; // The page we are linking to - var $total_rows = ''; // Total number of items (database results) - var $per_page = 10; // Max number of items you want shown per page + 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 $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 - var $first_link = '‹ First'; + var $cur_page = 0; // The current page being viewed + var $first_link = '‹ First'; var $next_link = '>'; var $prev_link = '<'; var $last_link = 'Last ›'; @@ -42,6 +45,7 @@ class CI_Pagination { var $first_tag_close = ' '; var $last_tag_open = ' '; var $last_tag_close = ''; + var $first_url = ''; // Alternative URL for the First Page. var $cur_tag_open = ' <strong>'; var $cur_tag_close = '</strong>'; var $next_tag_open = ' '; @@ -52,6 +56,8 @@ class CI_Pagination { var $num_tag_close = ''; var $page_query_string = FALSE; var $query_string_segment = 'per_page'; + var $display_pages = TRUE; + var $anchor_class = ''; /** * Constructor @@ -59,13 +65,18 @@ class CI_Pagination { * @access public * @param array initialization parameters */ - function CI_Pagination($params = array()) + public function __construct($params = array()) { if (count($params) > 0) { $this->initialize($params); } + if ($this->anchor_class != '') + { + $this->anchor_class = 'class="'.$this->anchor_class.'" '; + } + log_message('debug', "Pagination Class Initialized"); } @@ -179,53 +190,77 @@ class CI_Pagination { $this->base_url = rtrim($this->base_url, '/') .'/'; } - // And here we go... + // And here we go... $output = ''; // Render the "First" link - if ($this->cur_page > ($this->num_links + 1)) + if ($this->first_link !== FALSE AND $this->cur_page > ($this->num_links + 1)) { - $output .= $this->first_tag_open.'<a href="'.$this->base_url.'">'.$this->first_link.'</a>'.$this->first_tag_close; + $first_url = ($this->first_url == '') ? $this->base_url : $this->first_url; + $output .= $this->first_tag_open.'<a '.$this->anchor_class.'href="'.$first_url.'">'.$this->first_link.'</a>'.$this->first_tag_close; } // Render the "previous" link - if ($this->cur_page != 1) + if ($this->prev_link !== FALSE AND $this->cur_page != 1) { $i = $uri_page_number - $this->per_page; - if ($i == 0) $i = ''; - $output .= $this->prev_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close; + + if ($i == 0 && $this->first_url != '') + { + $output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$this->prev_link.'</a>'.$this->prev_tag_close; + } + else + { + $i = ($i == 0) ? '' : $this->prefix.$i.$this->suffix; + $output .= $this->prev_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$i.'">'.$this->prev_link.'</a>'.$this->prev_tag_close; + } + } - // Write the digit links - for ($loop = $start -1; $loop <= $end; $loop++) + // Render the pages + if ($this->display_pages !== FALSE) { - $i = ($loop * $this->per_page) - $this->per_page; - - if ($i >= 0) + // Write the digit links + for ($loop = $start -1; $loop <= $end; $loop++) { - if ($this->cur_page == $loop) - { - $output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page - } - else + $i = ($loop * $this->per_page) - $this->per_page; + + if ($i >= 0) { - $n = ($i == 0) ? '' : $i; - $output .= $this->num_tag_open.'<a href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close; + if ($this->cur_page == $loop) + { + $output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page + } + else + { + $n = ($i == 0) ? '' : $i; + + if ($n == '' && $this->first_url != '') + { + $output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->first_url.'">'.$loop.'</a>'.$this->num_tag_close; + } + else + { + $n = ($n == '') ? '' : $this->prefix.$n.$this->suffix; + + $output .= $this->num_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$n.'">'.$loop.'</a>'.$this->num_tag_close; + } + } } } } // Render the "next" link - if ($this->cur_page < $num_pages) + if ($this->next_link !== FALSE AND $this->cur_page < $num_pages) { - $output .= $this->next_tag_open.'<a href="'.$this->base_url.($this->cur_page * $this->per_page).'">'.$this->next_link.'</a>'.$this->next_tag_close; + $output .= $this->next_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.($this->cur_page * $this->per_page).$this->suffix.'">'.$this->next_link.'</a>'.$this->next_tag_close; } // Render the "Last" link - if (($this->cur_page + $this->num_links) < $num_pages) + if ($this->last_link !== FALSE AND ($this->cur_page + $this->num_links) < $num_pages) { $i = (($num_pages * $this->per_page) - $this->per_page); - $output .= $this->last_tag_open.'<a href="'.$this->base_url.$i.'">'.$this->last_link.'</a>'.$this->last_tag_close; + $output .= $this->last_tag_open.'<a '.$this->anchor_class.'href="'.$this->base_url.$this->prefix.$i.$this->suffix.'">'.$this->last_link.'</a>'.$this->last_tag_close; } // Kill double slashes. Note: Sometimes we can end up with a double slash diff --git a/system/libraries/Parser.php b/system/libraries/Parser.php index 399b14b2d..d223da020 100644..100755 --- a/system/libraries/Parser.php +++ b/system/libraries/Parser.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -29,11 +29,11 @@ class CI_Parser { var $l_delim = '{'; var $r_delim = '}'; var $object; - + /** * Parse a template * - * Parses pseudo-variables contained in the specified template, + * Parses pseudo-variables contained in the specified template view, * replacing them with the data in the second param * * @access public @@ -42,38 +42,77 @@ class CI_Parser { * @param bool * @return string */ - function parse($template, $data, $return = FALSE) + public function parse($template, $data, $return = FALSE) { $CI =& get_instance(); $template = $CI->load->view($template, $data, TRUE); - + + return $this->_parse($template, $data, $return); + } + + // -------------------------------------------------------------------- + + /** + * Parse a String + * + * Parses pseudo-variables contained in the specified string, + * replacing them with the data in the second param + * + * @access public + * @param string + * @param array + * @param bool + * @return string + */ + function parse_string($template, $data, $return = FALSE) + { + return $this->_parse($template, $data, $return); + } + + // -------------------------------------------------------------------- + + /** + * Parse a template + * + * Parses pseudo-variables contained in the specified template, + * replacing them with the data in the second param + * + * @access public + * @param string + * @param array + * @param bool + * @return string + */ + function _parse($template, $data, $return = FALSE) + { if ($template == '') { return FALSE; } - + foreach ($data as $key => $val) { if (is_array($val)) { - $template = $this->_parse_pair($key, $val, $template); + $template = $this->_parse_pair($key, $val, $template); } else { $template = $this->_parse_single($key, (string)$val, $template); } } - + if ($return == FALSE) { + $CI =& get_instance(); $CI->output->append_output($template); } - + return $template; } - + // -------------------------------------------------------------------- - + /** * Set the left/right variable delimiters * @@ -87,9 +126,9 @@ class CI_Parser { $this->l_delim = $l; $this->r_delim = $r; } - + // -------------------------------------------------------------------- - + /** * Parse a single key/value * @@ -103,9 +142,9 @@ class CI_Parser { { return str_replace($this->l_delim.$key.$this->r_delim, $val, $string); } - + // -------------------------------------------------------------------- - + /** * Parse a tag pair * @@ -118,7 +157,7 @@ class CI_Parser { * @return string */ function _parse_pair($variable, $data, $string) - { + { if (FALSE === ($match = $this->_match_pair($string, $variable))) { return $string; @@ -139,15 +178,15 @@ class CI_Parser { $temp = $this->_parse_pair($key, $val, $temp); } } - + $str .= $temp; } - + return str_replace($match['0'], $str, $string); } - + // -------------------------------------------------------------------- - + /** * Matches a variable pair * @@ -158,11 +197,11 @@ class CI_Parser { */ function _match_pair($string, $variable) { - if ( ! preg_match("|".$this->l_delim . $variable . $this->r_delim."(.+?)".$this->l_delim . '/' . $variable . $this->r_delim."|s", $string, $match)) + if ( ! preg_match("|" . preg_quote($this->l_delim) . $variable . preg_quote($this->r_delim) . "(.+?)". preg_quote($this->l_delim) . '/' . $variable . preg_quote($this->r_delim) . "|s", $string, $match)) { return FALSE; } - + return $match; } @@ -170,4 +209,4 @@ class CI_Parser { // END Parser Class /* End of file Parser.php */ -/* Location: ./system/libraries/Parser.php */
\ No newline at end of file +/* Location: ./system/libraries/Parser.php */ diff --git a/system/libraries/Profiler.php b/system/libraries/Profiler.php index 84f7871b5..6587eae0b 100644..100755 --- a/system/libraries/Profiler.php +++ b/system/libraries/Profiler.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -33,13 +33,57 @@ class CI_Profiler { var $CI; - - function CI_Profiler() - { - $this->CI =& get_instance(); - $this->CI->load->language('profiler'); - } - + + protected $_available_sections = array( + 'benchmarks', + 'get', + 'memory_usage', + 'post', + 'uri_string', + 'controller_info', + 'queries', + 'http_headers', + 'config' + ); + + public function __construct($config = array()) + { + $this->CI =& get_instance(); + $this->CI->load->language('profiler'); + + // default all sections to display + foreach ($this->_available_sections as $section) + { + if ( ! isset($config[$section])) + { + $this->_compile_{$section} = TRUE; + } + } + + $this->set_sections($config); + } + + // -------------------------------------------------------------------- + + /** + * Set Sections + * + * Sets the private _compile_* properties to enable/disable Profiler sections + * + * @param mixed + * @return void + */ + public function set_sections($config) + { + foreach ($config as $method => $enable) + { + if (in_array($method, $this->_available_sections)) + { + $this->_compile_{$method} = ($enable !== FALSE) ? TRUE : FALSE; + } + } + } + // -------------------------------------------------------------------- /** @@ -50,57 +94,55 @@ class CI_Profiler { * and "_end" respectively). It then compiles the execution times for * all points and returns it as an array * - * @access private * @return array */ - function _compile_benchmarks() - { - $profile = array(); - foreach ($this->CI->benchmark->marker as $key => $val) - { - // We match the "end" marker so that the list ends - // up in the order that it was defined - if (preg_match("/(.+?)_end/i", $key, $match)) - { - if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start'])) - { - $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key); - } - } - } + protected function _compile_benchmarks() + { + $profile = array(); + foreach ($this->CI->benchmark->marker as $key => $val) + { + // We match the "end" marker so that the list ends + // up in the order that it was defined + if (preg_match("/(.+?)_end/i", $key, $match)) + { + if (isset($this->CI->benchmark->marker[$match[1].'_end']) AND isset($this->CI->benchmark->marker[$match[1].'_start'])) + { + $profile[$match[1]] = $this->CI->benchmark->elapsed_time($match[1].'_start', $key); + } + } + } // Build a table containing the profile data. // Note: At some point we should turn this into a template that can // be modified. We also might want to make this data available to be logged - + $output = "\n\n"; - $output .= '<fieldset style="border:1px solid #990000;padding:6px 10px 10px 10px;margin:0 0 20px 0;background-color:#eee">'; + $output .= '<fieldset id="ci_profiler_benchmarks" style="border:1px solid #900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= "\n"; + $output .= '<legend style="color:#900;"> '.$this->CI->lang->line('profiler_benchmarks').' </legend>'; $output .= "\n"; - $output .= '<legend style="color:#990000;"> '.$this->CI->lang->line('profiler_benchmarks').' </legend>'; - $output .= "\n"; - $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n"; - + $output .= "\n\n<table style='width:100%'>\n"; + foreach ($profile as $key => $val) { $key = ucwords(str_replace(array('_', '-'), ' ', $key)); - $output .= "<tr><td width='50%' style='color:#000;font-weight:bold;background-color:#ddd;'>".$key." </td><td width='50%' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n"; + $output .= "<tr><td style='padding:5px;width:50%;color:#000;font-weight:bold;background-color:#ddd;'>".$key." </td><td style='padding:5px;width:50%;color:#900;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n"; } - + $output .= "</table>\n"; $output .= "</fieldset>"; - - return $output; - } - + + return $output; + } + // -------------------------------------------------------------------- /** * Compile Queries * - * @access private * @return string - */ - function _compile_queries() + */ + protected function _compile_queries() { $dbs = array(); @@ -112,100 +154,99 @@ class CI_Profiler { $dbs[] = $CI_object; } } - + if (count($dbs) == 0) { $output = "\n\n"; - $output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= '<fieldset id="ci_profiler_queries" style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; $output .= "\n"; $output .= '<legend style="color:#0000FF;"> '.$this->CI->lang->line('profiler_queries').' </legend>'; - $output .= "\n"; - $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n"; - $output .="<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n"; + $output .= "\n"; + $output .= "\n\n<table style='border:none; width:100%'>\n"; + $output .="<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px'>".$this->CI->lang->line('profiler_no_db')."</td></tr>\n"; $output .= "</table>\n"; $output .= "</fieldset>"; - + return $output; } - + // Load the text helper so we can highlight the SQL $this->CI->load->helper('text'); // Key words we want bolded - $highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT JOIN', 'ORDER BY', 'GROUP BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR', 'HAVING', 'OFFSET', 'NOT IN', 'IN', 'LIKE', 'NOT LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')'); + $highlight = array('SELECT', 'DISTINCT', 'FROM', 'WHERE', 'AND', 'LEFT JOIN', 'ORDER BY', 'GROUP BY', 'LIMIT', 'INSERT', 'INTO', 'VALUES', 'UPDATE', 'OR ', 'HAVING', 'OFFSET', 'NOT IN', 'IN', 'LIKE', 'NOT LIKE', 'COUNT', 'MAX', 'MIN', 'ON', 'AS', 'AVG', 'SUM', '(', ')'); $output = "\n\n"; - + foreach ($dbs as $db) { $output .= '<fieldset style="border:1px solid #0000FF;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; $output .= "\n"; - $output .= '<legend style="color:#0000FF;"> '.$this->CI->lang->line('profiler_database').': '.$db->database.' '.$this->CI->lang->line('profiler_queries').': '.count($this->CI->db->queries).' </legend>'; - $output .= "\n"; - $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n"; - + $output .= '<legend style="color:#0000FF;"> '.$this->CI->lang->line('profiler_database').': '.$db->database.' '.$this->CI->lang->line('profiler_queries').': '.count($db->queries).' </legend>'; + $output .= "\n"; + $output .= "\n\n<table style='width:100%;'>\n"; + if (count($db->queries) == 0) { - $output .= "<tr><td width='100%' style='color:#0000FF;font-weight:normal;background-color:#eee;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n"; + $output .= "<tr><td style='width:100%;color:#0000FF;font-weight:normal;background-color:#eee;padding:5px;'>".$this->CI->lang->line('profiler_no_queries')."</td></tr>\n"; } else - { + { foreach ($db->queries as $key => $val) - { + { $time = number_format($db->query_times[$key], 4); $val = highlight_code($val, ENT_QUOTES); - + foreach ($highlight as $bold) { - $val = str_replace($bold, '<strong>'.$bold.'</strong>', $val); + $val = str_replace($bold, '<strong>'.$bold.'</strong>', $val); } - - $output .= "<tr><td width='1%' valign='top' style='color:#990000;font-weight:normal;background-color:#ddd;'>".$time." </td><td style='color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n"; + + $output .= "<tr><td style='padding:5px; vertical-align: top;width:1%;color:#900;font-weight:normal;background-color:#ddd;'>".$time." </td><td style='padding:5px; color:#000;font-weight:normal;background-color:#ddd;'>".$val."</td></tr>\n"; } } - + $output .= "</table>\n"; $output .= "</fieldset>"; - + } - + return $output; } - + // -------------------------------------------------------------------- /** * Compile $_GET Data * - * @access private * @return string - */ - function _compile_get() - { + */ + protected function _compile_get() + { $output = "\n\n"; - $output .= '<fieldset style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= '<fieldset id="ci_profiler_get" style="border:1px solid #cd6e00;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; $output .= "\n"; $output .= '<legend style="color:#cd6e00;"> '.$this->CI->lang->line('profiler_get_data').' </legend>'; $output .= "\n"; - + if (count($_GET) == 0) { $output .= "<div style='color:#cd6e00;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_get')."</div>"; } else { - $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n"; - + $output .= "\n\n<table style='width:100%; border:none'>\n"; + foreach ($_GET as $key => $val) { if ( ! is_numeric($key)) { $key = "'".$key."'"; } - - $output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>$_GET[".$key."] </td><td width='50%' style='color:#cd6e00;font-weight:normal;background-color:#ddd;'>"; + + $output .= "<tr><td style='width:50%;color:#000;background-color:#ddd;padding:5px'>$_GET[".$key."] </td><td style='width:50%;padding:5px;color:#cd6e00;font-weight:normal;background-color:#ddd;'>"; if (is_array($val)) { $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>"; @@ -216,49 +257,48 @@ class CI_Profiler { } $output .= "</td></tr>\n"; } - + $output .= "</table>\n"; } $output .= "</fieldset>"; - return $output; + return $output; } - + // -------------------------------------------------------------------- - + /** * Compile $_POST Data * - * @access private * @return string - */ - function _compile_post() - { + */ + protected function _compile_post() + { $output = "\n\n"; - $output .= '<fieldset style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= '<fieldset id="ci_profiler_post" style="border:1px solid #009900;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; $output .= "\n"; $output .= '<legend style="color:#009900;"> '.$this->CI->lang->line('profiler_post_data').' </legend>'; $output .= "\n"; - + if (count($_POST) == 0) { $output .= "<div style='color:#009900;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_post')."</div>"; } else { - $output .= "\n\n<table cellpadding='4' cellspacing='1' border='0' width='100%'>\n"; - + $output .= "\n\n<table style='width:100%'>\n"; + foreach ($_POST as $key => $val) { if ( ! is_numeric($key)) { $key = "'".$key."'"; } - - $output .= "<tr><td width='50%' style='color:#000;background-color:#ddd;'>$_POST[".$key."] </td><td width='50%' style='color:#009900;font-weight:normal;background-color:#ddd;'>"; + + $output .= "<tr><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>$_POST[".$key."] </td><td style='width:50%;padding:5px;color:#009900;font-weight:normal;background-color:#ddd;'>"; if (is_array($val)) { - $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, true))) . "</pre>"; + $output .= "<pre>" . htmlspecialchars(stripslashes(print_r($val, TRUE))) . "</pre>"; } else { @@ -266,118 +306,188 @@ class CI_Profiler { } $output .= "</td></tr>\n"; } - + $output .= "</table>\n"; } $output .= "</fieldset>"; - return $output; + return $output; } - + // -------------------------------------------------------------------- - + /** * Show query string * - * @access private * @return string - */ - function _compile_uri_string() - { + */ + protected function _compile_uri_string() + { $output = "\n\n"; - $output .= '<fieldset style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= '<fieldset id="ci_profiler_uri_string" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; $output .= "\n"; $output .= '<legend style="color:#000;"> '.$this->CI->lang->line('profiler_uri_string').' </legend>'; $output .= "\n"; - + if ($this->CI->uri->uri_string == '') { $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_uri')."</div>"; } else { - $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>"; + $output .= "<div style='color:#000;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->uri->uri_string."</div>"; } - + $output .= "</fieldset>"; - return $output; + return $output; } // -------------------------------------------------------------------- - + /** * Show the controller and function that were called * - * @access private * @return string - */ - function _compile_controller_info() - { + */ + protected function _compile_controller_info() + { $output = "\n\n"; - $output .= '<fieldset style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= '<fieldset id="ci_profiler_controller_info" style="border:1px solid #995300;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; $output .= "\n"; $output .= '<legend style="color:#995300;"> '.$this->CI->lang->line('profiler_controller_info').' </legend>'; $output .= "\n"; - - $output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>"; - + $output .= "<div style='color:#995300;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->router->fetch_class()."/".$this->CI->router->fetch_method()."</div>"; + $output .= "</fieldset>"; - return $output; + return $output; } + // -------------------------------------------------------------------- - + /** * Compile memory usage * * Display total used memory * - * @access public * @return string */ - function _compile_memory_usage() + protected function _compile_memory_usage() { $output = "\n\n"; - $output .= '<fieldset style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= '<fieldset id="ci_profiler_memory_usage" style="border:1px solid #5a0099;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; $output .= "\n"; $output .= '<legend style="color:#5a0099;"> '.$this->CI->lang->line('profiler_memory_usage').' </legend>'; $output .= "\n"; - + if (function_exists('memory_get_usage') && ($usage = memory_get_usage()) != '') { $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".number_format($usage).' bytes</div>'; } else { - $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory_usage')."</div>"; + $output .= "<div style='color:#5a0099;font-weight:normal;padding:4px 0 4px 0'>".$this->CI->lang->line('profiler_no_memory_usage')."</div>"; + } + + $output .= "</fieldset>"; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile header information + * + * Lists HTTP headers + * + * @return string + */ + protected function _compile_http_headers() + { + $output = "\n\n"; + $output .= '<fieldset id="ci_profiler_http_headers" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= "\n"; + $output .= '<legend style="color:#000;"> '.$this->CI->lang->line('profiler_headers').' </legend>'; + $output .= "\n"; + + $output .= "\n\n<table style='width:100%'>\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) + { + $val = (isset($_SERVER[$header])) ? $_SERVER[$header] : ''; + $output .= "<tr><td style='vertical-align: top;width:50%;padding:5px;color:#900;background-color:#ddd;'>".$header." </td><td style='width:50%;padding:5px;color:#000;background-color:#ddd;'>".$val."</td></tr>\n"; } - + + $output .= "</table>\n"; + $output .= "</fieldset>"; + + return $output; + } + + // -------------------------------------------------------------------- + + /** + * Compile config information + * + * Lists developer config variables + * + * @return string + */ + protected function _compile_config() + { + $output = "\n\n"; + $output .= '<fieldset id="ci_profiler_config" style="border:1px solid #000;padding:6px 10px 10px 10px;margin:20px 0 20px 0;background-color:#eee">'; + $output .= "\n"; + $output .= '<legend style="color:#000;"> '.$this->CI->lang->line('profiler_config').' </legend>'; + $output .= "\n"; + + $output .= "\n\n<table style='width:100%'>\n"; + + foreach($this->CI->config->config as $config=>$val) + { + if (is_array($val)) + { + $val = print_r($val, TRUE); + } + + $output .= "<tr><td style='padding:5px; vertical-align: top;color:#900;background-color:#ddd;'>".$config." </td><td style='padding:5px; color:#000;background-color:#ddd;'>".htmlspecialchars($val)."</td></tr>\n"; + } + + $output .= "</table>\n"; $output .= "</fieldset>"; return $output; } // -------------------------------------------------------------------- - + /** * Run the Profiler * - * @access private * @return string - */ - function run() + */ + public function run() { $output = "<div id='codeigniter_profiler' style='clear:both;background-color:#fff;padding:10px;'>"; + $fields_displayed = 0; - $output .= $this->_compile_uri_string(); - $output .= $this->_compile_controller_info(); - $output .= $this->_compile_memory_usage(); - $output .= $this->_compile_benchmarks(); - $output .= $this->_compile_get(); - $output .= $this->_compile_post(); - $output .= $this->_compile_queries(); + foreach ($this->_available_sections as $section) + { + if ($this->_compile_{$section} !== FALSE) + { + $func = "_compile_{$section}"; + $output .= $this->{$func}(); + $fields_displayed++; + } + } + + if ($fields_displayed == 0) + { + $output .= '<p style="border:1px solid #5a0099;padding:10px;margin:20px 0;background-color:#eee">'.$this->CI->lang->line('profiler_no_profiles').'</p>'; + } $output .= '</div>'; diff --git a/system/libraries/Router.php b/system/libraries/Router.php deleted file mode 100644 index 7dbad0374..000000000 --- a/system/libraries/Router.php +++ /dev/null @@ -1,389 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * Router Class - * - * Parses URIs and determines routing - * - * @package CodeIgniter - * @subpackage Libraries - * @author ExpressionEngine Dev Team - * @category Libraries - * @link http://codeigniter.com/user_guide/general/routing.html - */ -class CI_Router { - - var $config; - var $routes = array(); - var $error_routes = array(); - var $class = ''; - var $method = 'index'; - var $directory = ''; - var $uri_protocol = 'auto'; - var $default_controller; - var $scaffolding_request = FALSE; // Must be set to FALSE - - /** - * Constructor - * - * Runs the route mapping function. - */ - function CI_Router() - { - $this->config =& load_class('Config'); - $this->uri =& load_class('URI'); - $this->_set_routing(); - log_message('debug', "Router Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Set the route mapping - * - * This function determines what should be served based on the URI request, - * as well as any "routes" that have been set in the routing config file. - * - * @access private - * @return void - */ - function _set_routing() - { - // Are query strings enabled in the config file? - // If so, we're done since segment based URIs are not used with query strings. - if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')])) - { - $this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')]))); - - if (isset($_GET[$this->config->item('function_trigger')])) - { - $this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')]))); - } - - return; - } - - // Load the routes.php file. - @include(APPPATH.'config/routes'.EXT); - $this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route; - unset($route); - - // Set the default controller so we can display it in the event - // the URI doesn't correlated to a valid controller. - $this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']); - - // Fetch the complete URI string - $this->uri->_fetch_uri_string(); - - // Is there a URI string? If not, the default controller specified in the "routes" file will be shown. - if ($this->uri->uri_string == '') - { - if ($this->default_controller === FALSE) - { - show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file."); - } - - if (strpos($this->default_controller, '/') !== FALSE) - { - $x = explode('/', $this->default_controller); - - $this->set_class(end($x)); - $this->set_method('index'); - $this->_set_request($x); - } - else - { - $this->set_class($this->default_controller); - $this->set_method('index'); - $this->_set_request(array($this->default_controller, 'index')); - } - - // re-index the routed segments array so it starts with 1 rather than 0 - $this->uri->_reindex_segments(); - - log_message('debug', "No URI present. Default controller set."); - return; - } - unset($this->routes['default_controller']); - - // Do we need to remove the URL suffix? - $this->uri->_remove_url_suffix(); - - // Compile the segments into an array - $this->uri->_explode_segments(); - - // Parse any custom routing that may exist - $this->_parse_routes(); - - // Re-index the segment array so that it starts with 1 rather than 0 - $this->uri->_reindex_segments(); - } - - // -------------------------------------------------------------------- - - /** - * Set the Route - * - * This function takes an array of URI segments as - * input, and sets the current class/method - * - * @access private - * @param array - * @param bool - * @return void - */ - function _set_request($segments = array()) - { - $segments = $this->_validate_request($segments); - - if (count($segments) == 0) - { - return; - } - - $this->set_class($segments[0]); - - if (isset($segments[1])) - { - // A scaffolding request. No funny business with the URL - if ($this->routes['scaffolding_trigger'] == $segments[1] AND $segments[1] != '_ci_scaffolding') - { - $this->scaffolding_request = TRUE; - unset($this->routes['scaffolding_trigger']); - } - else - { - // A standard method request - $this->set_method($segments[1]); - } - } - else - { - // This lets the "routed" segment array identify that the default - // index method is being used. - $segments[1] = 'index'; - } - - // Update our "routed" segment array to contain the segments. - // Note: If there is no custom routing, this array will be - // identical to $this->uri->segments - $this->uri->rsegments = $segments; - } - - // -------------------------------------------------------------------- - - /** - * Validates the supplied segments. Attempts to determine the path to - * the controller. - * - * @access private - * @param array - * @return array - */ - function _validate_request($segments) - { - // Does the requested controller exist in the root folder? - if (file_exists(APPPATH.'controllers/'.$segments[0].EXT)) - { - return $segments; - } - - // Is the controller in a sub-folder? - if (is_dir(APPPATH.'controllers/'.$segments[0])) - { - // Set the directory and remove it from the segment array - $this->set_directory($segments[0]); - $segments = array_slice($segments, 1); - - if (count($segments) > 0) - { - // Does the requested controller exist in the sub-folder? - if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT)) - { - show_404($this->fetch_directory().$segments[0]); - } - } - else - { - $this->set_class($this->default_controller); - $this->set_method('index'); - - // Does the default controller exist in the sub-folder? - if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT)) - { - $this->directory = ''; - return array(); - } - - } - - return $segments; - } - - // Can't find the requested controller... - show_404($segments[0]); - } - - // -------------------------------------------------------------------- - - /** - * Parse Routes - * - * This function matches any routes that may exist in - * the config/routes.php file against the URI to - * determine if the class/method need to be remapped. - * - * @access private - * @return void - */ - function _parse_routes() - { - // Do we even have any custom routing to deal with? - // There is a default scaffolding trigger, so we'll look just for 1 - if (count($this->routes) == 1) - { - $this->_set_request($this->uri->segments); - return; - } - - // Turn the segment array into a URI string - $uri = implode('/', $this->uri->segments); - - // Is there a literal match? If so we're done - if (isset($this->routes[$uri])) - { - $this->_set_request(explode('/', $this->routes[$uri])); - return; - } - - // Loop through the route array looking for wild-cards - foreach ($this->routes as $key => $val) - { - // Convert wild-cards to RegEx - $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key)); - - // Does the RegEx match? - if (preg_match('#^'.$key.'$#', $uri)) - { - // Do we have a back-reference? - if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE) - { - $val = preg_replace('#^'.$key.'$#', $val, $uri); - } - - $this->_set_request(explode('/', $val)); - return; - } - } - - // If we got this far it means we didn't encounter a - // matching route so we'll set the site default route - $this->_set_request($this->uri->segments); - } - - // -------------------------------------------------------------------- - - /** - * Set the class name - * - * @access public - * @param string - * @return void - */ - function set_class($class) - { - $this->class = str_replace(array('/', '.'), '', $class); - } - - // -------------------------------------------------------------------- - - /** - * Fetch the current class - * - * @access public - * @return string - */ - function fetch_class() - { - return $this->class; - } - - // -------------------------------------------------------------------- - - /** - * Set the method name - * - * @access public - * @param string - * @return void - */ - function set_method($method) - { - $this->method = $method; - } - - // -------------------------------------------------------------------- - - /** - * Fetch the current method - * - * @access public - * @return string - */ - function fetch_method() - { - if ($this->method == $this->fetch_class()) - { - return 'index'; - } - - return $this->method; - } - - // -------------------------------------------------------------------- - - /** - * Set the directory name - * - * @access public - * @param string - * @return void - */ - function set_directory($dir) - { - $this->directory = str_replace(array('/', '.'), '', $dir).'/'; - } - - // -------------------------------------------------------------------- - - /** - * Fetch the sub-directory (if any) that contains the requested controller class - * - * @access public - * @return string - */ - function fetch_directory() - { - return $this->directory; - } - -} -// END Router Class - -/* End of file Router.php */ -/* Location: ./system/libraries/Router.php */
\ No newline at end of file diff --git a/system/libraries/Security.php b/system/libraries/Security.php new file mode 100755 index 000000000..ba64c7326 --- /dev/null +++ b/system/libraries/Security.php @@ -0,0 +1,737 @@ +<?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) 2008 - 2011, EllisLab, Inc. + * @license http://codeigniter.com/user_guide/license.html + * @link http://codeigniter.com + * @since Version 1.0 + * @filesource + */ + +// ------------------------------------------------------------------------ + +/** + * Security Class + * + * @package CodeIgniter + * @subpackage Libraries + * @category Security + * @author ExpressionEngine Dev Team + * @link http://codeigniter.com/user_guide/libraries/sessions.html + */ +class CI_Security { + + public $xss_hash = ''; + public $csrf_hash = ''; + public $csrf_expire = 7200; // Two hours (in seconds) + public $csrf_token_name = 'ci_csrf_token'; + public $csrf_cookie_name = 'ci_csrf_token'; + + /* never allowed, string replacement */ + public $never_allowed_str = array( + 'document.cookie' => '[removed]', + 'document.write' => '[removed]', + '.parentNode' => '[removed]', + '.innerHTML' => '[removed]', + 'window.location' => '[removed]', + '-moz-binding' => '[removed]', + '<!--' => '<!--', + '-->' => '-->', + '<![CDATA[' => '<![CDATA[' + ); + /* never allowed, regex replacement */ + public $never_allowed_regex = array( + "javascript\s*:" => '[removed]', + "expression\s*(\(|&\#40;)" => '[removed]', // CSS and IE + "vbscript\s*:" => '[removed]', // IE, surprise! + "Redirect\s+302" => '[removed]' + ); + + public function __construct() + { + $this->csrf_token_name = (config_item('csrf_token_name')) ? config_item('csrf_token_name') : 'csrf_token_name'; + $this->csrf_cookie_name = (config_item('csrf_cookie_name')) ? config_item('csrf_cookie_name') : 'csrf_cookie_name'; + $this->csrf_expire = (config_item('csrf_expire')) ? config_item('csrf_expire') : 7200; + + // 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; + + // Set the CSRF hash + $this->_csrf_set_hash(); + + log_message('debug', "Security Class Initialized"); + } + + // -------------------------------------------------------------------- + + /** + * Verify Cross Site Request Forgery Protection + * + * @access public + * @return null + */ + public function csrf_verify() + { + // If no POST data exists we will set the CSRF cookie + if (count($_POST) == 0) + { + return $this->csrf_set_cookie(); + } + + // Do the tokens exist in both the _POST and _COOKIE arrays? + if ( ! isset($_POST[$this->csrf_token_name]) OR ! isset($_COOKIE[$this->csrf_cookie_name])) + { + $this->csrf_show_error(); + } + + // Do the tokens match? + if ($_POST[$this->csrf_token_name] != $_COOKIE[$this->csrf_cookie_name]) + { + $this->csrf_show_error(); + } + + // We kill this since we're done and we don't want to polute the _POST array + unset($_POST[$this->csrf_token_name]); + + // Nothing should last forever + unset($_COOKIE[$this->csrf_cookie_name]); + $this->_csrf_set_hash(); + $this->csrf_set_cookie(); + + log_message('debug', "CSRF token verified "); + } + + // -------------------------------------------------------------------- + + /** + * Set Cross Site Request Forgery Protection Cookie + * + * @access public + * @return null + */ + public function csrf_set_cookie() + { + $expire = time() + $this->csrf_expire; + + setcookie($this->csrf_cookie_name, $this->csrf_hash, $expire, config_item('cookie_path'), config_item('cookie_domain'), 0); + + log_message('debug', "CRSF cookie Set"); + } + + // -------------------------------------------------------------------- + + /** + * Set Cross Site Request Forgery Protection Cookie + * + * @access private + * @return null + */ + private function _csrf_set_hash() + { + if ($this->csrf_hash == '') + { + // If the cookie exists we will use it's value. We don't necessarily want to regenerate it with + // each page load since a page could contain embedded sub-pages causing this feature to fail + if (isset($_COOKIE[$this->csrf_cookie_name]) AND $_COOKIE[$this->csrf_cookie_name] != '') + { + $this->csrf_hash = $_COOKIE[$this->csrf_cookie_name]; + } + else + { + $this->csrf_hash = md5(uniqid(rand(), TRUE)); + } + } + + return $this->csrf_hash; + } + + // -------------------------------------------------------------------- + + /** + * Show CSRF Error + * + * @access public + * @return null + */ + public function csrf_show_error() + { + show_error('The action you have requested is not allowed.'); + } + + // -------------------------------------------------------------------- + + /** + * XSS Clean + * + * Sanitizes data so that Cross Site Scripting Hacks can be + * prevented. This function does a fair amount of work but + * it is extremely thorough, designed to prevent even the + * most obscure XSS attempts. Nothing is ever 100% foolproof, + * of course, but I haven't been able to get anything passed + * the filter. + * + * Note: This function should only be used to deal with data + * upon submission. It's not something that should + * be used for general runtime processing. + * + * This function was based in part on some code and ideas I + * got from Bitflux: http://channel.bitflux.ch/wiki/XSS_Prevention + * + * To help develop this script I used this great list of + * vulnerabilities along with a few other hacks I've + * harvested from examining vulnerabilities in other programs: + * http://ha.ckers.org/xss.html + * + * @access public + * @param mixed string or array + * @return string + */ + public function xss_clean($str, $is_image = FALSE) + { + /* + * Is the string an array? + * + */ + if (is_array($str)) + { + while (list($key) = each($str)) + { + $str[$key] = $this->xss_clean($str[$key]); + } + + return $str; + } + + /* + * Remove Invisible Characters + */ + $str = remove_invisible_characters($str); + + /* + * Protect GET variables in URLs + */ + + // 901119URL5918AMP18930PROTECT8198 + + $str = preg_replace('|\&([a-z\_0-9\-]+)\=([a-z\_0-9\-]+)|i', $this->xss_hash()."\\1=\\2", $str); + + /* + * Validate standard character entities + * + * Add a semicolon if missing. We do this to enable + * the conversion of entities to ASCII later. + * + */ + $str = preg_replace('#(&\#?[0-9a-z]{2,})([\x00-\x20])*;?#i', "\\1;\\2", $str); + + /* + * Validate UTF16 two byte encoding (x00) + * + * Just as above, adds a semicolon if missing. + * + */ + $str = preg_replace('#(&\#x?)([0-9A-F]+);?#i',"\\1\\2;",$str); + + /* + * Un-Protect GET variables in URLs + */ + $str = str_replace($this->xss_hash(), '&', $str); + + /* + * URL Decode + * + * Just in case stuff like this is submitted: + * + * <a href="http://%77%77%77%2E%67%6F%6F%67%6C%65%2E%63%6F%6D">Google</a> + * + * Note: Use rawurldecode() so it does not remove plus signs + * + */ + $str = rawurldecode($str); + + /* + * Convert character entities to ASCII + * + * This permits our tests below to work reliably. + * We only convert entities that are within tags since + * these are the ones that will pose security problems. + * + */ + + $str = preg_replace_callback("/[a-z]+=([\'\"]).*?\\1/si", array($this, '_convert_attribute'), $str); + + $str = preg_replace_callback("/<\w+.*?(?=>|<|$)/si", array($this, '_decode_entity'), $str); + + /* + * Remove Invisible Characters Again! + */ + $str = remove_invisible_characters($str); + + /* + * Convert all tabs to spaces + * + * This prevents strings like this: ja vascript + * NOTE: we deal with spaces between characters later. + * NOTE: preg_replace was found to be amazingly slow here on large blocks of data, + * so we use str_replace. + * + */ + + if (strpos($str, "\t") !== FALSE) + { + $str = str_replace("\t", ' ', $str); + } + + /* + * Capture converted string for later comparison + */ + $converted_string = $str; + + /* + * Not Allowed Under Any Conditions + */ + + foreach ($this->never_allowed_str as $key => $val) + { + $str = str_replace($key, $val, $str); + } + + foreach ($this->never_allowed_regex as $key => $val) + { + $str = preg_replace("#".$key."#i", $val, $str); + } + + /* + * Makes PHP tags safe + * + * Note: XML tags are inadvertently replaced too: + * + * <?xml + * + * But it doesn't seem to pose a problem. + * + */ + if ($is_image === TRUE) + { + // Images have a tendency to have the PHP short opening and closing tags every so often + // so we skip those and only do the long opening tags. + $str = preg_replace('/<\?(php)/i', "<?\\1", $str); + } + else + { + $str = str_replace(array('<?', '?'.'>'), array('<?', '?>'), $str); + } + + /* + * Compact any exploded words + * + * This corrects words like: j a v a s c r i p t + * These words are compacted back to their correct state. + * + */ + $words = array('javascript', 'expression', 'vbscript', 'script', 'applet', 'alert', 'document', 'write', 'cookie', 'window'); + foreach ($words as $word) + { + $temp = ''; + + for ($i = 0, $wordlen = strlen($word); $i < $wordlen; $i++) + { + $temp .= substr($word, $i, 1)."\s*"; + } + + // We only want to do this when it is followed by a non-word character + // That way valid stuff like "dealer to" does not become "dealerto" + $str = preg_replace_callback('#('.substr($temp, 0, -3).')(\W)#is', array($this, '_compact_exploded_words'), $str); + } + + /* + * Remove disallowed Javascript in links or img tags + * We used to do some version comparisons and use of stripos for PHP5, but it is dog slow compared + * to these simplified non-capturing preg_match(), especially if the pattern exists in the string + */ + do + { + $original = $str; + + if (preg_match("/<a/i", $str)) + { + $str = preg_replace_callback("#<a\s+([^>]*?)(>|$)#si", array($this, '_js_link_removal'), $str); + } + + if (preg_match("/<img/i", $str)) + { + $str = preg_replace_callback("#<img\s+([^>]*?)(\s?/?>|$)#si", array($this, '_js_img_removal'), $str); + } + + if (preg_match("/script/i", $str) OR preg_match("/xss/i", $str)) + { + $str = preg_replace("#<(/*)(script|xss)(.*?)\>#si", '[removed]', $str); + } + } + while($original != $str); + + unset($original); + + /* + * Remove JavaScript Event Handlers + * + * Note: This code is a little blunt. It removes + * the event handler and anything up to the closing >, + * but it's unlikely to be a problem. + * + */ + $event_handlers = array('[^a-z_\-]on\w*','xmlns'); + + if ($is_image === TRUE) + { + /* + * Adobe Photoshop puts XML metadata into JFIF images, including namespacing, + * so we have to allow this for images. -Paul + */ + unset($event_handlers[array_search('xmlns', $event_handlers)]); + } + + $str = preg_replace("#<([^><]+?)(".implode('|', $event_handlers).")(\s*=\s*[^><]*)([><]*)#i", "<\\1\\4", $str); + + /* + * Sanitize naughty HTML elements + * + * If a tag containing any of the words in the list + * below is found, the tag gets converted to entities. + * + * So this: <blink> + * Becomes: <blink> + * + */ + $naughty = 'alert|applet|audio|basefont|base|behavior|bgsound|blink|body|embed|expression|form|frameset|frame|head|html|ilayer|iframe|input|isindex|layer|link|meta|object|plaintext|style|script|textarea|title|video|xml|xss'; + $str = preg_replace_callback('#<(/*\s*)('.$naughty.')([^><]*)([><]*)#is', array($this, '_sanitize_naughty_html'), $str); + + /* + * Sanitize naughty scripting elements + * + * Similar to above, only instead of looking for + * tags it looks for PHP and JavaScript commands + * that are disallowed. Rather than removing the + * code, it simply converts the parenthesis to entities + * rendering the code un-executable. + * + * For example: eval('some code') + * Becomes: eval('some code') + * + */ + $str = preg_replace('#(alert|cmd|passthru|eval|exec|expression|system|fopen|fsockopen|file|file_get_contents|readfile|unlink)(\s*)\((.*?)\)#si', "\\1\\2(\\3)", $str); + + /* + * Final clean up + * + * This adds a bit of extra precaution in case + * something got through the above filters + * + */ + foreach ($this->never_allowed_str as $key => $val) + { + $str = str_replace($key, $val, $str); + } + + foreach ($this->never_allowed_regex as $key => $val) + { + $str = preg_replace("#".$key."#i", $val, $str); + } + + /* + * Images are Handled in a Special Way + * - Essentially, we want to know that after all of the character conversion is done whether + * any unwanted, likely XSS, code was found. If not, we return TRUE, as the image is clean. + * However, if the string post-conversion does not matched the string post-removal of XSS, + * then it fails, as there was unwanted XSS code found and removed/changed during processing. + */ + + if ($is_image === TRUE) + { + if ($str == $converted_string) + { + return TRUE; + } + else + { + return FALSE; + } + } + + log_message('debug', "XSS Filtering completed"); + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Random Hash for protecting URLs + * + * @access public + * @return string + */ + public function xss_hash() + { + if ($this->xss_hash == '') + { + if (phpversion() >= 4.2) + mt_srand(); + else + mt_srand(hexdec(substr(md5(microtime()), -8)) & 0x7fffffff); + + $this->xss_hash = md5(time() + mt_rand(0, 1999999999)); + } + + return $this->xss_hash; + } + + // -------------------------------------------------------------------- + + /** + * Compact Exploded Words + * + * Callback function for xss_clean() to remove whitespace from + * things like j a v a s c r i p t + * + * @access private + * @param type + * @return type + */ + private function _compact_exploded_words($matches) + { + return preg_replace('/\s+/s', '', $matches[1]).$matches[2]; + } + + // -------------------------------------------------------------------- + + /** + * Sanitize Naughty HTML + * + * Callback function for xss_clean() to remove naughty HTML elements + * + * @access private + * @param array + * @return string + */ + private function _sanitize_naughty_html($matches) + { + // encode opening brace + $str = '<'.$matches[1].$matches[2].$matches[3]; + + // encode captured opening or closing brace to prevent recursive vectors + $str .= str_replace(array('>', '<'), array('>', '<'), $matches[4]); + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * JS Link Removal + * + * Callback function for xss_clean() to sanitize links + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on link-heavy strings + * + * @access private + * @param array + * @return string + */ + private function _js_link_removal($match) + { + $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); + return str_replace($match[1], preg_replace("#href=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]); + } + + /** + * JS Image Removal + * + * Callback function for xss_clean() to sanitize image tags + * This limits the PCRE backtracks, making it more performance friendly + * and prevents PREG_BACKTRACK_LIMIT_ERROR from being triggered in + * PHP 5.2+ on image tag heavy strings + * + * @access private + * @param array + * @return string + */ + private function _js_img_removal($match) + { + $attributes = $this->_filter_attributes(str_replace(array('<', '>'), '', $match[1])); + return str_replace($match[1], preg_replace("#src=.*?(alert\(|alert&\#40;|javascript\:|charset\=|window\.|document\.|\.cookie|<script|<xss|base64\s*,)#si", "", $attributes), $match[0]); + } + + // -------------------------------------------------------------------- + + /** + * Attribute Conversion + * + * Used as a callback for XSS Clean + * + * @access private + * @param array + * @return string + */ + private function _convert_attribute($match) + { + return str_replace(array('>', '<', '\\'), array('>', '<', '\\\\'), $match[0]); + } + + // -------------------------------------------------------------------- + + /** + * Filter Attributes + * + * Filters tag attributes for consistency and safety + * + * @access private + * @param string + * @return string + */ + private function _filter_attributes($str) + { + $out = ''; + + if (preg_match_all('#\s*[a-z\-]+\s*=\s*(\042|\047)([^\\1]*?)\\1#is', $str, $matches)) + { + foreach ($matches[0] as $match) + { + $out .= preg_replace("#/\*.*?\*/#s", '', $match); + } + } + + return $out; + } + + // -------------------------------------------------------------------- + + /** + * HTML Entity Decode Callback + * + * Used as a callback for XSS Clean + * + * @access private + * @param array + * @return string + */ + private function _decode_entity($match) + { + return $this->entity_decode($match[0], strtoupper(config_item('charset'))); + } + + // -------------------------------------------------------------------- + + /** + * HTML Entities Decode + * + * This function is a replacement for html_entity_decode() + * + * In some versions of PHP the native function does not work + * when UTF-8 is the specified character set, so this gives us + * a work-around. More info here: + * http://bugs.php.net/bug.php?id=25670 + * + * NOTE: html_entity_decode() has a bug in some PHP versions when UTF-8 is the + * character set, and the PHP developers said they were not back porting the + * fix to versions other than PHP 5.x. + * + * @access public + * @param string + * @param string + * @return string + */ + public function entity_decode($str, $charset='UTF-8') + { + if (stristr($str, '&') === FALSE) return $str; + + // The reason we are not using html_entity_decode() by itself is because + // while it is not technically correct to leave out the semicolon + // at the end of an entity most browsers will still interpret the entity + // correctly. html_entity_decode() does not convert entities without + // semicolons, so we are left with our own little solution here. Bummer. + + if (function_exists('html_entity_decode') && (strtolower($charset) != 'utf-8' OR is_php('5.0.0'))) + { + $str = html_entity_decode($str, ENT_COMPAT, $charset); + $str = preg_replace('~&#x(0*[0-9a-f]{2,5})~ei', 'chr(hexdec("\\1"))', $str); + return preg_replace('~&#([0-9]{2,4})~e', 'chr(\\1)', $str); + } + + // Numeric Entities + $str = preg_replace('~&#x(0*[0-9a-f]{2,5});{0,1}~ei', 'chr(hexdec("\\1"))', $str); + $str = preg_replace('~&#([0-9]{2,4});{0,1}~e', 'chr(\\1)', $str); + + // Literal Entities - Slightly slow so we do another check + if (stristr($str, '&') === FALSE) + { + $str = strtr($str, array_flip(get_html_translation_table(HTML_ENTITIES))); + } + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Filename Security + * + * @access public + * @param string + * @return string + */ + public function sanitize_filename($str, $relative_path = FALSE) + { + $bad = array( + "../", + "<!--", + "-->", + "<", + ">", + "'", + '"', + '&', + '$', + '#', + '{', + '}', + '[', + ']', + '=', + ';', + '?', + "%20", + "%22", + "%3c", // < + "%253c", // < + "%3e", // > + "%0e", // > + "%28", // ( + "%29", // ) + "%2528", // ( + "%26", // & + "%24", // $ + "%3f", // ? + "%3b", // ; + "%3d" // = + ); + + if ( ! $relative_path) + { + $bad[] = './'; + $bad[] = '/'; + } + + return stripslashes(str_replace($bad, '', $str)); + } + +} +// END Security Class + +/* End of file Security.php */ +/* Location: ./system/libraries/Security.php */
\ No newline at end of file diff --git a/system/libraries/Session.php b/system/libraries/Session.php index bd9426818..53ff4f5d3 100644..100755 --- a/system/libraries/Session.php +++ b/system/libraries/Session.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -30,6 +30,7 @@ class CI_Session { var $sess_use_database = FALSE; var $sess_table_name = ''; var $sess_expiration = 7200; + var $sess_expire_on_close = FALSE; var $sess_match_ip = FALSE; var $sess_match_useragent = TRUE; var $sess_cookie_name = 'ci_session'; @@ -38,7 +39,7 @@ class CI_Session { var $cookie_domain = ''; var $sess_time_to_update = 300; var $encryption_key = ''; - var $flashdata_key = 'flash'; + var $flashdata_key = 'flash'; var $time_reference = 'time'; var $gc_probability = 5; var $userdata = array(); @@ -51,7 +52,7 @@ class CI_Session { * The constructor runs the session routines automatically * whenever the class is instantiated. */ - function CI_Session($params = array()) + public function __construct($params = array()) { log_message('debug', "Session Class Initialized"); @@ -60,11 +61,16 @@ class CI_Session { // Set all the session preferences, which can either be set // manually via the $params array above or via the config file - foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key) + foreach (array('sess_encrypt_cookie', 'sess_use_database', 'sess_table_name', 'sess_expiration', 'sess_expire_on_close', 'sess_match_ip', 'sess_match_useragent', 'sess_cookie_name', 'cookie_path', 'cookie_domain', 'sess_time_to_update', 'time_reference', 'cookie_prefix', 'encryption_key') as $key) { $this->$key = (isset($params[$key])) ? $params[$key] : $this->CI->config->item($key); } + if ($this->encryption_key == '') + { + show_error('In order to use the Session class you are required to set an encryption key in your config file.'); + } + // Load the string helper so we can use the strip_slashes() function $this->CI->load->helper('string'); @@ -90,7 +96,7 @@ class CI_Session { { $this->sess_expiration = (60*60*24*365*2); } - + // Set the cookie name $this->sess_cookie_name = $this->cookie_prefix.$this->sess_cookie_name; @@ -106,10 +112,10 @@ class CI_Session { } // Delete 'old' flashdata (from last request) - $this->_flashdata_sweep(); + $this->_flashdata_sweep(); // Mark all new flashdata as old (data will be deleted before next request) - $this->_flashdata_mark(); + $this->_flashdata_mark(); // Delete expired sessions if necessary $this->_sess_gc(); @@ -307,9 +313,9 @@ class CI_Session { $sessid .= $this->CI->input->ip_address(); $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), + 'session_id' => md5(uniqid($sessid, TRUE)), + 'ip_address' => $this->CI->input->ip_address(), + 'user_agent' => substr($this->CI->input->user_agent(), 0, 50), 'last_activity' => $this->now ); @@ -651,11 +657,13 @@ class CI_Session { $cookie_data = $cookie_data.md5($cookie_data.$this->encryption_key); } + $expire = ($this->sess_expire_on_close === TRUE) ? 0 : $this->sess_expiration + time(); + // Set the cookie setcookie( $this->sess_cookie_name, $cookie_data, - $this->sess_expiration + time(), + $expire, $this->cookie_path, $this->cookie_domain, 0 @@ -680,12 +688,18 @@ class CI_Session { { foreach ($data as $key => $val) { - $data[$key] = str_replace('\\', '{{slash}}', $val); + if (is_string($val)) + { + $data[$key] = str_replace('\\', '{{slash}}', $val); + } } } else { - $data = str_replace('\\', '{{slash}}', $data); + if (is_string($data)) + { + $data = str_replace('\\', '{{slash}}', $data); + } } return serialize($data); @@ -711,13 +725,16 @@ class CI_Session { { foreach ($data as $key => $val) { - $data[$key] = str_replace('{{slash}}', '\\', $val); + if (is_string($val)) + { + $data[$key] = str_replace('{{slash}}', '\\', $val); + } } return $data; } - return str_replace('{{slash}}', '\\', $data); + return (is_string($data)) ? str_replace('{{slash}}', '\\', $data) : $data; } // -------------------------------------------------------------------- diff --git a/system/libraries/Sha1.php b/system/libraries/Sha1.php index f9611a8a5..ad747a001 100644..100755 --- a/system/libraries/Sha1.php +++ b/system/libraries/Sha1.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -44,7 +44,7 @@ */ class CI_SHA { - function CI_SHA() + public function __construct() { log_message('debug', "SHA1 Class Initialized"); } @@ -55,7 +55,7 @@ class CI_SHA { * @access public * @param string * @return string - */ + */ function generate($str) { $n = ((strlen($str) + 8) >> 6) + 1; @@ -117,7 +117,7 @@ class CI_SHA { return $this->_hex($a).$this->_hex($b).$this->_hex($c).$this->_hex($d).$this->_hex($e); } - + // -------------------------------------------------------------------- /** @@ -126,7 +126,7 @@ class CI_SHA { * @access private * @param string * @return string - */ + */ function _hex($str) { $str = dechex($str); @@ -138,7 +138,7 @@ class CI_SHA { return $str; } - + // -------------------------------------------------------------------- /** @@ -146,7 +146,7 @@ class CI_SHA { * * @access private * @return string - */ + */ function _ft($t, $b, $c, $d) { if ($t < 20) @@ -166,7 +166,7 @@ class CI_SHA { * * @access private * @return string - */ + */ function _kt($t) { if ($t < 20) @@ -186,7 +186,7 @@ class CI_SHA { return -899497514; } } - + // -------------------------------------------------------------------- /** @@ -194,7 +194,7 @@ class CI_SHA { * * @access private * @return string - */ + */ function _safe_add($x, $y) { $lsw = ($x & 0xFFFF) + ($y & 0xFFFF); @@ -202,7 +202,7 @@ class CI_SHA { return ($msw << 16) | ($lsw & 0xFFFF); } - + // -------------------------------------------------------------------- /** @@ -210,7 +210,7 @@ class CI_SHA { * * @access private * @return integer - */ + */ function _rol($num, $cnt) { return ($num << $cnt) | $this->_zero_fill($num, 32 - $cnt); @@ -223,7 +223,7 @@ class CI_SHA { * * @access private * @return string - */ + */ function _zero_fill($a, $b) { $bin = decbin($a); diff --git a/system/libraries/Table.php b/system/libraries/Table.php index a990d406c..485541630 100644..100755 --- a/system/libraries/Table.php +++ b/system/libraries/Table.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.3.1 @@ -30,14 +30,14 @@ class CI_Table { var $rows = array(); var $heading = array(); - var $auto_heading = TRUE; - var $caption = NULL; - var $template = NULL; + var $auto_heading = TRUE; + var $caption = NULL; + var $template = NULL; var $newline = "\n"; var $empty_cells = ""; - - - function CI_Table() + var $function = FALSE; + + public function __construct() { log_message('debug', "Table Class Initialized"); } @@ -57,7 +57,7 @@ class CI_Table { { return FALSE; } - + $this->template = $template; } @@ -75,7 +75,7 @@ class CI_Table { function set_heading() { $args = func_get_args(); - $this->heading = (is_array($args[0])) ? $args[0] : $args; + $this->heading = $this->_prep_args($args); } // -------------------------------------------------------------------- @@ -97,21 +97,21 @@ class CI_Table { { return FALSE; } - - // Turn off the auto-heading feature since it's doubtful we + + // Turn off the auto-heading feature since it's doubtful we // will want headings from a one-dimensional array $this->auto_heading = FALSE; - + if ($col_limit == 0) { return $array; } - + $new = array(); while(count($array) > 0) - { + { $temp = array_splice($array, 0, $col_limit); - + if (count($temp) < $col_limit) { for ($i = count($temp); $i < $col_limit; $i++) @@ -119,10 +119,10 @@ class CI_Table { $temp[] = ' '; } } - + $new[] = $temp; } - + return $new; } @@ -141,7 +141,7 @@ class CI_Table { { $this->empty_cells = $value; } - + // -------------------------------------------------------------------- /** @@ -156,7 +156,55 @@ class CI_Table { function add_row() { $args = func_get_args(); - $this->rows[] = (is_array($args[0])) ? $args[0] : $args; + $this->rows[] = $this->_prep_args($args); + } + + // -------------------------------------------------------------------- + + /** + * Prep Args + * + * Ensures a standard associative array format for all cell data + * + * @access public + * @param type + * @return type + */ + function _prep_args($args) + { + // If there is no $args[0], skip this and treat as an associative array + // This can happen if there is only a single key, for example this is passed to table->generate + // array(array('foo'=>'bar')) + if (isset($args[0]) AND (count($args) == 1 && is_array($args[0]))) + { + // args sent as indexed array + if ( ! isset($args[0]['data'])) + { + foreach ($args[0] as $key => $val) + { + if (is_array($val) && isset($val['data'])) + { + $args[$key] = $val; + } + else + { + $args[$key] = array('data' => $val); + } + } + } + } + else + { + foreach ($args as $key => $val) + { + if ( ! is_array($val)) + { + $args[$key] = array('data' => $val); + } + } + } + + return $args; } // -------------------------------------------------------------------- @@ -171,7 +219,7 @@ class CI_Table { function set_caption($caption) { $this->caption = $caption; - } + } // -------------------------------------------------------------------- @@ -198,21 +246,23 @@ class CI_Table { $this->_set_from_array($table_data, $set_heading); } } - + // Is there anything to display? No? Smite them! if (count($this->heading) == 0 AND count($this->rows) == 0) { return 'Undefined table data'; } - + // Compile and validate the template date $this->_compile_template(); - - + + // set a custom cell manipulation function to a locally scoped variable so its callable + $function = $this->function; + // Build the table! - + $out = $this->template['table_open']; - $out .= $this->newline; + $out .= $this->newline; // Add any caption here if ($this->caption) @@ -225,23 +275,40 @@ class CI_Table { // Is there a table heading to display? if (count($this->heading) > 0) { + $out .= $this->template['thead_open']; + $out .= $this->newline; $out .= $this->template['heading_row_start']; - $out .= $this->newline; + $out .= $this->newline; foreach($this->heading as $heading) { - $out .= $this->template['heading_cell_start']; - $out .= $heading; + $temp = $this->template['heading_cell_start']; + + foreach ($heading as $key => $val) + { + if ($key != 'data') + { + $temp = str_replace('<th', "<th $key='$val'", $temp); + } + } + + $out .= $temp; + $out .= isset($heading['data']) ? $heading['data'] : ''; $out .= $this->template['heading_cell_end']; } $out .= $this->template['heading_row_end']; - $out .= $this->newline; + $out .= $this->newline; + $out .= $this->template['thead_close']; + $out .= $this->newline; } // Build the table rows if (count($this->rows) > 0) { + $out .= $this->template['tbody_open']; + $out .= $this->newline; + $i = 1; foreach($this->rows as $row) { @@ -249,39 +316,60 @@ class CI_Table { { break; } - + // We use modulus to alternate the row colors $name = (fmod($i++, 2)) ? '' : 'alt_'; - + $out .= $this->template['row_'.$name.'start']; - $out .= $this->newline; - + $out .= $this->newline; + foreach($row as $cell) { - $out .= $this->template['cell_'.$name.'start']; - - if ($cell === "") + $temp = $this->template['cell_'.$name.'start']; + + foreach ($cell as $key => $val) + { + if ($key != 'data') + { + $temp = str_replace('<td', "<td $key='$val'", $temp); + } + } + + $cell = isset($cell['data']) ? $cell['data'] : ''; + $out .= $temp; + + if ($cell === "" OR $cell === NULL) { $out .= $this->empty_cells; } else { - $out .= $cell; + if ($function !== FALSE && is_callable($function)) + { + $out .= call_user_func($function, $cell); + } + else + { + $out .= $cell; + } } - + $out .= $this->template['cell_'.$name.'end']; } - + $out .= $this->template['row_'.$name.'end']; - $out .= $this->newline; + $out .= $this->newline; } + + $out .= $this->template['tbody_close']; + $out .= $this->newline; } $out .= $this->template['table_close']; - + return $out; } - + // -------------------------------------------------------------------- /** @@ -294,9 +382,9 @@ class CI_Table { { $this->rows = array(); $this->heading = array(); - $this->auto_heading = TRUE; + $this->auto_heading = TRUE; } - + // -------------------------------------------------------------------- /** @@ -312,7 +400,7 @@ class CI_Table { { return FALSE; } - + // First generate the headings from the table column names if (count($this->heading) == 0) { @@ -320,17 +408,17 @@ class CI_Table { { return FALSE; } - - $this->heading = $query->list_fields(); + + $this->heading = $this->_prep_args($query->list_fields()); } - + // Next blast through the result array and build out the rows - + if ($query->num_rows() > 0) { foreach ($query->result_array() as $row) { - $this->rows[] = $row; + $this->rows[] = $this->_prep_args($row); } } } @@ -350,26 +438,20 @@ class CI_Table { { return FALSE; } - + $i = 0; foreach ($data as $row) { - if ( ! is_array($row)) - { - $this->rows[] = $data; - break; - } - // If a heading hasn't already been set we'll use the first row of the array as the heading if ($i == 0 AND count($data) > 1 AND count($this->heading) == 0 AND $set_heading == TRUE) { - $this->heading = $row; + $this->heading = $this->_prep_args($row); } else { - $this->rows[] = $row; + $this->rows[] = $this->_prep_args($row); } - + $i++; } } @@ -382,24 +464,24 @@ class CI_Table { * @access private * @return void */ - function _compile_template() - { - if ($this->template == NULL) - { - $this->template = $this->_default_template(); - return; - } - + function _compile_template() + { + if ($this->template == NULL) + { + $this->template = $this->_default_template(); + return; + } + $this->temp = $this->_default_template(); - foreach (array('table_open','heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val) + foreach (array('table_open', 'thead_open', 'thead_close', 'heading_row_start', 'heading_row_end', 'heading_cell_start', 'heading_cell_end', 'tbody_open', 'tbody_close', 'row_start', 'row_end', 'cell_start', 'cell_end', 'row_alt_start', 'row_alt_end', 'cell_alt_start', 'cell_alt_end', 'table_close') as $val) { if ( ! isset($this->template[$val])) { $this->template[$val] = $this->temp[$val]; } - } - } - + } + } + // -------------------------------------------------------------------- /** @@ -411,27 +493,33 @@ class CI_Table { function _default_template() { return array ( - 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', + 'table_open' => '<table border="0" cellpadding="4" cellspacing="0">', + + 'thead_open' => '<thead>', + 'thead_close' => '</thead>', - 'heading_row_start' => '<tr>', - 'heading_row_end' => '</tr>', + 'heading_row_start' => '<tr>', + 'heading_row_end' => '</tr>', 'heading_cell_start' => '<th>', 'heading_cell_end' => '</th>', - 'row_start' => '<tr>', - 'row_end' => '</tr>', + 'tbody_open' => '<tbody>', + 'tbody_close' => '</tbody>', + + 'row_start' => '<tr>', + 'row_end' => '</tr>', 'cell_start' => '<td>', 'cell_end' => '</td>', - 'row_alt_start' => '<tr>', - 'row_alt_end' => '</tr>', + 'row_alt_start' => '<tr>', + 'row_alt_end' => '</tr>', 'cell_alt_start' => '<td>', 'cell_alt_end' => '</td>', - 'table_close' => '</table>' - ); + 'table_close' => '</table>' + ); } - + } diff --git a/system/libraries/Trackback.php b/system/libraries/Trackback.php index 9b1737c5f..e29b35c7a 100644..100755 --- a/system/libraries/Trackback.php +++ b/system/libraries/Trackback.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -27,7 +27,7 @@ * @link http://codeigniter.com/user_guide/libraries/trackback.html */ class CI_Trackback { - + var $time_format = 'local'; var $charset = 'UTF-8'; var $data = array('url' => '', 'title' => '', 'excerpt' => '', 'blog_name' => '', 'charset' => ''); @@ -40,28 +40,28 @@ class CI_Trackback { * * @access public */ - function CI_Trackback() + public function __construct() { log_message('debug', "Trackback Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Send Trackback * * @access public * @param array * @return bool - */ + */ function send($tb_data) - { + { if ( ! is_array($tb_data)) { $this->set_error('The send() method must be passed an array'); return FALSE; } - + // Pre-process the Trackback Data foreach (array('url', 'title', 'excerpt', 'blog_name', 'ping_url') as $item) { @@ -70,14 +70,14 @@ class CI_Trackback { $this->set_error('Required item missing: '.$item); return FALSE; } - + switch ($item) { case 'ping_url' : $$item = $this->extract_urls($tb_data[$item]); break; case 'excerpt' : $$item = $this->limit_characters($this->convert_xml(strip_tags(stripslashes($tb_data[$item])))); break; - case 'url' : $$item = str_replace('-', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item])))); + case 'url' : $$item = str_replace('-', '-', $this->convert_xml(strip_tags(stripslashes($tb_data[$item])))); break; default : $$item = $this->convert_xml(strip_tags(stripslashes($tb_data[$item]))); break; @@ -103,9 +103,9 @@ class CI_Trackback { // Build the Trackback data string $charset = ( ! isset($tb_data['charset'])) ? $this->charset : $tb_data['charset']; - + $data = "url=".rawurlencode($url)."&title=".rawurlencode($title)."&blog_name=".rawurlencode($blog_name)."&excerpt=".rawurlencode($excerpt)."&charset=".rawurlencode($charset); - + // Send Trackback(s) $return = TRUE; if (count($ping_url) > 0) @@ -116,27 +116,27 @@ class CI_Trackback { { $return = FALSE; } - } + } } return $return; } - + // -------------------------------------------------------------------- - + /** * Receive Trackback Data * * This function simply validates the incoming TB data. - * It returns false on failure and true on success. + * It returns FALSE on failure and TRUE on success. * If the data is valid it is set to the $this->data array * so that it can be inserted into a database. * * @access public * @return bool - */ + */ function receive() - { + { foreach (array('url', 'title', 'blog_name', 'excerpt') as $val) { if ( ! isset($_POST[$val]) OR $_POST[$val] == '') @@ -144,29 +144,29 @@ class CI_Trackback { $this->set_error('The following required POST variable is missing: '.$val); return FALSE; } - + $this->data['charset'] = ( ! isset($_POST['charset'])) ? 'auto' : strtoupper(trim($_POST['charset'])); - + if ($val != 'url' && function_exists('mb_convert_encoding')) { $_POST[$val] = mb_convert_encoding($_POST[$val], $this->charset, $this->data['charset']); } - + $_POST[$val] = ($val != 'url') ? $this->convert_xml(strip_tags($_POST[$val])) : strip_tags($_POST[$val]); - + if ($val == 'excerpt') { $_POST['excerpt'] = $this->limit_characters($_POST['excerpt']); } - + $this->data[$val] = $_POST[$val]; } return TRUE; - } - + } + // -------------------------------------------------------------------- - + /** * Send Trackback Error Message * @@ -177,15 +177,15 @@ class CI_Trackback { * @access public * @param string * @return void - */ + */ function send_error($message = 'Incomplete Information') { echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>1</error>\n<message>".$message."</message>\n</response>"; exit; } - + // -------------------------------------------------------------------- - + /** * Send Trackback Success Message * @@ -194,44 +194,44 @@ class CI_Trackback { * * @access public * @return void - */ + */ function send_success() { echo "<?xml version=\"1.0\" encoding=\"utf-8\"?".">\n<response>\n<error>0</error>\n</response>"; exit; } - + // -------------------------------------------------------------------- - + /** * Fetch a particular item * * @access public * @param string * @return string - */ + */ function data($item) { return ( ! isset($this->data[$item])) ? '' : $this->data[$item]; } // -------------------------------------------------------------------- - + /** * Process Trackback * * Opens a socket connection and passes the data to - * the server. Returns true on success, false on failure + * the server. Returns TRUE on success, FALSE on failure * * @access public * @param string * @param string * @return bool - */ + */ function process($url, $data) { $target = parse_url($url); - + // Open the socket if ( ! $fp = @fsockopen($target['host'], 80)) { @@ -241,7 +241,7 @@ class CI_Trackback { // Build the path $ppath = ( ! isset($target['path'])) ? $url : $target['path']; - + $path = (isset($target['query']) && $target['query'] != "") ? $ppath.'?'.$target['query'] : $ppath; // Add the Trackback ID to the data string @@ -260,31 +260,32 @@ class CI_Trackback { // Was it successful? $this->response = ""; - + while( ! feof($fp)) { $this->response .= fgets($fp, 128); } @fclose($fp); - + + if (stristr($this->response, '<error>0</error>') === FALSE) { $message = 'An unknown error was encountered'; - + if (preg_match("/<message>(.*?)<\/message>/is", $this->response, $match)) { $message = trim($match['1']); } - + $this->set_error($message); return FALSE; } return TRUE; } - + // -------------------------------------------------------------------- - + /** * Extract Trackback URLs * @@ -295,34 +296,34 @@ class CI_Trackback { * @access public * @param string * @return string - */ + */ function extract_urls($urls) - { + { // Remove the pesky white space and replace with a comma. $urls = preg_replace("/\s*(\S+)\s*/", "\\1,", $urls); - + // If they use commas get rid of the doubles. $urls = str_replace(",,", ",", $urls); - + // Remove any comma that might be at the end if (substr($urls, -1) == ",") { $urls = substr($urls, 0, -1); } - + // Break into an array via commas $urls = preg_split('/[,]/', $urls); - + // Removes duplicates $urls = array_unique($urls); - + array_walk($urls, array($this, 'validate_url')); - + return $urls; } - + // -------------------------------------------------------------------- - + /** * Validate URL * @@ -331,7 +332,7 @@ class CI_Trackback { * @access public * @param string * @return string - */ + */ function validate_url($url) { $url = trim($url); @@ -341,58 +342,58 @@ class CI_Trackback { $url = "http://".$url; } } - + // -------------------------------------------------------------------- - + /** * Find the Trackback URL's ID * * @access public * @param string * @return string - */ + */ function get_id($url) - { + { $tb_id = ""; - - if (strstr($url, '?')) + + if (strpos($url, '?') !== FALSE) { $tb_array = explode('/', $url); $tb_end = $tb_array[count($tb_array)-1]; - + if ( ! is_numeric($tb_end)) { $tb_end = $tb_array[count($tb_array)-2]; } - + $tb_array = explode('=', $tb_end); $tb_id = $tb_array[count($tb_array)-1]; } else { $url = rtrim($url, '/'); - + $tb_array = explode('/', $url); $tb_id = $tb_array[count($tb_array)-1]; - + if ( ! is_numeric($tb_id)) { $tb_id = $tb_array[count($tb_array)-2]; } - } - + } + if ( ! preg_match ("/^([0-9]+)$/", $tb_id)) { - return false; + return FALSE; } else { return $tb_id; - } + } } - + // -------------------------------------------------------------------- - + /** * Convert Reserved XML characters to Entities * @@ -403,22 +404,22 @@ class CI_Trackback { function convert_xml($str) { $temp = '__TEMP_AMPERSANDS__'; - + $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str); $str = preg_replace("/&(\w+);/", "$temp\\1;", $str); - + $str = str_replace(array("&","<",">","\"", "'", "-"), - array("&", "<", ">", """, "'", "-"), - $str); - + array("&", "<", ">", """, "'", "-"), + $str); + $str = preg_replace("/$temp(\d+);/","&#\\1;",$str); $str = preg_replace("/$temp(\w+);/","&\\1;", $str); - + return $str; - } - + } + // -------------------------------------------------------------------- - + /** * Character limiter * @@ -438,25 +439,25 @@ class CI_Trackback { } $str = preg_replace("/\s+/", ' ', str_replace(array("\r\n", "\r", "\n"), ' ', $str)); - + if (strlen($str) <= $n) { return $str; } - + $out = ""; foreach (explode(' ', trim($str)) as $val) { - $out .= $val.' '; + $out .= $val.' '; if (strlen($out) >= $n) { return trim($out).$end_char; - } + } } } - + // -------------------------------------------------------------------- - + /** * High ASCII to Entities * @@ -469,58 +470,58 @@ class CI_Trackback { */ function convert_ascii($str) { - $count = 1; - $out = ''; - $temp = array(); - - for ($i = 0, $s = strlen($str); $i < $s; $i++) - { - $ordinal = ord($str[$i]); - - if ($ordinal < 128) - { - $out .= $str[$i]; - } - else - { - if (count($temp) == 0) - { - $count = ($ordinal < 224) ? 2 : 3; - } - - $temp[] = $ordinal; - - if (count($temp) == $count) - { - $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); - - $out .= '&#'.$number.';'; - $count = 1; - $temp = array(); - } - } - } - - return $out; + $count = 1; + $out = ''; + $temp = array(); + + for ($i = 0, $s = strlen($str); $i < $s; $i++) + { + $ordinal = ord($str[$i]); + + if ($ordinal < 128) + { + $out .= $str[$i]; + } + else + { + if (count($temp) == 0) + { + $count = ($ordinal < 224) ? 2 : 3; + } + + $temp[] = $ordinal; + + if (count($temp) == $count) + { + $number = ($count == 3) ? (($temp['0'] % 16) * 4096) + (($temp['1'] % 64) * 64) + ($temp['2'] % 64) : (($temp['0'] % 32) * 64) + ($temp['1'] % 64); + + $out .= '&#'.$number.';'; + $count = 1; + $temp = array(); + } + } + } + + return $out; } - + // -------------------------------------------------------------------- - + /** * Set error message * * @access public * @param string * @return void - */ + */ function set_error($msg) { log_message('error', $msg); $this->error_msg[] = $msg; } - + // -------------------------------------------------------------------- - + /** * Show error messages * @@ -528,15 +529,15 @@ class CI_Trackback { * @param string * @param string * @return string - */ + */ function display_errors($open = '<p>', $close = '</p>') - { + { $str = ''; foreach ($this->error_msg as $val) { $str .= $open.$val.$close; } - + return $str; } diff --git a/system/libraries/Typography.php b/system/libraries/Typography.php index 0f0a8b7a2..734cec104 100644..100755 --- a/system/libraries/Typography.php +++ b/system/libraries/Typography.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -28,39 +28,31 @@ class CI_Typography { // Block level elements that should not be wrapped inside <p> tags var $block_elements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul'; - + // Elements that should not have <p> and <br /> tags within them. var $skip_elements = 'p|pre|ol|ul|dl|object|table|h\d'; - + // Tags we want the parser to completely ignore when splitting the string. var $inline_elements = 'a|abbr|acronym|b|bdo|big|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|q|samp|select|small|span|strong|sub|sup|textarea|tt|var'; - + // array of block level elements that require inner content to be within another block level element var $inner_block_required = array('blockquote'); - + // the last block element parsed var $last_block_element = ''; - + // whether or not to protect quotes within { curly braces } var $protect_braced_quotes = FALSE; - - /** - * Nothing to do here... - * - */ - function CI_Typography() - { - } /** * Auto Typography * * This function converts text, making it typographically correct: - * - Converts double spaces into paragraphs. - * - Converts single line breaks into <br /> tags - * - Converts single and double quotes into correctly facing curly quote entities. - * - Converts three dots into ellipsis. - * - Converts double dashes into em-dashes. + * - Converts double spaces into paragraphs. + * - Converts single line breaks into <br /> tags + * - Converts single and double quotes into correctly facing curly quote entities. + * - Converts three dots into ellipsis. + * - Converts double dashes into em-dashes. * - Converts two spaces into entities * * @access public @@ -78,15 +70,15 @@ class CI_Typography { // Standardize Newlines to make matching easier if (strpos($str, "\r") !== FALSE) { - $str = str_replace(array("\r\n", "\r"), "\n", $str); + $str = str_replace(array("\r\n", "\r"), "\n", $str); } - + // Reduce line breaks. If there are more than two consecutive linebreaks // we'll compress them down to a maximum of two since there's no benefit to more. if ($reduce_linebreaks === TRUE) { $str = preg_replace("/\n\n+/", "\n\n", $str); - } + } // HTML comment tags don't conform to patterns of normal tags, so pull them out separately, only if needed $html_comments = array(); @@ -101,50 +93,50 @@ class CI_Typography { } } } - + // match and yank <pre> tags if they exist. It's cheaper to do this separately since most content will // not contain <pre> tags, and it keeps the PCRE patterns below simpler and faster if (strpos($str, '<pre') !== FALSE) { $str = preg_replace_callback("#<pre.*?>.*?</pre>#si", array($this, '_protect_characters'), $str); } - + // Convert quotes within tags to temporary markers. $str = preg_replace_callback("#<.+?>#si", array($this, '_protect_characters'), $str); // Do the same with braces if necessary if ($this->protect_braced_quotes === TRUE) { - $str = preg_replace_callback("#\{.+?\}#si", array($this, '_protect_characters'), $str); + $str = preg_replace_callback("#\{.+?\}#si", array($this, '_protect_characters'), $str); } - - // Convert "ignore" tags to temporary marker. The parser splits out the string at every tag - // it encounters. Certain inline tags, like image tags, links, span tags, etc. will be + + // Convert "ignore" tags to temporary marker. The parser splits out the string at every tag + // it encounters. Certain inline tags, like image tags, links, span tags, etc. will be // adversely affected if they are split out so we'll convert the opening bracket < temporarily to: {@TAG} $str = preg_replace("#<(/*)(".$this->inline_elements.")([ >])#i", "{@TAG}\\1\\2\\3", $str); // Split the string at every tag. This expression creates an array with this prototype: - // - // [array] - // { - // [0] = <opening tag> - // [1] = Content... - // [2] = <closing tag> - // Etc... - // } + // + // [array] + // { + // [0] = <opening tag> + // [1] = Content... + // [2] = <closing tag> + // Etc... + // } $chunks = preg_split('/(<(?:[^<>]+(?:"[^"]*"|\'[^\']*\')?)+>)/', $str, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY); - - // Build our finalized string. We cycle through the array, skipping tags, and processing the contained text + + // Build our finalized string. We cycle through the array, skipping tags, and processing the contained text $str = ''; $process = TRUE; $paragraph = FALSE; $current_chunk = 0; $total_chunks = count($chunks); - + foreach ($chunks as $chunk) - { + { $current_chunk++; - + // Are we dealing with a tag? If so, we'll skip the processing for this cycle. // Well also set the "process" flag which allows us to skip <pre> tags and a few other things. if (preg_match("#<(/*)(".$this->block_elements.").*?>#", $chunk, $match)) @@ -153,7 +145,7 @@ class CI_Typography { { $process = ($match[1] == '/') ? TRUE : FALSE; } - + if ($match[1] == '') { $this->last_block_element = $match[2]; @@ -162,32 +154,32 @@ class CI_Typography { $str .= $chunk; continue; } - + if ($process == FALSE) { $str .= $chunk; continue; } - + // Force a newline to make sure end tags get processed by _format_newlines() if ($current_chunk == $total_chunks) { - $chunk .= "\n"; + $chunk .= "\n"; } - + // Convert Newlines into <p> and <br /> tags $str .= $this->_format_newlines($chunk); } - + // No opening block level tag? Add it if needed. if ( ! preg_match("/^\s*<(?:".$this->block_elements.")/i", $str)) { $str = preg_replace("/^(.*?)<(".$this->block_elements.")/i", '<p>$1</p><$2', $str); } - + // Convert quotes, elipsis, em-dashes, non-breaking spaces, and ampersands $str = $this->format_characters($str); - + // restore HTML comments for ($i = 0, $total = count($html_comments); $i < $total; $i++) { @@ -196,18 +188,18 @@ class CI_Typography { // if '<p>{@HC1}' then replace <p>{@HC1}</p> with the comment, else replace only {@HC1} with the comment $str = preg_replace('#(?(?=<p>\{@HC'.$i.'\})<p>\{@HC'.$i.'\}(\s*</p>)|\{@HC'.$i.'\})#s', $html_comments[$i], $str); } - + // Final clean up $table = array( - + // If the user submitted their own paragraph tags within the text // we will retain them instead of using our tags. - '/(<p[^>*?]>)<p>/' => '$1', // <?php BBEdit syntax coloring bug fix - + '/(<p[^>*?]>)<p>/' => '$1', // <?php BBEdit syntax coloring bug fix + // Reduce multiple instances of opening/closing paragraph tags to a single one '#(</p>)+#' => '</p>', '/(<p>\W*<p>)+/' => '<p>', - + // Clean up stray paragraph tags that appear before block level elements '#<p></p><('.$this->block_elements.')#' => '<$1', @@ -219,10 +211,19 @@ class CI_Typography { '/\{@DQ\}/' => '"', '/\{@SQ\}/' => "'", '/\{@DD\}/' => '--', - '/\{@NBS\}/' => ' ' + '/\{@NBS\}/' => ' ', + // An unintended consequence of the _format_newlines function is that + // some of the newlines get truncated, resulting in <p> tags + // starting immediately after <block> tags on the same line. + // This forces a newline after such occurrences, which looks much nicer. + "/><p>\n/" => ">\n<p>", + + // Similarly, there might be cases where a closing </block> will follow + // a closing </p> tag, so we'll correct it by adding a newline in between + "#</p></#" => "</p>\n</" ); - + // Do we need to reduce empty lines? if ($reduce_linebreaks === TRUE) { @@ -234,13 +235,13 @@ class CI_Typography { // otherwise most browsers won't treat them as true paragraphs $table['#<p></p>#'] = '<p> </p>'; } - + return preg_replace(array_keys($table), $table, $str); } - + // -------------------------------------------------------------------- - + /** * Format Characters * @@ -255,10 +256,10 @@ class CI_Typography { function format_characters($str) { static $table; - + if ( ! isset($table)) { - $table = array( + $table = array( // nested smart quotes, opening and closing // note that rules for grammar (English) allow only for two levels deep // and that single quotes are _supposed_ to always be on the outside @@ -304,7 +305,7 @@ class CI_Typography { return preg_replace(array_keys($table), $table, $str); } - + // -------------------------------------------------------------------- /** @@ -315,47 +316,50 @@ class CI_Typography { * @access public * @param string * @return string - */ + */ function _format_newlines($str) { if ($str == '') { return $str; } - + if (strpos($str, "\n") === FALSE && ! in_array($this->last_block_element, $this->inner_block_required)) { return $str; } - + // Convert two consecutive newlines to paragraphs $str = str_replace("\n\n", "</p>\n\n<p>", $str); - + // Convert single spaces to <br /> tags $str = preg_replace("/([^\n])(\n)([^\n])/", "\\1<br />\\2\\3", $str); - + // Wrap the whole enchilada in enclosing paragraphs if ($str != "\n") { - $str = '<p>'.$str.'</p>'; + // We trim off the right-side new line so that the closing </p> tag + // will be positioned immediately following the string, matching + // the behavior of the opening <p> tag + $str = '<p>'.rtrim($str).'</p>'; } // Remove empty paragraphs if they are on the first line, as this // is a potential unintended consequence of the previous code $str = preg_replace("/<p><\/p>(.*)/", "\\1", $str, 1); - + return $str; } - + // ------------------------------------------------------------------------ - + /** * Protect Characters * * Protects special characters from being formatted later * We don't want quotes converted within tags so we'll temporarily convert them to {@DQ} and {@SQ} - * and we don't want double dashes converted to emdash entities, so they are marked with {@DD} - * likewise double spaces are converted to {@NBS} to prevent entity conversion + * and we don't want double dashes converted to emdash entities, so they are marked with {@DD} + * likewise double spaces are converted to {@NBS} to prevent entity conversion * * @access public * @param array @@ -367,19 +371,19 @@ class CI_Typography { } // -------------------------------------------------------------------- - + /** * Convert newlines to HTML line breaks except within PRE tags * * @access public * @param string * @return string - */ + */ function nl2br_except_pre($str) { $ex = explode("pre>",$str); $ct = count($ex); - + $newstr = ""; for ($i = 0; $i < $ct; $i++) { @@ -391,14 +395,14 @@ class CI_Typography { { $newstr .= $ex[$i]; } - + if ($ct - 1 != $i) $newstr .= "pre>"; } - + return $newstr; } - + } // END Typography Class diff --git a/system/libraries/URI.php b/system/libraries/URI.php deleted file mode 100644 index 23efb38c1..000000000 --- a/system/libraries/URI.php +++ /dev/null @@ -1,586 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * URI Class - * - * Parses URIs and determines routing - * - * @package CodeIgniter - * @subpackage Libraries - * @category URI - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/uri.html - */ -class CI_URI { - - var $keyval = array(); - var $uri_string; - var $segments = array(); - var $rsegments = array(); - - /** - * Constructor - * - * Simply globalizes the $RTR object. The front - * loads the Router class early on so it's not available - * normally as other classes are. - * - * @access public - */ - function CI_URI() - { - $this->config =& load_class('Config'); - log_message('debug', "URI Class Initialized"); - } - - - // -------------------------------------------------------------------- - - /** - * Get the URI String - * - * @access private - * @return string - */ - function _fetch_uri_string() - { - if (strtoupper($this->config->item('uri_protocol')) == 'AUTO') - { - // If the URL has a question mark then it's simplest to just - // build the URI string from the zero index of the $_GET array. - // This avoids having to deal with $_SERVER variables, which - // can be unreliable in some environments - if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '') - { - $this->uri_string = key($_GET); - return; - } - - // Is there a PATH_INFO variable? - // Note: some servers seem to have trouble with getenv() so we'll test it two ways - $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO'); - if (trim($path, '/') != '' && $path != "/".SELF) - { - $this->uri_string = $path; - return; - } - - // No PATH_INFO?... What about QUERY_STRING? - $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING'); - if (trim($path, '/') != '') - { - $this->uri_string = $path; - return; - } - - // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists? - $path = str_replace($_SERVER['SCRIPT_NAME'], '', (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO')); - if (trim($path, '/') != '' && $path != "/".SELF) - { - // remove path and script information so we have good URI data - $this->uri_string = $path; - return; - } - - // We've exhausted all our options... - $this->uri_string = ''; - } - else - { - $uri = strtoupper($this->config->item('uri_protocol')); - - if ($uri == 'REQUEST_URI') - { - $this->uri_string = $this->_parse_request_uri(); - return; - } - - $this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri); - } - - // If the URI contains only a slash we'll kill it - if ($this->uri_string == '/') - { - $this->uri_string = ''; - } - } - - // -------------------------------------------------------------------- - - /** - * Parse the REQUEST_URI - * - * Due to the way REQUEST_URI works it usually contains path info - * that makes it unusable as URI data. We'll trim off the unnecessary - * data, hopefully arriving at a valid URI that we can use. - * - * @access private - * @return string - */ - function _parse_request_uri() - { - if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '') - { - return ''; - } - - $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI'])); - - if ($request_uri == '' OR $request_uri == SELF) - { - return ''; - } - - $fc_path = FCPATH.SELF; - if (strpos($request_uri, '?') !== FALSE) - { - $fc_path .= '?'; - } - - $parsed_uri = explode("/", $request_uri); - - $i = 0; - foreach(explode("/", $fc_path) as $segment) - { - if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i]) - { - $i++; - } - } - - $parsed_uri = implode("/", array_slice($parsed_uri, $i)); - - if ($parsed_uri != '') - { - $parsed_uri = '/'.$parsed_uri; - } - - return $parsed_uri; - } - - // -------------------------------------------------------------------- - - /** - * Filter segments for malicious characters - * - * @access private - * @param string - * @return string - */ - function _filter_uri($str) - { - if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE) - { - // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards - // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern - if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str)) - { - show_error('The URI you submitted has disallowed characters.', 400); - } - } - - // Convert programatic characters to entities - $bad = array('$', '(', ')', '%28', '%29'); - $good = array('$', '(', ')', '(', ')'); - - return str_replace($bad, $good, $str); - } - - // -------------------------------------------------------------------- - - /** - * Remove the suffix from the URL if needed - * - * @access private - * @return void - */ - function _remove_url_suffix() - { - if ($this->config->item('url_suffix') != "") - { - $this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string); - } - } - - // -------------------------------------------------------------------- - - /** - * Explode the URI Segments. The individual segments will - * be stored in the $this->segments array. - * - * @access private - * @return void - */ - function _explode_segments() - { - foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val) - { - // Filter segments for security - $val = trim($this->_filter_uri($val)); - - if ($val != '') - { - $this->segments[] = $val; - } - } - } - - // -------------------------------------------------------------------- - /** - * Re-index Segments - * - * This function re-indexes the $this->segment array so that it - * starts at 1 rather than 0. Doing so makes it simpler to - * use functions like $this->uri->segment(n) since there is - * a 1:1 relationship between the segment array and the actual segments. - * - * @access private - * @return void - */ - function _reindex_segments() - { - array_unshift($this->segments, NULL); - array_unshift($this->rsegments, NULL); - unset($this->segments[0]); - unset($this->rsegments[0]); - } - - // -------------------------------------------------------------------- - - /** - * Fetch a URI Segment - * - * This function returns the URI segment based on the number provided. - * - * @access public - * @param integer - * @param bool - * @return string - */ - function segment($n, $no_result = FALSE) - { - return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n]; - } - - // -------------------------------------------------------------------- - - /** - * Fetch a URI "routed" Segment - * - * This function returns the re-routed URI segment (assuming routing rules are used) - * based on the number provided. If there is no routing this function returns the - * same result as $this->segment() - * - * @access public - * @param integer - * @param bool - * @return string - */ - function rsegment($n, $no_result = FALSE) - { - return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n]; - } - - // -------------------------------------------------------------------- - - /** - * Generate a key value pair from the URI string - * - * This function generates and associative array of URI data starting - * at the supplied segment. For example, if this is your URI: - * - * example.com/user/search/name/joe/location/UK/gender/male - * - * You can use this function to generate an array with this prototype: - * - * array ( - * name => joe - * location => UK - * gender => male - * ) - * - * @access public - * @param integer the starting segment number - * @param array an array of default values - * @return array - */ - function uri_to_assoc($n = 3, $default = array()) - { - return $this->_uri_to_assoc($n, $default, 'segment'); - } - /** - * Identical to above only it uses the re-routed segment array - * - */ - function ruri_to_assoc($n = 3, $default = array()) - { - return $this->_uri_to_assoc($n, $default, 'rsegment'); - } - - // -------------------------------------------------------------------- - - /** - * Generate a key value pair from the URI string or Re-routed URI string - * - * @access private - * @param integer the starting segment number - * @param array an array of default values - * @param string which array we should use - * @return array - */ - function _uri_to_assoc($n = 3, $default = array(), $which = 'segment') - { - if ($which == 'segment') - { - $total_segments = 'total_segments'; - $segment_array = 'segment_array'; - } - else - { - $total_segments = 'total_rsegments'; - $segment_array = 'rsegment_array'; - } - - if ( ! is_numeric($n)) - { - return $default; - } - - if (isset($this->keyval[$n])) - { - return $this->keyval[$n]; - } - - if ($this->$total_segments() < $n) - { - if (count($default) == 0) - { - return array(); - } - - $retval = array(); - foreach ($default as $val) - { - $retval[$val] = FALSE; - } - return $retval; - } - - $segments = array_slice($this->$segment_array(), ($n - 1)); - - $i = 0; - $lastval = ''; - $retval = array(); - foreach ($segments as $seg) - { - if ($i % 2) - { - $retval[$lastval] = $seg; - } - else - { - $retval[$seg] = FALSE; - $lastval = $seg; - } - - $i++; - } - - if (count($default) > 0) - { - foreach ($default as $val) - { - if ( ! array_key_exists($val, $retval)) - { - $retval[$val] = FALSE; - } - } - } - - // Cache the array for reuse - $this->keyval[$n] = $retval; - return $retval; - } - - // -------------------------------------------------------------------- - - /** - * Generate a URI string from an associative array - * - * - * @access public - * @param array an associative array of key/values - * @return array - */ - function assoc_to_uri($array) - { - $temp = array(); - foreach ((array)$array as $key => $val) - { - $temp[] = $key; - $temp[] = $val; - } - - return implode('/', $temp); - } - - // -------------------------------------------------------------------- - - /** - * Fetch a URI Segment and add a trailing slash - * - * @access public - * @param integer - * @param string - * @return string - */ - function slash_segment($n, $where = 'trailing') - { - return $this->_slash_segment($n, $where, 'segment'); - } - - // -------------------------------------------------------------------- - - /** - * Fetch a URI Segment and add a trailing slash - * - * @access public - * @param integer - * @param string - * @return string - */ - function slash_rsegment($n, $where = 'trailing') - { - return $this->_slash_segment($n, $where, 'rsegment'); - } - - // -------------------------------------------------------------------- - - /** - * Fetch a URI Segment and add a trailing slash - helper function - * - * @access private - * @param integer - * @param string - * @param string - * @return string - */ - function _slash_segment($n, $where = 'trailing', $which = 'segment') - { - if ($where == 'trailing') - { - $trailing = '/'; - $leading = ''; - } - elseif ($where == 'leading') - { - $leading = '/'; - $trailing = ''; - } - else - { - $leading = '/'; - $trailing = '/'; - } - return $leading.$this->$which($n).$trailing; - } - - // -------------------------------------------------------------------- - - /** - * Segment Array - * - * @access public - * @return array - */ - function segment_array() - { - return $this->segments; - } - - // -------------------------------------------------------------------- - - /** - * Routed Segment Array - * - * @access public - * @return array - */ - function rsegment_array() - { - return $this->rsegments; - } - - // -------------------------------------------------------------------- - - /** - * Total number of segments - * - * @access public - * @return integer - */ - function total_segments() - { - return count($this->segments); - } - - // -------------------------------------------------------------------- - - /** - * Total number of routed segments - * - * @access public - * @return integer - */ - function total_rsegments() - { - return count($this->rsegments); - } - - // -------------------------------------------------------------------- - - /** - * Fetch the entire URI string - * - * @access public - * @return string - */ - function uri_string() - { - return $this->uri_string; - } - - - // -------------------------------------------------------------------- - - /** - * Fetch the entire Re-routed URI string - * - * @access public - * @return string - */ - function ruri_string() - { - return '/'.implode('/', $this->rsegment_array()).'/'; - } - -} -// END URI Class - -/* End of file URI.php */ -/* Location: ./system/libraries/URI.php */
\ No newline at end of file diff --git a/system/libraries/Unit_test.php b/system/libraries/Unit_test.php index 29aeaae90..5bd7e801a 100644..100755 --- a/system/libraries/Unit_test.php +++ b/system/libraries/Unit_test.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.3.1 @@ -28,19 +28,50 @@ */ class CI_Unit_test { - var $active = TRUE; - var $results = array(); - var $strict = FALSE; - var $_template = NULL; - var $_template_rows = NULL; + var $active = TRUE; + var $results = array(); + var $strict = FALSE; + var $_template = NULL; + var $_template_rows = NULL; + var $_test_items_visible = array(); - function CI_Unit_test() + public function __construct() { + // These are the default items visible when a test is run. + $this->_test_items_visible = array ( + 'test_name', + 'test_datatype', + 'res_datatype', + 'result', + 'file', + 'line', + 'notes' + ); + log_message('debug', "Unit Testing Class Initialized"); - } + } // -------------------------------------------------------------------- - + + /** + * Run the tests + * + * Runs the supplied tests + * + * @access public + * @param array + * @return void + */ + function set_test_items($items = array()) + { + if ( ! empty($items) AND is_array($items)) + { + $this->_test_items_visible = $items; + } + } + + // -------------------------------------------------------------------- + /** * Run the tests * @@ -51,48 +82,49 @@ class CI_Unit_test { * @param mixed * @param string * @return string - */ - function run($test, $expected = TRUE, $test_name = 'undefined') + */ + function run($test, $expected = TRUE, $test_name = 'undefined', $notes = '') { if ($this->active == FALSE) { return FALSE; } - - if (in_array($expected, array('is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE)) + + if (in_array($expected, array('is_object', 'is_string', 'is_bool', 'is_true', 'is_false', 'is_int', 'is_numeric', 'is_float', 'is_double', 'is_array', 'is_null'), TRUE)) { $expected = str_replace('is_float', 'is_double', $expected); - $result = ($expected($test)) ? TRUE : FALSE; + $result = ($expected($test)) ? TRUE : FALSE; $extype = str_replace(array('true', 'false'), 'bool', str_replace('is_', '', $expected)); } else { if ($this->strict == TRUE) - $result = ($test === $expected) ? TRUE : FALSE; + $result = ($test === $expected) ? TRUE : FALSE; else - $result = ($test == $expected) ? TRUE : FALSE; - + $result = ($test == $expected) ? TRUE : FALSE; + $extype = gettype($expected); } - + $back = $this->_backtrace(); - + $report[] = array ( 'test_name' => $test_name, 'test_datatype' => gettype($test), 'res_datatype' => $extype, 'result' => ($result === TRUE) ? 'passed' : 'failed', 'file' => $back['file'], - 'line' => $back['line'] + 'line' => $back['line'], + 'notes' => $notes ); - $this->results[] = $report; - + $this->results[] = $report; + return($this->report($this->result($report))); } // -------------------------------------------------------------------- - + /** * Generate a report * @@ -120,7 +152,6 @@ class CI_Unit_test { foreach ($res as $key => $val) { - if ($key == $CI->lang->line('ut_result')) { if ($val == $CI->lang->line('ut_passed')) @@ -144,9 +175,9 @@ class CI_Unit_test { return $r; } - + // -------------------------------------------------------------------- - + /** * Use strict comparison * @@ -160,9 +191,9 @@ class CI_Unit_test { { $this->strict = ($state == FALSE) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Make Unit testing active * @@ -176,9 +207,9 @@ class CI_Unit_test { { $this->active = ($state == FALSE) ? FALSE : TRUE; } - + // -------------------------------------------------------------------- - + /** * Result Array * @@ -188,21 +219,26 @@ class CI_Unit_test { * @return array */ function result($results = array()) - { + { $CI =& get_instance(); $CI->load->language('unit_test'); - + if (count($results) == 0) { $results = $this->results; } - + $retval = array(); foreach ($results as $result) { $temp = array(); foreach ($result as $key => $val) { + if ( ! in_array($key, $this->_test_items_visible)) + { + continue; + } + if (is_array($val)) { foreach ($val as $k => $v) @@ -210,8 +246,8 @@ class CI_Unit_test { if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$v)))) { $v = $line; - } - $temp[$CI->lang->line('ut_'.$k)] = $v; + } + $temp[$CI->lang->line('ut_'.$k)] = $v; } } else @@ -219,19 +255,19 @@ class CI_Unit_test { if (FALSE !== ($line = $CI->lang->line(strtolower('ut_'.$val)))) { $val = $line; - } + } $temp[$CI->lang->line('ut_'.$key)] = $val; } } - + $retval[] = $temp; } - + return $retval; } - + // -------------------------------------------------------------------- - + /** * Set the template * @@ -240,14 +276,14 @@ class CI_Unit_test { * @access public * @param string * @return void - */ + */ function set_template($template) { $this->_template = $template; } - + // -------------------------------------------------------------------- - + /** * Generate a backtrace * @@ -261,17 +297,17 @@ class CI_Unit_test { if (function_exists('debug_backtrace')) { $back = debug_backtrace(); - + $file = ( ! isset($back['1']['file'])) ? '' : $back['1']['file']; $line = ( ! isset($back['1']['line'])) ? '' : $back['1']['line']; - + return array('file' => $file, 'line' => $line); } return array('file' => 'Unknown', 'line' => 'Unknown'); } // -------------------------------------------------------------------- - + /** * Get Default Template * @@ -279,17 +315,17 @@ class CI_Unit_test { * @return string */ function _default_template() - { + { $this->_template = "\n".'<table style="width:100%; font-size:small; margin:10px 0; border-collapse:collapse; border:1px solid #CCC;">'; $this->_template .= '{rows}'; $this->_template .= "\n".'</table>'; - + $this->_template_rows = "\n\t".'<tr>'; $this->_template_rows .= "\n\t\t".'<th style="text-align: left; border-bottom:1px solid #CCC;">{item}</th>'; $this->_template_rows .= "\n\t\t".'<td style="border-bottom:1px solid #CCC;">{result}</td>'; - $this->_template_rows .= "\n\t".'</tr>'; + $this->_template_rows .= "\n\t".'</tr>'; } - + // -------------------------------------------------------------------- /** @@ -300,29 +336,29 @@ class CI_Unit_test { * @access private * @return void */ - function _parse_template() - { - if ( ! is_null($this->_template_rows)) - { - return; - } - - if (is_null($this->_template)) - { - $this->_default_template(); - return; - } - + function _parse_template() + { + if ( ! is_null($this->_template_rows)) + { + return; + } + + if (is_null($this->_template)) + { + $this->_default_template(); + return; + } + if ( ! preg_match("/\{rows\}(.*?)\{\/rows\}/si", $this->_template, $match)) { - $this->_default_template(); - return; + $this->_default_template(); + return; } $this->_template_rows = $match['1']; - $this->_template = str_replace($match['0'], '{rows}', $this->_template); - } - + $this->_template = str_replace($match['0'], '{rows}', $this->_template); + } + } // END Unit_test Class diff --git a/system/libraries/Upload.php b/system/libraries/Upload.php index a97b7bdfb..8f84ffd7e 100644..100755 --- a/system/libraries/Upload.php +++ b/system/libraries/Upload.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -25,59 +25,59 @@ * @link http://codeigniter.com/user_guide/libraries/file_uploading.html */ class CI_Upload { - - var $max_size = 0; - var $max_width = 0; - var $max_height = 0; - var $max_filename = 0; - var $allowed_types = ""; - var $file_temp = ""; - var $file_name = ""; - var $orig_name = ""; - var $file_type = ""; - var $file_size = ""; - var $file_ext = ""; - var $upload_path = ""; - var $overwrite = FALSE; - var $encrypt_name = FALSE; - var $is_image = FALSE; - var $image_width = ''; - var $image_height = ''; - var $image_type = ''; - var $image_size_str = ''; - var $error_msg = array(); - var $mimes = array(); - var $remove_spaces = TRUE; - var $xss_clean = FALSE; - var $temp_prefix = "temp_file_"; - var $client_name = ''; - - var $_file_name_override = ''; + + public $max_size = 0; + public $max_width = 0; + public $max_height = 0; + public $max_filename = 0; + public $allowed_types = ""; + public $file_temp = ""; + public $file_name = ""; + public $orig_name = ""; + public $file_type = ""; + public $file_size = ""; + public $file_ext = ""; + public $upload_path = ""; + public $overwrite = FALSE; + public $encrypt_name = FALSE; + public $is_image = FALSE; + public $image_width = ''; + public $image_height = ''; + public $image_type = ''; + public $image_size_str = ''; + public $error_msg = array(); + public $mimes = array(); + public $remove_spaces = TRUE; + public $xss_clean = FALSE; + public $temp_prefix = "temp_file_"; + public $client_name = ''; + + protected $_file_name_override = ''; + /** * Constructor * * @access public */ - function CI_Upload($props = array()) + public function __construct($props = array()) { if (count($props) > 0) { $this->initialize($props); } - + log_message('debug', "Upload Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Initialize preferences * - * @access public * @param array * @return void - */ - function initialize($config = array()) + */ + public function initialize($config = array()) { $defaults = array( 'max_size' => 0, @@ -105,9 +105,9 @@ class CI_Upload { 'xss_clean' => FALSE, 'temp_prefix' => "temp_file_", 'client_name' => '' - ); - - + ); + + foreach ($defaults as $key => $val) { if (isset($config[$key])) @@ -120,28 +120,27 @@ class CI_Upload { else { $this->$key = $config[$key]; - } + } } else { $this->$key = $val; } } - + // if a file_name was provided in the config, use it instead of the user input // supplied file name for all uploads until initialized again $this->_file_name_override = $this->file_name; } - + // -------------------------------------------------------------------- - + /** * Perform the file upload * - * @access public * @return bool - */ - function do_upload($field = 'userfile') + */ + public function do_upload($field = 'userfile') { // Is $_FILES[$field] set? If not, no reason to continue. if ( ! isset($_FILES[$field])) @@ -149,7 +148,7 @@ class CI_Upload { $this->set_error('upload_no_file_selected'); return FALSE; } - + // Is the upload path valid? if ( ! $this->validate_upload_path()) { @@ -171,10 +170,10 @@ class CI_Upload { $this->set_error('upload_file_exceeds_form_limit'); break; case 3: // UPLOAD_ERR_PARTIAL - $this->set_error('upload_file_partial'); + $this->set_error('upload_file_partial'); break; case 4: // UPLOAD_ERR_NO_FILE - $this->set_error('upload_no_file_selected'); + $this->set_error('upload_no_file_selected'); break; case 6: // UPLOAD_ERR_NO_TMP_DIR $this->set_error('upload_no_temp_directory'); @@ -192,9 +191,10 @@ class CI_Upload { return FALSE; } + // Set the uploaded data as class variables - $this->file_temp = $_FILES[$field]['tmp_name']; - $this->file_size = $_FILES[$field]['size']; + $this->file_temp = $_FILES[$field]['tmp_name']; + $this->file_size = $_FILES[$field]['size']; $this->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type']); $this->file_type = strtolower(trim(stripslashes($this->file_type), '"')); $this->file_name = $this->_prep_filename($_FILES[$field]['name']); @@ -207,20 +207,31 @@ class CI_Upload { $this->set_error('upload_invalid_filetype'); return FALSE; } - + // if we're overriding, let's now make sure the new name and type is allowed 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)) { $this->set_error('upload_invalid_filetype'); - return FALSE; + return FALSE; } } - + // Convert the file size to kilobytes if ($this->file_size > 0) { @@ -244,7 +255,7 @@ class CI_Upload { // Sanitize the file name for security $this->file_name = $this->clean_file_name($this->file_name); - + // Truncate the file name if it's too long if ($this->max_filename > 0) { @@ -268,7 +279,7 @@ class CI_Upload { if ($this->overwrite == FALSE) { $this->file_name = $this->set_filename($this->upload_path, $this->file_name); - + if ($this->file_name === FALSE) { return FALSE; @@ -276,6 +287,21 @@ class CI_Upload { } /* + * Run the file through the XSS hacking filter + * This helps prevent malicious code from being + * embedded within a file. Scripts can easily + * be disguised as images or other file types. + */ + if ($this->xss_clean) + { + if ($this->do_xss_clean() === FALSE) + { + $this->set_error('upload_unable_to_write_file'); + return FALSE; + } + } + + /* * Move the file to the final destination * To deal with different server configurations * we'll attempt to use copy() first. If that fails @@ -286,21 +312,10 @@ class CI_Upload { { if ( ! @move_uploaded_file($this->file_temp, $this->upload_path.$this->file_name)) { - $this->set_error('upload_destination_error'); - return FALSE; + $this->set_error('upload_destination_error'); + return FALSE; } } - - /* - * Run the file through the XSS hacking filter - * This helps prevent malicious code from being - * embedded within a file. Scripts can easily - * be disguised as images or other file types. - */ - if ($this->xss_clean == TRUE) - { - $this->do_xss_clean(); - } /* * Set the finalized image dimensions @@ -312,19 +327,18 @@ class CI_Upload { return TRUE; } - + // -------------------------------------------------------------------- - + /** * Finalized Data Array - * + * * Returns an associative array containing all of the information * related to the upload, allowing the developer easy access in one array. * - * @access public * @return array - */ - function data() + */ + public function data() { return array ( 'file_name' => $this->file_name, @@ -343,24 +357,23 @@ class CI_Upload { 'image_size_str' => $this->image_size_str, ); } - + // -------------------------------------------------------------------- - + /** * Set Upload Path * - * @access public * @param string * @return void - */ - function set_upload_path($path) + */ + public function set_upload_path($path) { // Make sure it has a trailing slash $this->upload_path = rtrim($path, '/').'/'; } - + // -------------------------------------------------------------------- - + /** * Set the file name * @@ -368,29 +381,28 @@ class CI_Upload { * existence of a file with the same name. If found, it will append a * number to the end of the filename to avoid overwriting a pre-existing file. * - * @access public * @param string * @param string * @return string - */ - function set_filename($path, $filename) + */ + public function set_filename($path, $filename) { if ($this->encrypt_name == TRUE) - { + { mt_srand(); - $filename = md5(uniqid(mt_rand())).$this->file_ext; + $filename = md5(uniqid(mt_rand())).$this->file_ext; } - + if ( ! file_exists($path.$filename)) { return $filename; } - + $filename = str_replace($this->file_ext, '', $filename); - + $new_filename = ''; for ($i = 1; $i < 100; $i++) - { + { if ( ! file_exists($path.$filename.$i.$this->file_ext)) { $new_filename = $filename.$i.$this->file_ext; @@ -408,89 +420,88 @@ class CI_Upload { return $new_filename; } } - + // -------------------------------------------------------------------- - + /** * Set Maximum File Size * - * @access public * @param integer * @return void - */ - function set_max_filesize($n) + */ + public function set_max_filesize($n) { $this->max_size = ((int) $n < 0) ? 0: (int) $n; } - + // -------------------------------------------------------------------- - + /** * Set Maximum File Name Length * - * @access public * @param integer * @return void - */ - function set_max_filename($n) + */ + public function set_max_filename($n) { $this->max_filename = ((int) $n < 0) ? 0: (int) $n; } // -------------------------------------------------------------------- - + /** * Set Maximum Image Width * - * @access public * @param integer * @return void - */ - function set_max_width($n) + */ + public function set_max_width($n) { $this->max_width = ((int) $n < 0) ? 0: (int) $n; } - + // -------------------------------------------------------------------- - + /** * Set Maximum Image Height * - * @access public * @param integer * @return void - */ - function set_max_height($n) + */ + public function set_max_height($n) { $this->max_height = ((int) $n < 0) ? 0: (int) $n; } - + // -------------------------------------------------------------------- - + /** * Set Allowed File Types * - * @access public * @param string * @return void - */ - function set_allowed_types($types) + */ + public function set_allowed_types($types) { + if ( ! is_array($types) && $types == '*') + { + $this->allowed_types = '*'; + return; + } $this->allowed_types = explode('|', $types); } - + // -------------------------------------------------------------------- - + /** * Set Image Properties * * Uses GD to determine the width/height/type of image * - * @access public * @param string * @return void - */ - function set_image_properties($path = '') + */ + public function set_image_properties($path = '') { if ( ! $this->is_image()) { @@ -500,7 +511,7 @@ class CI_Upload { if (function_exists('getimagesize')) { if (FALSE !== ($D = @getimagesize($path))) - { + { $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png'); $this->image_width = $D['0']; @@ -510,45 +521,43 @@ class CI_Upload { } } } - + // -------------------------------------------------------------------- - + /** * Set XSS Clean * * Enables the XSS flag so that the file that was uploaded * will be run through the XSS filter. * - * @access public * @param bool * @return void */ - function set_xss_clean($flag = FALSE) + public function set_xss_clean($flag = FALSE) { $this->xss_clean = ($flag == TRUE) ? TRUE : FALSE; } - + // -------------------------------------------------------------------- - + /** * Validate the image * - * @access public * @return bool - */ - function is_image() + */ + public function is_image() { // IE will sometimes return odd mime-types during upload, so here we just standardize all // jpegs or pngs to the same file type. $png_mimes = array('image/x-png'); $jpeg_mimes = array('image/jpg', 'image/jpe', 'image/jpeg', 'image/pjpeg'); - + if (in_array($this->file_type, $png_mimes)) { $this->file_type = 'image/png'; } - + if (in_array($this->file_type, $jpeg_mimes)) { $this->file_type = 'image/jpeg'; @@ -558,29 +567,33 @@ class CI_Upload { 'image/gif', 'image/jpeg', 'image/png', - ); + ); return (in_array($this->file_type, $img_mimes, TRUE)) ? TRUE : FALSE; } - + // -------------------------------------------------------------------- - + /** * Verify that the filetype is allowed * - * @access public * @return bool - */ - function is_allowed_filetype($ignore_mime = FALSE) + */ + public function is_allowed_filetype($ignore_mime = FALSE) { + if ($this->allowed_types == '*') + { + return TRUE; + } + if (count($this->allowed_types) == 0 OR ! is_array($this->allowed_types)) { $this->set_error('upload_no_file_types'); return FALSE; } - + $ext = strtolower(ltrim($this->file_ext, '.')); - + if ( ! in_array($ext, $this->allowed_types)) { return FALSE; @@ -594,40 +607,39 @@ class CI_Upload { if (getimagesize($this->file_temp) === FALSE) { return FALSE; - } + } } if ($ignore_mime === TRUE) { return TRUE; } - + $mime = $this->mimes_types($ext); - + if (is_array($mime)) { if (in_array($this->file_type, $mime, TRUE)) { return TRUE; - } + } } elseif ($mime == $this->file_type) { return TRUE; } - + return FALSE; } - + // -------------------------------------------------------------------- - + /** * Verify that the file is within the allowed size * - * @access public * @return bool - */ - function is_allowed_filesize() + */ + public function is_allowed_filesize() { if ($this->max_size != 0 AND $this->file_size > $this->max_size) { @@ -638,16 +650,15 @@ class CI_Upload { return TRUE; } } - + // -------------------------------------------------------------------- - + /** * Verify that the image is within the allowed width/height * - * @access public * @return bool - */ - function is_allowed_dimensions() + */ + public function is_allowed_dimensions() { if ( ! $this->is_image()) { @@ -673,26 +684,25 @@ class CI_Upload { return TRUE; } - + // -------------------------------------------------------------------- - + /** * Validate Upload Path * * Verifies that it is a valid upload path with proper permissions. * * - * @access public * @return bool - */ - function validate_upload_path() + */ + public function validate_upload_path() { if ($this->upload_path == '') { $this->set_error('upload_no_filepath'); return FALSE; } - + if (function_exists('realpath') AND @realpath($this->upload_path) !== FALSE) { $this->upload_path = str_replace("\\", "/", realpath($this->upload_path)); @@ -713,32 +723,30 @@ class CI_Upload { $this->upload_path = preg_replace("/(.+?)\/*$/", "\\1/", $this->upload_path); return TRUE; } - + // -------------------------------------------------------------------- - + /** * Extract the file extension * - * @access public * @param string * @return string - */ - function get_extension($filename) + */ + public function get_extension($filename) { $x = explode('.', $filename); return '.'.end($x); - } - + } + // -------------------------------------------------------------------- - + /** * Clean the file name for security * - * @access public * @param string * @return string - */ - function clean_file_name($filename) + */ + public function clean_file_name($filename) { $bad = array( "<!--", @@ -756,40 +764,39 @@ class CI_Upload { "%20", "%22", "%3c", // < - "%253c", // < - "%3e", // > - "%0e", // > - "%28", // ( - "%29", // ) - "%2528", // ( - "%26", // & - "%24", // $ - "%3f", // ? - "%3b", // ; + "%253c", // < + "%3e", // > + "%0e", // > + "%28", // ( + "%29", // ) + "%2528", // ( + "%26", // & + "%24", // $ + "%3f", // ? + "%3b", // ; "%3d" // = ); - + $filename = str_replace($bad, '', $filename); return stripslashes($filename); } // -------------------------------------------------------------------- - + /** * Limit the File Name Length * - * @access public * @param string * @return string - */ - function limit_filename_length($filename, $length) + */ + public function limit_filename_length($filename, $length) { if (strlen($filename) < $length) { return $filename; } - + $ext = ''; if (strpos($filename, '.') !== FALSE) { @@ -797,12 +804,12 @@ class CI_Upload { $ext = '.'.array_pop($parts); $filename = implode('.', $parts); } - + return substr($filename, 0, ($length - strlen($ext))).$ext; } // -------------------------------------------------------------------- - + /** * Runs the file through the XSS clean function * @@ -810,59 +817,93 @@ class CI_Upload { * I'm not sure that it won't negatively affect certain files in unexpected ways, * but so far I haven't found that it causes trouble. * - * @access public * @return void - */ - function do_xss_clean() - { - $file = $this->upload_path.$this->file_name; - + */ + public function do_xss_clean() + { + $file = $this->file_temp; + if (filesize($file) == 0) { return FALSE; } + if (function_exists('memory_get_usage') && memory_get_usage() && ini_get('memory_limit') != '') + { + $current = ini_get('memory_limit') * 1024 * 1024; + + // There was a bug/behavioural change in PHP 5.2, where numbers over one million get output + // into scientific notation. number_format() ensures this number is an integer + // http://bugs.php.net/bug.php?id=43053 + + $new_memory = number_format(ceil(filesize($file) + $current), 0, '.', ''); + + ini_set('memory_limit', $new_memory); // When an integer is used, the value is measured in bytes. - PHP.net + } + + // If the file being uploaded is an image, then we should have no problem with XSS attacks (in theory), but + // IE can be fooled into mime-type detecting a malformed image as an html file, thus executing an XSS attack on anyone + // using IE who looks at the image. It does this by inspecting the first 255 bytes of an image. To get around this + // CI will itself look at the first 255 bytes of an image to determine its relative safety. This can save a lot of + // processor power and time if it is actually a clean image, as it will be in nearly all instances _except_ an + // attempted XSS attack. + + if (function_exists('getimagesize') && @getimagesize($file) !== FALSE) + { + if (($file = @fopen($file, 'rb')) === FALSE) // "b" to force binary + { + return FALSE; // Couldn't open the file, return FALSE + } + + $opening_bytes = fread($file, 256); + fclose($file); + + // These are known to throw IE into mime-type detection chaos + // <a, <body, <head, <html, <img, <plaintext, <pre, <script, <table, <title + // title is basically just in SVG, but we filter it anyhow + + if ( ! preg_match('/<(a|body|head|html|img|plaintext|pre|script|table|title)[\s>]/i', $opening_bytes)) + { + return TRUE; // its an image, no "triggers" detected in the first 256 bytes, we're good + } + } + if (($data = @file_get_contents($file)) === FALSE) { return FALSE; } - - if ( ! $fp = @fopen($file, FOPEN_READ_WRITE)) + + $CI =& get_instance(); + + if ( ! isset($CI->security)) { - return FALSE; + $CI->load->library('security'); } - $CI =& get_instance(); - $data = $CI->input->xss_clean($data); - - flock($fp, LOCK_EX); - fwrite($fp, $data); - flock($fp, LOCK_UN); - fclose($fp); + return $CI->security->xss_clean($data, TRUE); } - + // -------------------------------------------------------------------- - + /** * Set an error message * - * @access public * @param string * @return void - */ - function set_error($msg) + */ + public function set_error($msg) { - $CI =& get_instance(); + $CI =& get_instance(); $CI->lang->load('upload'); - + if (is_array($msg)) { foreach ($msg as $val) { - $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val); + $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val); $this->error_msg[] = $msg; log_message('error', $msg); - } + } } else { @@ -871,44 +912,42 @@ class CI_Upload { log_message('error', $msg); } } - + // -------------------------------------------------------------------- - + /** * Display the error message * - * @access public * @param string * @param string * @return string - */ - function display_errors($open = '<p>', $close = '</p>') + */ + public function display_errors($open = '<p>', $close = '</p>') { $str = ''; foreach ($this->error_msg as $val) { $str .= $open.$val.$close; } - + return $str; } - + // -------------------------------------------------------------------- - + /** * List of Mime Types * * This is a list of mime types. We use it to validate * the "allowed types" set by the developer * - * @access public * @param string * @return string - */ - function mimes_types($mime) + */ + public function mimes_types($mime) { global $mimes; - + if (count($this->mimes) == 0) { if (@require_once(APPPATH.'config/mimes'.EXT)) @@ -917,25 +956,24 @@ class CI_Upload { unset($mimes); } } - + return ( ! isset($this->mimes[$mime])) ? FALSE : $this->mimes[$mime]; } // -------------------------------------------------------------------- - + /** * Prep Filename * * Prevents possible script execution from Apache's handling of files multiple extensions * http://httpd.apache.org/docs/1.3/mod/mod_mime.html#multipleext * - * @access private * @param string * @return string */ - function _prep_filename($filename) + protected function _prep_filename($filename) { - if (strpos($filename, '.') === FALSE) + if (strpos($filename, '.') === FALSE OR $this->allowed_types == '*') { return $filename; } @@ -957,7 +995,7 @@ class CI_Upload { } $filename .= '.'.$ext; - + return $filename; } diff --git a/system/libraries/User_agent.php b/system/libraries/User_agent.php index a7c7a7609..c62174836 100644..100755 --- a/system/libraries/User_agent.php +++ b/system/libraries/User_agent.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -29,25 +29,25 @@ class CI_User_agent { var $agent = NULL; - + var $is_browser = FALSE; var $is_robot = FALSE; var $is_mobile = FALSE; var $languages = array(); var $charsets = array(); - + var $platforms = array(); var $browsers = array(); var $mobiles = array(); var $robots = array(); - + var $platform = ''; var $browser = ''; var $version = ''; var $mobile = ''; var $robot = ''; - + /** * Constructor * @@ -55,14 +55,14 @@ class CI_User_agent { * * @access public * @return void - */ - function CI_User_agent() + */ + public function __construct() { if (isset($_SERVER['HTTP_USER_AGENT'])) { $this->agent = trim($_SERVER['HTTP_USER_AGENT']); } - + if ( ! is_null($this->agent)) { if ($this->_load_agent_file()) @@ -70,27 +70,27 @@ class CI_User_agent { $this->_compile_data(); } } - + log_message('debug', "User Agent Class Initialized"); } - + // -------------------------------------------------------------------- - + /** * Compile the User Agent Data * * @access private * @return bool - */ - function _load_agent_file() + */ + private function _load_agent_file() { if ( ! @include(APPPATH.'config/user_agents'.EXT)) { return FALSE; } - + $return = FALSE; - + if (isset($platforms)) { $this->platforms = $platforms; @@ -111,7 +111,7 @@ class CI_User_agent { unset($mobiles); $return = TRUE; } - + if (isset($robots)) { $this->robots = $robots; @@ -121,37 +121,37 @@ class CI_User_agent { return $return; } - + // -------------------------------------------------------------------- - + /** * Compile the User Agent Data * * @access private * @return bool - */ - function _compile_data() + */ + private function _compile_data() { $this->_set_platform(); - + foreach (array('_set_browser', '_set_robot', '_set_mobile') as $function) { if ($this->$function() === TRUE) { break; } - } + } } - + // -------------------------------------------------------------------- - + /** * Set the Platform * * @access private * @return mixed - */ - function _set_platform() + */ + private function _set_platform() { if (is_array($this->platforms) AND count($this->platforms) > 0) { @@ -168,19 +168,19 @@ class CI_User_agent { } // -------------------------------------------------------------------- - + /** * Set the Browser * * @access private * @return bool - */ - function _set_browser() + */ + private function _set_browser() { if (is_array($this->browsers) AND count($this->browsers) > 0) { foreach ($this->browsers as $key => $val) - { + { if (preg_match("|".preg_quote($key).".*?([0-9\.]+)|i", $this->agent, $match)) { $this->is_browser = TRUE; @@ -193,19 +193,19 @@ class CI_User_agent { } return FALSE; } - + // -------------------------------------------------------------------- - + /** * Set the Robot * * @access private * @return bool - */ - function _set_robot() + */ + private function _set_robot() { if (is_array($this->robots) AND count($this->robots) > 0) - { + { foreach ($this->robots as $key => $val) { if (preg_match("|".preg_quote($key)."|i", $this->agent)) @@ -220,17 +220,17 @@ class CI_User_agent { } // -------------------------------------------------------------------- - + /** * Set the Mobile Device * * @access private * @return bool - */ - function _set_mobile() + */ + private function _set_mobile() { if (is_array($this->mobiles) AND count($this->mobiles) > 0) - { + { foreach ($this->mobiles as $key => $val) { if (FALSE !== (strpos(strtolower($this->agent), $key))) @@ -240,261 +240,296 @@ class CI_User_agent { return TRUE; } } - } + } return FALSE; } - + // -------------------------------------------------------------------- - + /** * Set the accepted languages * * @access private * @return void - */ - function _set_languages() + */ + private function _set_languages() { if ((count($this->languages) == 0) AND isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) AND $_SERVER['HTTP_ACCEPT_LANGUAGE'] != '') { $languages = preg_replace('/(;q=[0-9\.]+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_LANGUAGE']))); - + $this->languages = explode(',', $languages); } - + if (count($this->languages) == 0) { $this->languages = array('Undefined'); - } + } } - + // -------------------------------------------------------------------- - + /** * Set the accepted character sets * * @access private * @return void - */ - function _set_charsets() - { + */ + private function _set_charsets() + { if ((count($this->charsets) == 0) AND isset($_SERVER['HTTP_ACCEPT_CHARSET']) AND $_SERVER['HTTP_ACCEPT_CHARSET'] != '') { $charsets = preg_replace('/(;q=.+)/i', '', strtolower(trim($_SERVER['HTTP_ACCEPT_CHARSET']))); - + $this->charsets = explode(',', $charsets); } - + if (count($this->charsets) == 0) { $this->charsets = array('Undefined'); - } + } } // -------------------------------------------------------------------- - + /** * Is Browser * * @access public * @return bool - */ - function is_browser() + */ + public function is_browser($key = NULL) { - return $this->is_browser; + if ( ! $this->is_browser) + { + return FALSE; + } + + // No need to be specific, it's a browser + if ($key === NULL) + { + return TRUE; + } + + // Check for a specific browser + return array_key_exists($key, $this->browsers) AND $this->browser === $this->browsers[$key]; } // -------------------------------------------------------------------- - + /** * Is Robot * * @access public * @return bool - */ - function is_robot() + */ + public function is_robot($key = NULL) { - return $this->is_robot; + if ( ! $this->is_robot) + { + return FALSE; + } + + // No need to be specific, it's a robot + if ($key === NULL) + { + return TRUE; + } + + // Check for a specific robot + return array_key_exists($key, $this->robots) AND $this->robot === $this->robots[$key]; } // -------------------------------------------------------------------- - + /** * Is Mobile * * @access public * @return bool - */ - function is_mobile() + */ + public function is_mobile($key = NULL) { - return $this->is_mobile; - } + if ( ! $this->is_mobile) + { + return FALSE; + } + + // No need to be specific, it's a mobile + if ($key === NULL) + { + return TRUE; + } + + // Check for a specific robot + return array_key_exists($key, $this->mobiles) AND $this->mobile === $this->mobiles[$key]; + } // -------------------------------------------------------------------- - + /** * Is this a referral from another site? * * @access public * @return bool - */ - function is_referral() + */ + public function is_referral() { - return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? FALSE : TRUE; + return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == ''); } // -------------------------------------------------------------------- - + /** * Agent String * * @access public * @return string - */ - function agent_string() + */ + public function agent_string() { return $this->agent; } // -------------------------------------------------------------------- - + /** * Get Platform * * @access public * @return string - */ - function platform() + */ + public function platform() { return $this->platform; } // -------------------------------------------------------------------- - + /** * Get Browser Name * * @access public * @return string - */ - function browser() + */ + public function browser() { return $this->browser; } // -------------------------------------------------------------------- - + /** * Get the Browser Version * * @access public * @return string - */ - function version() + */ + public function version() { return $this->version; } // -------------------------------------------------------------------- - + /** * Get The Robot Name * * @access public * @return string - */ - function robot() + */ + public function robot() { return $this->robot; } // -------------------------------------------------------------------- - + /** * Get the Mobile Device * * @access public * @return string - */ - function mobile() + */ + public function mobile() { return $this->mobile; } - + // -------------------------------------------------------------------- - + /** * Get the referrer * * @access public * @return bool - */ - function referrer() + */ + public function referrer() { return ( ! isset($_SERVER['HTTP_REFERER']) OR $_SERVER['HTTP_REFERER'] == '') ? '' : trim($_SERVER['HTTP_REFERER']); } // -------------------------------------------------------------------- - + /** * Get the accepted languages * * @access public * @return array - */ - function languages() + */ + public function languages() { if (count($this->languages) == 0) { $this->_set_languages(); } - + return $this->languages; } // -------------------------------------------------------------------- - + /** * Get the accepted Character Sets * * @access public * @return array - */ - function charsets() + */ + public function charsets() { if (count($this->charsets) == 0) { $this->_set_charsets(); } - + return $this->charsets; } - + // -------------------------------------------------------------------- - + /** * Test for a particular language * * @access public * @return bool - */ - function accept_lang($lang = 'en') + */ + public function accept_lang($lang = 'en') { - return (in_array(strtolower($lang), $this->languages(), TRUE)) ? TRUE : FALSE; + return (in_array(strtolower($lang), $this->languages(), TRUE)); } - + // -------------------------------------------------------------------- - + /** * Test for a particular character set * * @access public * @return bool - */ - function accept_charset($charset = 'utf-8') + */ + public function accept_charset($charset = 'utf-8') { - return (in_array(strtolower($charset), $this->charsets(), TRUE)) ? TRUE : FALSE; + return (in_array(strtolower($charset), $this->charsets(), TRUE)); } - - + } diff --git a/system/libraries/Validation.php b/system/libraries/Validation.php deleted file mode 100644 index a42b7760b..000000000 --- a/system/libraries/Validation.php +++ /dev/null @@ -1,875 +0,0 @@ -<?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) 2008 - 2010, EllisLab, Inc. - * @license http://codeigniter.com/user_guide/license.html - * @link http://codeigniter.com - * @since Version 1.0 - * @filesource - */ - -// ------------------------------------------------------------------------ - -/** - * Validation Class - * - * @package CodeIgniter - * @subpackage Libraries - * @category Validation - * @author ExpressionEngine Dev Team - * @link http://codeigniter.com/user_guide/libraries/validation.html - */ -class CI_Validation { - - var $CI; - var $error_string = ''; - var $_error_array = array(); - var $_rules = array(); - var $_fields = array(); - var $_error_messages = array(); - var $_current_field = ''; - var $_safe_form_data = FALSE; - var $_error_prefix = '<p>'; - var $_error_suffix = '</p>'; - - - - /** - * Constructor - * - */ - function CI_Validation() - { - $this->CI =& get_instance(); - - if (function_exists('mb_internal_encoding')) - { - mb_internal_encoding($this->CI->config->item('charset')); - } - - log_message('debug', "Validation Class Initialized"); - } - - // -------------------------------------------------------------------- - - /** - * Set Fields - * - * This function takes an array of field names as input - * and generates class variables with the same name, which will - * either be blank or contain the $_POST value corresponding to it - * - * @access public - * @param string - * @param string - * @return void - */ - function set_fields($data = '', $field = '') - { - if ($data == '') - { - if (count($this->_fields) == 0) - { - return FALSE; - } - } - else - { - if ( ! is_array($data)) - { - $data = array($data => $field); - } - - if (count($data) > 0) - { - $this->_fields = $data; - } - } - - foreach($this->_fields as $key => $val) - { - $this->$key = ( ! isset($_POST[$key])) ? '' : $this->prep_for_form($_POST[$key]); - - $error = $key.'_error'; - if ( ! isset($this->$error)) - { - $this->$error = ''; - } - } - } - - // -------------------------------------------------------------------- - - /** - * Set Rules - * - * This function takes an array of field names and validation - * rules as input ad simply stores is for use later. - * - * @access public - * @param mixed - * @param string - * @return void - */ - function set_rules($data, $rules = '') - { - if ( ! is_array($data)) - { - if ($rules == '') - return; - - $data = array($data => $rules); - } - - foreach ($data as $key => $val) - { - $this->_rules[$key] = $val; - } - } - - // -------------------------------------------------------------------- - - /** - * Set Error Message - * - * Lets users set their own error messages on the fly. Note: The key - * name has to match the function name that it corresponds to. - * - * @access public - * @param string - * @param string - * @return string - */ - function set_message($lang, $val = '') - { - if ( ! is_array($lang)) - { - $lang = array($lang => $val); - } - - $this->_error_messages = array_merge($this->_error_messages, $lang); - } - - // -------------------------------------------------------------------- - - /** - * Set The Error Delimiter - * - * Permits a prefix/suffix to be added to each error message - * - * @access public - * @param string - * @param string - * @return void - */ - function set_error_delimiters($prefix = '<p>', $suffix = '</p>') - { - $this->_error_prefix = $prefix; - $this->_error_suffix = $suffix; - } - - // -------------------------------------------------------------------- - - /** - * Run the Validator - * - * This function does all the work. - * - * @access public - * @return bool - */ - function run() - { - // Do we even have any data to process? Mm? - if (count($_POST) == 0 OR count($this->_rules) == 0) - { - return FALSE; - } - - // Load the language file containing error messages - $this->CI->lang->load('validation'); - - // Cycle through the rules and test for errors - foreach ($this->_rules as $field => $rules) - { - //Explode out the rules! - $ex = explode('|', $rules); - - // Is the field required? If not, if the field is blank we'll move on to the next test - if ( ! in_array('required', $ex, TRUE)) - { - if ( ! isset($_POST[$field]) OR $_POST[$field] == '') - { - continue; - } - } - - /* - * Are we dealing with an "isset" rule? - * - * Before going further, we'll see if one of the rules - * is to check whether the item is set (typically this - * applies only to checkboxes). If so, we'll - * test for it here since there's not reason to go - * further - */ - if ( ! isset($_POST[$field])) - { - if (in_array('isset', $ex, TRUE) OR in_array('required', $ex)) - { - if ( ! isset($this->_error_messages['isset'])) - { - if (FALSE === ($line = $this->CI->lang->line('isset'))) - { - $line = 'The field was not set'; - } - } - else - { - $line = $this->_error_messages['isset']; - } - - // Build the error message - $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field]; - $message = sprintf($line, $mfield); - - // Set the error variable. Example: $this->username_error - $error = $field.'_error'; - $this->$error = $this->_error_prefix.$message.$this->_error_suffix; - $this->_error_array[] = $message; - } - - continue; - } - - /* - * Set the current field - * - * The various prepping functions need to know the - * current field name so they can do this: - * - * $_POST[$this->_current_field] == 'bla bla'; - */ - $this->_current_field = $field; - - // Cycle through the rules! - foreach ($ex As $rule) - { - // Is the rule a callback? - $callback = FALSE; - if (substr($rule, 0, 9) == 'callback_') - { - $rule = substr($rule, 9); - $callback = TRUE; - } - - // Strip the parameter (if exists) from the rule - // Rules can contain a parameter: max_length[5] - $param = FALSE; - if (preg_match("/(.*?)\[(.*?)\]/", $rule, $match)) - { - $rule = $match[1]; - $param = $match[2]; - } - - // Call the function that corresponds to the rule - if ($callback === TRUE) - { - if ( ! method_exists($this->CI, $rule)) - { - continue; - } - - $result = $this->CI->$rule($_POST[$field], $param); - - // If the field isn't required and we just processed a callback we'll move on... - if ( ! in_array('required', $ex, TRUE) AND $result !== FALSE) - { - continue 2; - } - - } - else - { - if ( ! method_exists($this, $rule)) - { - /* - * Run the native PHP function if called for - * - * If our own wrapper function doesn't exist we see - * if a native PHP function does. Users can use - * any native PHP function call that has one param. - */ - if (function_exists($rule)) - { - $_POST[$field] = $rule($_POST[$field]); - $this->$field = $_POST[$field]; - } - - continue; - } - - $result = $this->$rule($_POST[$field], $param); - } - - // Did the rule test negatively? If so, grab the error. - if ($result === FALSE) - { - if ( ! isset($this->_error_messages[$rule])) - { - if (FALSE === ($line = $this->CI->lang->line($rule))) - { - $line = 'Unable to access an error message corresponding to your field name.'; - } - } - else - { - $line = $this->_error_messages[$rule]; - } - - // Build the error message - $mfield = ( ! isset($this->_fields[$field])) ? $field : $this->_fields[$field]; - $mparam = ( ! isset($this->_fields[$param])) ? $param : $this->_fields[$param]; - $message = sprintf($line, $mfield, $mparam); - - // Set the error variable. Example: $this->username_error - $error = $field.'_error'; - $this->$error = $this->_error_prefix.$message.$this->_error_suffix; - - // Add the error to the error array - $this->_error_array[] = $message; - continue 2; - } - } - - } - - $total_errors = count($this->_error_array); - - /* - * Recompile the class variables - * - * If any prepping functions were called the $_POST data - * might now be different then the corresponding class - * variables so we'll set them anew. - */ - if ($total_errors > 0) - { - $this->_safe_form_data = TRUE; - } - - $this->set_fields(); - - // Did we end up with any errors? - if ($total_errors == 0) - { - return TRUE; - } - - // Generate the error string - foreach ($this->_error_array as $val) - { - $this->error_string .= $this->_error_prefix.$val.$this->_error_suffix."\n"; - } - - return FALSE; - } - - // -------------------------------------------------------------------- - - /** - * Required - * - * @access public - * @param string - * @return bool - */ - function required($str) - { - if ( ! is_array($str)) - { - return (trim($str) == '') ? FALSE : TRUE; - } - else - { - return ( ! empty($str)); - } - } - - // -------------------------------------------------------------------- - - /** - * Match one field to another - * - * @access public - * @param string - * @param field - * @return bool - */ - function matches($str, $field) - { - if ( ! isset($_POST[$field])) - { - return FALSE; - } - - return ($str !== $_POST[$field]) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Minimum Length - * - * @access public - * @param string - * @param value - * @return bool - */ - function min_length($str, $val) - { - if (preg_match("/[^0-9]/", $val)) - { - return FALSE; - } - - if (function_exists('mb_strlen')) - { - return (mb_strlen($str) < $val) ? FALSE : TRUE; - } - - return (strlen($str) < $val) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Max Length - * - * @access public - * @param string - * @param value - * @return bool - */ - function max_length($str, $val) - { - if (preg_match("/[^0-9]/", $val)) - { - return FALSE; - } - - if (function_exists('mb_strlen')) - { - return (mb_strlen($str) > $val) ? FALSE : TRUE; - } - - return (strlen($str) > $val) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Exact Length - * - * @access public - * @param string - * @param value - * @return bool - */ - function exact_length($str, $val) - { - if (preg_match("/[^0-9]/", $val)) - { - return FALSE; - } - - if (function_exists('mb_strlen')) - { - return (mb_strlen($str) != $val) ? FALSE : TRUE; - } - - return (strlen($str) != $val) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Valid Email - * - * @access public - * @param string - * @return bool - */ - function valid_email($str) - { - return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Valid Emails - * - * @access public - * @param string - * @return bool - */ - function valid_emails($str) - { - if (strpos($str, ',') === FALSE) - { - return $this->valid_email(trim($str)); - } - - foreach(explode(',', $str) as $email) - { - if (trim($email) != '' && $this->valid_email(trim($email)) === FALSE) - { - return FALSE; - } - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Validate IP Address - * - * @access public - * @param string - * @return string - */ - function valid_ip($ip) - { - return $this->CI->input->valid_ip($ip); - } - - // -------------------------------------------------------------------- - - /** - * Alpha - * - * @access public - * @param string - * @return bool - */ - function alpha($str) - { - return ( ! preg_match("/^([a-z])+$/i", $str)) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Alpha-numeric - * - * @access public - * @param string - * @return bool - */ - function alpha_numeric($str) - { - return ( ! preg_match("/^([a-z0-9])+$/i", $str)) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Alpha-numeric with underscores and dashes - * - * @access public - * @param string - * @return bool - */ - function alpha_dash($str) - { - return ( ! preg_match("/^([-a-z0-9_-])+$/i", $str)) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Numeric - * - * @access public - * @param string - * @return bool - */ - function numeric($str) - { - return (bool)preg_match( '/^[\-+]?[0-9]*\.?[0-9]+$/', $str); - - } - - // -------------------------------------------------------------------- - - /** - * Is Numeric - * - * @access public - * @param string - * @return bool - */ - function is_numeric($str) - { - return ( ! is_numeric($str)) ? FALSE : TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Integer - * - * @access public - * @param string - * @return bool - */ - function integer($str) - { - return (bool)preg_match( '/^[\-+]?[0-9]+$/', $str); - } - - // -------------------------------------------------------------------- - - /** - * Is a Natural number (0,1,2,3, etc.) - * - * @access public - * @param string - * @return bool - */ - function is_natural($str) - { - return (bool)preg_match( '/^[0-9]+$/', $str); - } - - // -------------------------------------------------------------------- - - /** - * Is a Natural number, but not a zero (1,2,3, etc.) - * - * @access public - * @param string - * @return bool - */ - function is_natural_no_zero($str) - { - if ( ! preg_match( '/^[0-9]+$/', $str)) - { - return FALSE; - } - - if ($str == 0) - { - return FALSE; - } - - return TRUE; - } - - // -------------------------------------------------------------------- - - /** - * Valid Base64 - * - * Tests a string for characters outside of the Base64 alphabet - * as defined by RFC 2045 http://www.faqs.org/rfcs/rfc2045 - * - * @access public - * @param string - * @return bool - */ - function valid_base64($str) - { - return (bool) ! preg_match('/[^a-zA-Z0-9\/\+=]/', $str); - } - - // -------------------------------------------------------------------- - - /** - * Set Select - * - * Enables pull-down lists to be set to the value the user - * selected in the event of an error - * - * @access public - * @param string - * @param string - * @return string - */ - function set_select($field = '', $value = '') - { - if ($field == '' OR $value == '' OR ! isset($_POST[$field])) - { - return ''; - } - - if ($_POST[$field] == $value) - { - return ' selected="selected"'; - } - } - - // -------------------------------------------------------------------- - - /** - * Set Radio - * - * Enables radio buttons to be set to the value the user - * selected in the event of an error - * - * @access public - * @param string - * @param string - * @return string - */ - function set_radio($field = '', $value = '') - { - if ($field == '' OR $value == '' OR ! isset($_POST[$field])) - { - return ''; - } - - if ($_POST[$field] == $value) - { - return ' checked="checked"'; - } - } - - // -------------------------------------------------------------------- - - /** - * Set Checkbox - * - * Enables checkboxes to be set to the value the user - * selected in the event of an error - * - * @access public - * @param string - * @param string - * @return string - */ - function set_checkbox($field = '', $value = '') - { - if ($field == '' OR $value == '' OR ! isset($_POST[$field])) - { - return ''; - } - - if ($_POST[$field] == $value) - { - return ' checked="checked"'; - } - } - - // -------------------------------------------------------------------- - - /** - * Prep data for form - * - * This function allows HTML to be safely shown in a form. - * Special characters are converted. - * - * @access public - * @param string - * @return string - */ - function prep_for_form($data = '') - { - if (is_array($data)) - { - foreach ($data as $key => $val) - { - $data[$key] = $this->prep_for_form($val); - } - - return $data; - } - - if ($this->_safe_form_data == FALSE OR $data == '') - { - return $data; - } - - return str_replace(array("'", '"', '<', '>'), array("'", """, '<', '>'), stripslashes($data)); - } - - // -------------------------------------------------------------------- - - /** - * Prep URL - * - * @access public - * @param string - * @return string - */ - function prep_url($str = '') - { - if ($str == 'http://' OR $str == '') - { - $_POST[$this->_current_field] = ''; - return; - } - - if (substr($str, 0, 7) != 'http://' && substr($str, 0, 8) != 'https://') - { - $str = 'http://'.$str; - } - - $_POST[$this->_current_field] = $str; - } - - // -------------------------------------------------------------------- - - /** - * Strip Image Tags - * - * @access public - * @param string - * @return string - */ - function strip_image_tags($str) - { - $_POST[$this->_current_field] = $this->CI->input->strip_image_tags($str); - } - - // -------------------------------------------------------------------- - - /** - * XSS Clean - * - * @access public - * @param string - * @return string - */ - function xss_clean($str) - { - $_POST[$this->_current_field] = $this->CI->input->xss_clean($str); - } - - // -------------------------------------------------------------------- - - /** - * Convert PHP tags to entities - * - * @access public - * @param string - * @return string - */ - function encode_php_tags($str) - { - $_POST[$this->_current_field] = str_replace(array('<?php', '<?PHP', '<?', '?>'), array('<?php', '<?PHP', '<?', '?>'), $str); - } - -} -// END Validation Class - -/* End of file Validation.php */ -/* Location: ./system/libraries/Validation.php */
\ No newline at end of file diff --git a/system/libraries/Xmlrpc.php b/system/libraries/Xmlrpc.php index fe5562fef..9cf307cc0 100644..100755 --- a/system/libraries/Xmlrpc.php +++ b/system/libraries/Xmlrpc.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -14,7 +14,7 @@ */ if ( ! function_exists('xml_parser_create')) -{ +{ show_error('Your PHP installation does not support XML'); } @@ -32,60 +32,61 @@ if ( ! function_exists('xml_parser_create')) */ class CI_Xmlrpc { - var $debug = FALSE; // Debugging on or off + var $debug = FALSE; // Debugging on or off var $xmlrpcI4 = 'i4'; var $xmlrpcInt = 'int'; var $xmlrpcBoolean = 'boolean'; - var $xmlrpcDouble = 'double'; + var $xmlrpcDouble = 'double'; var $xmlrpcString = 'string'; var $xmlrpcDateTime = 'dateTime.iso8601'; var $xmlrpcBase64 = 'base64'; var $xmlrpcArray = 'array'; var $xmlrpcStruct = 'struct'; - + var $xmlrpcTypes = array(); var $valid_parents = array(); var $xmlrpcerr = array(); // Response numbers var $xmlrpcstr = array(); // Response strings - + var $xmlrpc_defencoding = 'UTF-8'; var $xmlrpcName = 'XML-RPC for CodeIgniter'; var $xmlrpcVersion = '1.1'; var $xmlrpcerruser = 800; // Start of user errors var $xmlrpcerrxml = 100; // Start of XML Parse errors var $xmlrpc_backslash = ''; // formulate backslashes for escaping regexp - + var $client; var $method; var $data; var $message = ''; - var $error = ''; // Error string for request + var $error = ''; // Error string for request var $result; var $response = array(); // Response from remote server + var $xss_clean = TRUE; //------------------------------------- // VALUES THAT MULTIPLE CLASSES NEED //------------------------------------- - function CI_Xmlrpc ($config = array()) + public function __construct($config = array()) { - $this->xmlrpcName = $this->xmlrpcName; + $this->xmlrpcName = $this->xmlrpcName; $this->xmlrpc_backslash = chr(92).chr(92); - + // Types for info sent back and forth $this->xmlrpcTypes = array( - $this->xmlrpcI4 => '1', - $this->xmlrpcInt => '1', - $this->xmlrpcBoolean => '1', - $this->xmlrpcString => '1', - $this->xmlrpcDouble => '1', - $this->xmlrpcDateTime => '1', - $this->xmlrpcBase64 => '1', - $this->xmlrpcArray => '2', - $this->xmlrpcStruct => '3' + $this->xmlrpcI4 => '1', + $this->xmlrpcInt => '1', + $this->xmlrpcBoolean => '1', + $this->xmlrpcString => '1', + $this->xmlrpcDouble => '1', + $this->xmlrpcDateTime => '1', + $this->xmlrpcBase64 => '1', + $this->xmlrpcArray => '2', + $this->xmlrpcStruct => '3' ); - + // Array of Valid Parents for Various XML-RPC elements $this->valid_parents = array('BOOLEAN' => array('VALUE'), 'I4' => array('VALUE'), @@ -105,13 +106,13 @@ class CI_Xmlrpc { 'FAULT' => array('METHODRESPONSE'), 'VALUE' => array('MEMBER', 'DATA', 'PARAM', 'FAULT') ); - - + + // XML-RPC Responses $this->xmlrpcerr['unknown_method'] = '1'; $this->xmlrpcstr['unknown_method'] = 'This is not a known method for this XML-RPC Server'; $this->xmlrpcerr['invalid_return'] = '2'; - $this->xmlrpcstr['invalid_return'] = 'The XML data receieved was either invalid or not in the correct form for XML-RPC. Turn on debugging to examine the XML data further.'; + $this->xmlrpcstr['invalid_return'] = 'The XML data received was either invalid or not in the correct form for XML-RPC. Turn on debugging to examine the XML data further.'; $this->xmlrpcerr['incorrect_params'] = '3'; $this->xmlrpcstr['incorrect_params'] = 'Incorrect parameters were passed to method'; $this->xmlrpcerr['introspect_unknown'] = '4'; @@ -120,13 +121,13 @@ class CI_Xmlrpc { $this->xmlrpcstr['http_error'] = "Did not receive a '200 OK' response from remote server."; $this->xmlrpcerr['no_data'] = '6'; $this->xmlrpcstr['no_data'] ='No data received from server.'; - + $this->initialize($config); - + log_message('debug', "XML-RPC Class Initialized"); } - - + + //------------------------------------- // Initialize Prefs //------------------------------------- @@ -139,13 +140,13 @@ class CI_Xmlrpc { { if (isset($this->$key)) { - $this->$key = $val; + $this->$key = $val; } } } } // END - + //------------------------------------- // Take URL and parse it //------------------------------------- @@ -156,20 +157,20 @@ class CI_Xmlrpc { { $url = "http://".$url; } - + $parts = parse_url($url); - + $path = ( ! isset($parts['path'])) ? '/' : $parts['path']; - + if (isset($parts['query']) && $parts['query'] != '') { $path .= '?'.$parts['query']; - } - + } + $this->client = new XML_RPC_Client($path, $parts['host'], $port); } // END - + //------------------------------------- // Set Timeout //------------------------------------- @@ -182,7 +183,7 @@ class CI_Xmlrpc { } } // END - + //------------------------------------- // Set Methods //------------------------------------- @@ -192,7 +193,7 @@ class CI_Xmlrpc { $this->method = $function; } // END - + //------------------------------------- // Take Array of Data and Create Objects //------------------------------------- @@ -203,17 +204,17 @@ class CI_Xmlrpc { { // Send Error } - + $this->data = array(); - + foreach($incoming as $key => $value) { $this->data[$key] = $this->values_parsing($value); } } // END - - + + //------------------------------------- // Set Debug //------------------------------------- @@ -222,14 +223,14 @@ class CI_Xmlrpc { { $this->debug = ($flag == TRUE) ? TRUE : FALSE; } - + //------------------------------------- // Values Parsing //------------------------------------- function values_parsing($value, $return = FALSE) { - if (is_array($value) && isset($value['0'])) + if (is_array($value) && array_key_exists(0, $value)) { if ( ! isset($value['1']) OR (! isset($this->xmlrpcTypes[$value['1']]))) { @@ -248,7 +249,7 @@ class CI_Xmlrpc { { $value['0'][$k] = $this->values_parsing($value['0'][$k], TRUE); } - + $temp = new XML_RPC_Values($value['0'], $value['1']); } else @@ -274,7 +275,7 @@ class CI_Xmlrpc { { $this->message = new XML_RPC_Message($this->method,$this->data); $this->message->debug = $this->debug; - + if ( ! $this->result = $this->client->send($this->message)) { $this->error = $this->result->errstr; @@ -285,13 +286,13 @@ class CI_Xmlrpc { $this->error = $this->result->errstr; return FALSE; } - + $this->response = $this->result->decode(); - + return TRUE; } // END - + //------------------------------------- // Returns Error //------------------------------------- @@ -301,7 +302,7 @@ class CI_Xmlrpc { return $this->error; } // END - + //------------------------------------- // Returns Remote Server Response //------------------------------------- @@ -311,37 +312,37 @@ class CI_Xmlrpc { return $this->response; } // END - + //------------------------------------- // Sends an Error Message for Server Request //------------------------------------- - + function send_error_message($number, $message) { return new XML_RPC_Response('0',$number, $message); } // END - - + + //------------------------------------- // Send Response for Server Request //------------------------------------- - + function send_response($response) { // $response should be array of values, which will be parsed // based on their data and type into a valid group of XML-RPC values - + $response = $this->values_parsing($response); - + return new XML_RPC_Response($response); } // END - + } // END XML_RPC Class - - + + /** * XML-RPC Client class * @@ -359,15 +360,15 @@ class XML_RPC_Client extends CI_Xmlrpc var $timeout = 5; var $no_multicall = false; - function XML_RPC_Client($path, $server, $port=80) + public function __construct($path, $server, $port=80) { - parent::CI_Xmlrpc(); - + parent::__construct(); + $this->port = $port; $this->server = $server; $this->path = $path; } - + function send($msg) { if (is_array($msg)) @@ -381,22 +382,22 @@ class XML_RPC_Client extends CI_Xmlrpc } function sendPayload($msg) - { + { $fp = @fsockopen($this->server, $this->port,$this->errno, $this->errstr, $this->timeout); - + if ( ! is_resource($fp)) { error_log($this->xmlrpcstr['http_error']); $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'],$this->xmlrpcstr['http_error']); return $r; } - + if(empty($msg->payload)) { // $msg = XML_RPC_Messages $msg->createPayload(); } - + $r = "\r\n"; $op = "POST {$this->path} HTTP/1.0$r"; $op .= "Host: {$this->server}$r"; @@ -404,7 +405,7 @@ class XML_RPC_Client extends CI_Xmlrpc $op .= "User-Agent: {$this->xmlrpcName}$r"; $op .= "Content-Length: ".strlen($msg->payload). "$r$r"; $op .= $msg->payload; - + if ( ! fputs($fp, $op, strlen($op))) { @@ -433,9 +434,10 @@ class XML_RPC_Response var $errno = 0; var $errstr = ''; var $headers = array(); + var $xss_clean = TRUE; - function XML_RPC_Response($val, $code = 0, $fstr = '') - { + public function __construct($val, $code = 0, $fstr = '') + { if ($code != 0) { // error @@ -468,7 +470,7 @@ class XML_RPC_Response { return $this->val; } - + function prepare_response() { $result = "<methodResponse>\n"; @@ -498,11 +500,16 @@ class XML_RPC_Response $result .= "\n</methodResponse>"; return $result; } - + function decode($array=FALSE) { $CI =& get_instance(); + if ($this->xss_clean && ! isset($CI->security)) + { + $CI->load->library('security'); + } + if ($array !== FALSE && is_array($array)) { while (list($key) = each($array)) @@ -513,31 +520,31 @@ class XML_RPC_Response } else { - $array[$key] = $CI->input->xss_clean($array[$key]); + $array[$key] = ($this->xss_clean) ? $CI->security->xss_clean($array[$key]) : $array[$key]; } } - + $result = $array; } else { $result = $this->xmlrpc_decoder($this->val); - + if (is_array($result)) { $result = $this->decode($result); } else { - $result = $CI->input->xss_clean($result); + $result = ($this->xss_clean) ? $CI->security->xss_clean($result) : $result; } } - + return $result; } - - + + //------------------------------------- // XML-RPC Object to PHP Types //------------------------------------- @@ -555,7 +562,7 @@ class XML_RPC_Response reset($xmlrpc_val->me); list($a,$b) = each($xmlrpc_val->me); $size = count($b); - + $arr = array(); for($i = 0; $i < $size; $i++) @@ -576,8 +583,8 @@ class XML_RPC_Response return $arr; } } - - + + //------------------------------------- // ISO-8601 time to server or UTC time //------------------------------------- @@ -595,7 +602,7 @@ class XML_RPC_Response } return $t; } - + } // End Response Class @@ -612,12 +619,12 @@ class XML_RPC_Message extends CI_Xmlrpc var $payload; var $method_name; var $params = array(); - var $xh = array(); + var $xh = array(); - function XML_RPC_Message($method, $pars=0) + public function __construct($method, $pars=0) { - parent::CI_Xmlrpc(); - + parent::__construct(); + $this->method_name = $method; if (is_array($pars) && count($pars) > 0) { @@ -628,51 +635,51 @@ class XML_RPC_Message extends CI_Xmlrpc } } } - + //------------------------------------- // Create Payload to Send //------------------------------------- - + function createPayload() { $this->payload = "<?xml version=\"1.0\"?".">\r\n<methodCall>\r\n"; $this->payload .= '<methodName>' . $this->method_name . "</methodName>\r\n"; $this->payload .= "<params>\r\n"; - + for($i=0; $i<count($this->params); $i++) { // $p = XML_RPC_Values $p = $this->params[$i]; $this->payload .= "<param>\r\n".$p->serialize_class()."</param>\r\n"; } - + $this->payload .= "</params>\r\n</methodCall>\r\n"; } - + //------------------------------------- // Parse External XML-RPC Server's Response //------------------------------------- - + function parseResponse($fp) { $data = ''; - + while($datum = fread($fp, 4096)) { $data .= $datum; } - + //------------------------------------- // DISPLAY HTTP CONTENT for DEBUGGING //------------------------------------- - + if ($this->debug === TRUE) { echo "<pre>"; echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n"; echo "</pre>"; } - + //------------------------------------- // Check for data //------------------------------------- @@ -683,32 +690,32 @@ class XML_RPC_Message extends CI_Xmlrpc $r = new XML_RPC_Response(0, $this->xmlrpcerr['no_data'], $this->xmlrpcstr['no_data']); return $r; } - - + + //------------------------------------- // Check for HTTP 200 Response //------------------------------------- - + if (strncmp($data, 'HTTP', 4) == 0 && ! preg_match('/^HTTP\/[0-9\.]+ 200 /', $data)) { $errstr= substr($data, 0, strpos($data, "\n")-1); $r = new XML_RPC_Response(0, $this->xmlrpcerr['http_error'], $this->xmlrpcstr['http_error']. ' (' . $errstr . ')'); return $r; } - + //------------------------------------- // Create and Set Up XML Parser //------------------------------------- - + $parser = xml_parser_create($this->xmlrpc_defencoding); - $this->xh[$parser] = array(); - $this->xh[$parser]['isf'] = 0; - $this->xh[$parser]['ac'] = ''; - $this->xh[$parser]['headers'] = array(); - $this->xh[$parser]['stack'] = array(); - $this->xh[$parser]['valuestack'] = array(); - $this->xh[$parser]['isf_reason'] = 0; + $this->xh[$parser] = array(); + $this->xh[$parser]['isf'] = 0; + $this->xh[$parser]['ac'] = ''; + $this->xh[$parser]['headers'] = array(); + $this->xh[$parser]['stack'] = array(); + $this->xh[$parser]['valuestack'] = array(); + $this->xh[$parser]['isf_reason'] = 0; xml_set_object($parser, $this); xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, true); @@ -720,7 +727,7 @@ class XML_RPC_Message extends CI_Xmlrpc //------------------------------------- // GET HEADERS //------------------------------------- - + $lines = explode("\r\n", $data); while (($line = array_shift($lines))) { @@ -731,11 +738,11 @@ class XML_RPC_Message extends CI_Xmlrpc $this->xh[$parser]['headers'][] = $line; } $data = implode("\r\n", $lines); - - + + //------------------------------------- // PARSE XML DATA - //------------------------------------- + //------------------------------------- if ( ! xml_parse($parser, $data, count($data))) { @@ -748,11 +755,11 @@ class XML_RPC_Message extends CI_Xmlrpc return $r; } xml_parser_free($parser); - + // --------------------------------------- // Got Ourselves Some Badness, It Seems // --------------------------------------- - + if ($this->xh[$parser]['isf'] > 1) { if ($this->debug === TRUE) @@ -761,7 +768,7 @@ class XML_RPC_Message extends CI_Xmlrpc echo $this->xh[$parser]['isf_reason']; echo "---Invalid Return---\n\n"; } - + $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); return $r; } @@ -770,15 +777,15 @@ class XML_RPC_Message extends CI_Xmlrpc $r = new XML_RPC_Response(0, $this->xmlrpcerr['invalid_return'],$this->xmlrpcstr['invalid_return'].' '.$this->xh[$parser]['isf_reason']); return $r; } - + //------------------------------------- // DISPLAY XML CONTENT for DEBUGGING - //------------------------------------- - + //------------------------------------- + if ($this->debug === TRUE) { echo "<pre>"; - + if (count($this->xh[$parser]['headers'] > 0)) { echo "---HEADERS---\n"; @@ -788,20 +795,20 @@ class XML_RPC_Message extends CI_Xmlrpc } echo "---END HEADERS---\n\n"; } - + echo "---DATA---\n" . htmlspecialchars($data) . "\n---END DATA---\n\n"; - + echo "---PARSED---\n" ; var_dump($this->xh[$parser]['value']); echo "\n---END PARSED---</pre>"; } - + //------------------------------------- // SEND RESPONSE //------------------------------------- - + $v = $this->xh[$parser]['value']; - + if ($this->xh[$parser]['isf']) { $errno_v = $v->me['struct']['faultCode']; @@ -824,11 +831,11 @@ class XML_RPC_Message extends CI_Xmlrpc $r->headers = $this->xh[$parser]['headers']; return $r; } - + // ------------------------------------ // Begin Return Message Parsing section // ------------------------------------ - + // quick explanation of components: // ac - used to accumulate values // isf - used to indicate a fault @@ -847,9 +854,9 @@ class XML_RPC_Message extends CI_Xmlrpc { // If invalid nesting, then return if ($this->xh[$the_parser]['isf'] > 1) return; - + // Evaluate and check for correct nesting of XML elements - + if (count($this->xh[$the_parser]['stack']) == 0) { if ($name != 'METHODRESPONSE' && $name != 'METHODCALL') @@ -869,16 +876,16 @@ class XML_RPC_Message extends CI_Xmlrpc return; } } - + switch($name) { case 'STRUCT': case 'ARRAY': // Creates array for child elements - + $cur_val = array('value' => array(), 'type' => $name); - + array_unshift($this->xh[$the_parser]['valuestack'], $cur_val); break; case 'METHODNAME': @@ -910,13 +917,13 @@ class XML_RPC_Message extends CI_Xmlrpc $this->xh[$the_parser]['isf_reason'] = "'Twas a $name element following a ".$this->xh[$the_parser]['vt']." element inside a single value"; return; } - + $this->xh[$the_parser]['ac'] = ''; break; case 'MEMBER': // Set name of <member> to nothing to prevent errors later if no <name> is found $this->xh[$the_parser]['valuestack'][0]['name'] = ''; - + // Set NULL value to check to see if value passed for this param/member $this->xh[$the_parser]['value'] = null; break; @@ -932,7 +939,7 @@ class XML_RPC_Message extends CI_Xmlrpc $this->xh[$the_parser]['isf_reason'] = "Invalid XML-RPC element found: $name"; break; } - + // Add current element name to stack, to allow validation of nesting array_unshift($this->xh[$the_parser]['stack'], $name); @@ -948,14 +955,14 @@ class XML_RPC_Message extends CI_Xmlrpc function closing_tag($the_parser, $name) { if ($this->xh[$the_parser]['isf'] > 1) return; - + // Remove current element from stack and set variable // NOTE: If the XML validates, then we do not have to worry about // the opening and closing of elements. Nesting is checked on the opening // tag so we be safe there as well. - + $curr_elem = array_shift($this->xh[$the_parser]['stack']); - + switch($name) { case 'STRUCT': @@ -975,7 +982,7 @@ class XML_RPC_Message extends CI_Xmlrpc case 'DATETIME.ISO8601': case 'BASE64': $this->xh[$the_parser]['vt'] = strtolower($name); - + if ($name == 'STRING') { $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; @@ -1037,10 +1044,10 @@ class XML_RPC_Message extends CI_Xmlrpc $this->xh[$the_parser]['value'] = $this->xh[$the_parser]['ac']; $this->xh[$the_parser]['vt'] = $this->xmlrpcString; } - + // build the XML-RPC value out of the data received, and substitute it $temp = new XML_RPC_Values($this->xh[$the_parser]['value'], $this->xh[$the_parser]['vt']); - + if (count($this->xh[$the_parser]['valuestack']) && $this->xh[$the_parser]['valuestack'][0]['type'] == 'ARRAY') { // Array @@ -1054,7 +1061,7 @@ class XML_RPC_Message extends CI_Xmlrpc break; case 'MEMBER': $this->xh[$the_parser]['ac']=''; - + // If value add to array in the stack for the last element built if ($this->xh[$the_parser]['value']) { @@ -1092,7 +1099,7 @@ class XML_RPC_Message extends CI_Xmlrpc function character_data($the_parser, $data) { if ($this->xh[$the_parser]['isf'] > 1) return; // XML Fault found already - + // If a value has not been found if ($this->xh[$the_parser]['lv'] != 3) { @@ -1100,22 +1107,27 @@ class XML_RPC_Message extends CI_Xmlrpc { $this->xh[$the_parser]['lv'] = 2; // Found a value } - + if( ! @isset($this->xh[$the_parser]['ac'])) { $this->xh[$the_parser]['ac'] = ''; } - + $this->xh[$the_parser]['ac'] .= $data; } } - - + + function addParam($par) { $this->params[]=$par; } - + function output_parameters($array=FALSE) { - $CI =& get_instance(); + $CI =& get_instance(); + + if ($this->xss_clean && ! isset($CI->security)) + { + $CI->load->library('security'); + } if ($array !== FALSE && is_array($array)) { @@ -1127,35 +1139,37 @@ class XML_RPC_Message extends CI_Xmlrpc } else { - $array[$key] = $CI->input->xss_clean($array[$key]); + // 'bits' is for the MetaWeblog API image bits + // @todo - this needs to be made more general purpose + $array[$key] = ($key == 'bits' OR $this->xss_clean == FALSE) ? $array[$key] : $CI->security->xss_clean($array[$key]); } } - + $parameters = $array; } else { $parameters = array(); - + for ($i = 0; $i < count($this->params); $i++) { $a_param = $this->decode_message($this->params[$i]); - + if (is_array($a_param)) { $parameters[] = $this->output_parameters($a_param); } else { - $parameters[] = $CI->input->xss_clean($a_param); + $parameters[] = ($this->xss_clean) ? $CI->security->xss_clean($a_param) : $a_param; } - } + } } - + return $parameters; } - - + + function decode_message($param) { $kind = $param->kindOf(); @@ -1168,31 +1182,31 @@ class XML_RPC_Message extends CI_Xmlrpc { reset($param->me); list($a,$b) = each($param->me); - + $arr = array(); for($i = 0; $i < count($b); $i++) { $arr[] = $this->decode_message($param->me['array'][$i]); } - + return $arr; } elseif($kind == 'struct') { reset($param->me['struct']); - + $arr = array(); while(list($key,$value) = each($param->me['struct'])) { $arr[$key] = $this->decode_message($value); } - + return $arr; } } - + } // End XML_RPC_Messages class @@ -1206,17 +1220,17 @@ class XML_RPC_Message extends CI_Xmlrpc */ class XML_RPC_Values extends CI_Xmlrpc { - var $me = array(); + var $me = array(); var $mytype = 0; - function XML_RPC_Values($val=-1, $type='') - { - parent::CI_Xmlrpc(); - + public function __construct($val=-1, $type='') + { + parent::__construct(); + if ($val != -1 OR $type != '') { $type = $type == '' ? 'string' : $type; - + if ($this->xmlrpcTypes[$type] == 1) { $this->addScalar($val,$type); @@ -1235,13 +1249,13 @@ class XML_RPC_Values extends CI_Xmlrpc function addScalar($val, $type='string') { $typeof = $this->xmlrpcTypes[$type]; - + if ($this->mytype==1) { echo '<strong>XML_RPC_Values</strong>: scalar can have only one value<br />'; return 0; } - + if ($typeof != 1) { echo '<strong>XML_RPC_Values</strong>: not a scalar type (${typeof})<br />'; @@ -1322,7 +1336,7 @@ class XML_RPC_Values extends CI_Xmlrpc function serializedata($typ, $val) { $rs = ''; - + switch($this->xmlrpcTypes[$typ]) { case 3: @@ -1378,12 +1392,12 @@ class XML_RPC_Values extends CI_Xmlrpc { $ar = $o->me; reset($ar); - + list($typ, $val) = each($ar); $rs = "<value>\n".$this->serializedata($typ, $val)."</value>\n"; return $rs; } - + function scalarval() { reset($this->me); @@ -1395,11 +1409,11 @@ class XML_RPC_Values extends CI_Xmlrpc //------------------------------------- // Encode time in ISO-8601 form. //------------------------------------- - + // Useful for sending time in XML-RPC function iso8601_encode($time, $utc=0) - { + { if ($utc == 1) { $t = strftime("%Y%m%dT%H:%M:%S", $time); @@ -1413,7 +1427,7 @@ class XML_RPC_Values extends CI_Xmlrpc } return $t; } - + } // END XML_RPC_Values Class diff --git a/system/libraries/Xmlrpcs.php b/system/libraries/Xmlrpcs.php index 429ab8472..6bedfe324 100644..100755 --- a/system/libraries/Xmlrpcs.php +++ b/system/libraries/Xmlrpcs.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -14,7 +14,7 @@ */ if ( ! function_exists('xml_parser_create')) -{ +{ show_error('Your PHP installation does not support XML'); } @@ -36,57 +36,60 @@ if ( ! class_exists('CI_Xmlrpc')) */ class CI_Xmlrpcs extends CI_Xmlrpc { - var $methods = array(); //array of methods mapped to function names and signatures + var $methods = array(); //array of methods mapped to function names and signatures var $debug_msg = ''; // Debug Message - var $system_methods = array(); // XML RPC Server methods + var $system_methods = array(); // XML RPC Server methods var $controller_obj; var $object = FALSE; - - - //------------------------------------- - // Constructor, more or less - //------------------------------------- - function CI_Xmlrpcs($config=array()) - { - parent::CI_Xmlrpc(); + /** + * Constructor + */ + public function __construct($config=array()) + { + parent::__construct(); $this->set_system_methods(); - + if (isset($config['functions']) && is_array($config['functions'])) { $this->methods = array_merge($this->methods, $config['functions']); } - + log_message('debug', "XML-RPC Server Class Initialized"); } - + //------------------------------------- // Initialize Prefs and Serve //------------------------------------- - + function initialize($config=array()) - { + { if (isset($config['functions']) && is_array($config['functions'])) { $this->methods = array_merge($this->methods, $config['functions']); } - + if (isset($config['debug'])) { $this->debug = $config['debug']; } - + if (isset($config['object']) && is_object($config['object'])) { $this->object = $config['object']; } + + if (isset($config['xss_clean'])) + { + $this->xss_clean = $config['xss_clean']; + } } - + //------------------------------------- // Setting of System Methods //------------------------------------- - + function set_system_methods () { $this->methods = array( @@ -113,14 +116,14 @@ class CI_Xmlrpcs extends CI_Xmlrpc //------------------------------------- // Main Server Function //------------------------------------- - + function serve() { $r = $this->parseRequest(); $payload = '<?xml version="1.0" encoding="'.$this->xmlrpc_defencoding.'"?'.'>'."\n"; $payload .= $this->debug_msg; $payload .= $r->prepare_response(); - + header("Content-Type: text/xml"); header("Content-Length: ".strlen($payload)); exit($payload); @@ -129,7 +132,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc //------------------------------------- // Add Method to Class //------------------------------------- - + function add_to_map($methodname,$function,$sig,$doc) { $this->methods[$methodname] = array( @@ -143,11 +146,11 @@ class CI_Xmlrpcs extends CI_Xmlrpc //------------------------------------- // Parse Server Request //------------------------------------- - + function parseRequest($data='') { global $HTTP_RAW_POST_DATA; - + //------------------------------------- // Get Data //------------------------------------- @@ -160,10 +163,10 @@ class CI_Xmlrpcs extends CI_Xmlrpc //------------------------------------- // Set up XML Parser //------------------------------------- - + $parser = xml_parser_create($this->xmlrpc_defencoding); $parser_object = new XML_RPC_Message("filler"); - + $parser_object->xh[$parser] = array(); $parser_object->xh[$parser]['isf'] = 0; $parser_object->xh[$parser]['isf_reason'] = ''; @@ -177,12 +180,12 @@ class CI_Xmlrpcs extends CI_Xmlrpc xml_set_element_handler($parser, 'open_tag', 'closing_tag'); xml_set_character_data_handler($parser, 'character_data'); //xml_set_default_handler($parser, 'default_handler'); - - + + //------------------------------------- // PARSE + PROCESS XML DATA - //------------------------------------- - + //------------------------------------- + if ( ! xml_parse($parser, $data, 1)) { // return XML error as a faultCode @@ -200,69 +203,74 @@ class CI_Xmlrpcs extends CI_Xmlrpc else { xml_parser_free($parser); - + $m = new XML_RPC_Message($parser_object->xh[$parser]['method']); $plist=''; - + for($i=0; $i < count($parser_object->xh[$parser]['params']); $i++) { if ($this->debug === TRUE) { $plist .= "$i - " . print_r(get_object_vars($parser_object->xh[$parser]['params'][$i]), TRUE). ";\n"; } - + $m->addParam($parser_object->xh[$parser]['params'][$i]); } - + if ($this->debug === TRUE) { echo "<pre>"; echo "---PLIST---\n" . $plist . "\n---PLIST END---\n\n"; echo "</pre>"; } - + $r = $this->_execute($m); } - + //------------------------------------- // SET DEBUGGING MESSAGE - //------------------------------------- - + //------------------------------------- + if ($this->debug === TRUE) { $this->debug_msg = "<!-- DEBUG INFO:\n\n".$plist."\n END DEBUG-->\n"; } - + return $r; } //------------------------------------- // Executes the Method //------------------------------------- - + function _execute($m) { $methName = $m->method_name; - + // Check to see if it is a system call $system_call = (strncmp($methName, 'system', 5) == 0) ? TRUE : FALSE; - + + if ($this->xss_clean == FALSE) + { + $m->xss_clean = FALSE; + } + //------------------------------------- // Valid Method //------------------------------------- - + if ( ! isset($this->methods[$methName]['function'])) { return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); } - + //------------------------------------- // Check for Method (and Object) //------------------------------------- - + $method_parts = explode(".", $this->methods[$methName]['function']); $objectCall = (isset($method_parts['1']) && $method_parts['1'] != "") ? TRUE : FALSE; - + if ($system_call === TRUE) { if ( ! is_callable(array($this,$method_parts['1']))) @@ -281,30 +289,30 @@ class CI_Xmlrpcs extends CI_Xmlrpc return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); } } - + //------------------------------------- // Checking Methods Signature //------------------------------------- - + if (isset($this->methods[$methName]['signature'])) { $sig = $this->methods[$methName]['signature']; for($i=0; $i<count($sig); $i++) { $current_sig = $sig[$i]; - + if (count($current_sig) == count($m->params)+1) { for($n=0; $n < count($m->params); $n++) { $p = $m->params[$n]; $pt = ($p->kindOf() == 'scalar') ? $p->scalarval() : $p->kindOf(); - + if ($pt != $current_sig[$n+1]) { $pno = $n+1; $wanted = $current_sig[$n+1]; - + return new XML_RPC_Response(0, $this->xmlrpcerr['incorrect_params'], $this->xmlrpcstr['incorrect_params'] . @@ -344,22 +352,22 @@ class CI_Xmlrpcs extends CI_Xmlrpc return call_user_func($this->methods[$methName]['function'], $m); } } - - + + //------------------------------------- // Server Function: List Methods //------------------------------------- - + function listMethods($m) { $v = new XML_RPC_Values(); $output = array(); - + foreach($this->methods as $key => $value) { $output[] = new XML_RPC_Values($key, 'string'); } - + foreach($this->system_methods as $key => $value) { $output[]= new XML_RPC_Values($key, 'string'); @@ -368,23 +376,23 @@ class CI_Xmlrpcs extends CI_Xmlrpc $v->addArray($output); return new XML_RPC_Response($v); } - + //------------------------------------- // Server Function: Return Signature for Method //------------------------------------- - + function methodSignature($m) { $parameters = $m->output_parameters(); $method_name = $parameters[0]; - + if (isset($this->methods[$method_name])) { if ($this->methods[$method_name]['signature']) { $sigs = array(); $signature = $this->methods[$method_name]['signature']; - + for($i=0; $i < count($signature); $i++) { $cursig = array(); @@ -408,20 +416,20 @@ class CI_Xmlrpcs extends CI_Xmlrpc } return $r; } - + //------------------------------------- // Server Function: Doc String for Method //------------------------------------- - + function methodHelp($m) { $parameters = $m->output_parameters(); $method_name = $parameters[0]; - + if (isset($this->methods[$method_name])) { $docstring = isset($this->methods[$method_name]['docstring']) ? $this->methods[$method_name]['docstring'] : ''; - + return new XML_RPC_Response(new XML_RPC_Values($docstring, 'string')); } else @@ -438,7 +446,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc { // Disabled return new XML_RPC_Response(0, $this->xmlrpcerr['unknown_method'], $this->xmlrpcstr['unknown_method']); - + $parameters = $m->output_parameters(); $calls = $parameters[0]; @@ -447,15 +455,15 @@ class CI_Xmlrpcs extends CI_Xmlrpc foreach ($calls as $value) { //$attempt = $this->_execute(new XML_RPC_Message($value[0], $value[1])); - + $m = new XML_RPC_Message($value[0]); $plist=''; - + for($i=0; $i < count($value[1]); $i++) { $m->addParam(new XML_RPC_Values($value[1][$i], 'string')); } - + $attempt = $this->_execute($m); if ($attempt->faultCode() != 0) @@ -468,8 +476,8 @@ class CI_Xmlrpcs extends CI_Xmlrpc return new XML_RPC_Response(new XML_RPC_Values($result, 'array')); } - - + + //------------------------------------- // Multi-call Function: Error Handling //------------------------------------- @@ -478,28 +486,28 @@ class CI_Xmlrpcs extends CI_Xmlrpc { $str = is_string($err) ? $this->xmlrpcstr["multicall_${err}"] : $err->faultString(); $code = is_string($err) ? $this->xmlrpcerr["multicall_${err}"] : $err->faultCode(); - + $struct['faultCode'] = new XML_RPC_Values($code, 'int'); $struct['faultString'] = new XML_RPC_Values($str, 'string'); - + return new XML_RPC_Values($struct, 'struct'); } - - + + //------------------------------------- // Multi-call Function: Processes method //------------------------------------- - + function do_multicall($call) { if ($call->kindOf() != 'struct') return $this->multicall_error('notstruct'); elseif ( ! $methName = $call->me['struct']['methodName']) return $this->multicall_error('nomethod'); - + list($scalar_type,$scalar_value)=each($methName->me); $scalar_type = $scalar_type == $this->xmlrpcI4 ? $this->xmlrpcInt : $scalar_type; - + if ($methName->kindOf() != 'scalar' OR $scalar_type != 'string') return $this->multicall_error('notstring'); elseif ($scalar_value == 'system.multicall') @@ -508,7 +516,7 @@ class CI_Xmlrpcs extends CI_Xmlrpc return $this->multicall_error('noparams'); elseif ($params->kindOf() != 'array') return $this->multicall_error('notarray'); - + list($a,$b)=each($params->me); $numParams = count($b); @@ -526,8 +534,8 @@ class CI_Xmlrpcs extends CI_Xmlrpc } return new XML_RPC_Values(array($result->value()), 'array'); - } - + } + } // END XML_RPC_Server class diff --git a/system/libraries/Zip.php b/system/libraries/Zip.php index af50ca1cb..80633c708 100644..100755 --- a/system/libraries/Zip.php +++ b/system/libraries/Zip.php @@ -2,11 +2,11 @@ /** * CodeIgniter * - * An open source application development framework for PHP 4.3.2 or newer + * An open source application development framework for PHP 5.1.6 or newer * * @package CodeIgniter * @author ExpressionEngine Dev Team - * @copyright Copyright (c) 2008 - 2010, EllisLab, Inc. + * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc. * @license http://codeigniter.com/user_guide/license.html * @link http://codeigniter.com * @since Version 1.0 @@ -32,15 +32,21 @@ */ class CI_Zip { - var $zipdata = ''; - var $directory = ''; - var $entries = 0; - var $file_num = 0; + var $zipdata = ''; + var $directory = ''; + var $entries = 0; + var $file_num = 0; var $offset = 0; + var $now; - function CI_Zip() + /** + * Constructor + */ + public function __construct() { log_message('debug', "Zip Compression Class Initialized"); + + $this->now = time(); } // -------------------------------------------------------------------- @@ -63,25 +69,50 @@ class CI_Zip { $dir .= '/'; } - $this->_add_dir($dir); + $dir_time = $this->_get_mod_time($dir); + + $this->_add_dir($dir, $dir_time['file_mtime'], $dir_time['file_mdate']); } } // -------------------------------------------------------------------- /** + * Get file/directory modification time + * + * If this is a newly created file/dir, we will set the time to 'now' + * + * @param string path to file + * @return array filemtime/filemdate + */ + function _get_mod_time($dir) + { + // filemtime() will return false, but it does raise an error. + $date = (@filemtime($dir)) ? filemtime($dir) : getdate($this->now); + + $time['file_mtime'] = ($date['hours'] << 11) + ($date['minutes'] << 5) + $date['seconds'] / 2; + $time['file_mdate'] = (($date['year'] - 1980) << 9) + ($date['mon'] << 5) + $date['mday']; + + return $time; + } + + // -------------------------------------------------------------------- + + /** * Add Directory * * @access private * @param string the directory name * @return void */ - function _add_dir($dir) + function _add_dir($dir, $file_mtime, $file_mdate) { $dir = str_replace("\\", "/", $dir); $this->zipdata .= - "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00" + .pack('v', $file_mtime) + .pack('v', $file_mdate) .pack('V', 0) // crc32 .pack('V', 0) // compressed filesize .pack('V', 0) // uncompressed filesize @@ -94,7 +125,9 @@ class CI_Zip { .pack('V', 0); // uncompressed filesize $this->directory .= - "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00" + .pack('v', $file_mtime) + .pack('v', $file_mdate) .pack('V',0) // crc32 .pack('V',0) // compressed filesize .pack('V',0) // uncompressed filesize @@ -110,7 +143,7 @@ class CI_Zip { $this->offset = strlen($this->zipdata); $this->entries++; } - + // -------------------------------------------------------------------- /** @@ -124,19 +157,23 @@ class CI_Zip { * @param mixed * @param string * @return void - */ + */ function add_data($filepath, $data = NULL) { if (is_array($filepath)) { foreach ($filepath as $path => $data) { - $this->_add_data($path, $data); + $file_data = $this->_get_mod_time($path); + + $this->_add_data($path, $data, $file_data['file_mtime'], $file_data['file_mdate']); } } else { - $this->_add_data($filepath, $data); + $file_data = $this->_get_mod_time($filepath); + + $this->_add_data($filepath, $data, $file_data['file_mtime'], $file_data['file_mdate']); } } @@ -149,8 +186,8 @@ class CI_Zip { * @param string the file name/path * @param string the data to be encoded * @return void - */ - function _add_data($filepath, $data) + */ + function _add_data($filepath, $data, $file_mtime, $file_mdate) { $filepath = str_replace("\\", "/", $filepath); @@ -162,7 +199,9 @@ class CI_Zip { $compressed_size = strlen($gzdata); $this->zipdata .= - "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00" + .pack('v', $file_mtime) + .pack('v', $file_mdate) .pack('V', $crc32) .pack('V', $compressed_size) .pack('V', $uncompressed_size) @@ -172,7 +211,9 @@ class CI_Zip { .$gzdata; // "file data" segment $this->directory .= - "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00\x00\x00\x00\x00" + "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00" + .pack('v', $file_mtime) + .pack('v', $file_mdate) .pack('V', $crc32) .pack('V', $compressed_size) .pack('V', $uncompressed_size) @@ -189,7 +230,7 @@ class CI_Zip { $this->entries++; $this->file_num++; } - + // -------------------------------------------------------------------- /** @@ -197,7 +238,7 @@ class CI_Zip { * * @access public * @return bool - */ + */ function read_file($path, $preserve_filepath = FALSE) { if ( ! file_exists($path)) @@ -208,7 +249,7 @@ class CI_Zip { if (FALSE !== ($data = file_get_contents($path))) { $name = str_replace("\\", "/", $path); - + if ($preserve_filepath === FALSE) { $name = preg_replace("|.*/(.+)|", "\\1", $name); @@ -221,7 +262,7 @@ class CI_Zip { } // ------------------------------------------------------------------------ - + /** * Read a directory and add it to the zip. * @@ -232,27 +273,48 @@ class CI_Zip { * @access public * @param string path to source * @return bool - */ - function read_dir($path) - { - if ($fp = @opendir($path)) + */ + function read_dir($path, $preserve_filepath = TRUE, $root_path = NULL) + { + if ( ! $fp = @opendir($path)) { - while (FALSE !== ($file = readdir($fp))) + return FALSE; + } + + // Set the original directory root for child dir's to use as relative + if ($root_path === NULL) + { + $root_path = dirname($path).'/'; + } + + while (FALSE !== ($file = readdir($fp))) + { + if(substr($file, 0, 1) == '.') { - if (@is_dir($path.$file) && substr($file, 0, 1) != '.') - { - $this->read_dir($path.$file."/"); - } - elseif (substr($file, 0, 1) != ".") + continue; + } + + if (@is_dir($path.$file)) + { + $this->read_dir($path.$file."/", $preserve_filepath, $root_path); + } + else + { + if (FALSE !== ($data = file_get_contents($path.$file))) { - if (FALSE !== ($data = file_get_contents($path.$file))) - { - $this->add_data(str_replace("\\", "/", $path).$file, $data); + $name = str_replace("\\", "/", $path); + + if ($preserve_filepath === FALSE) + { + $name = str_replace($root_path, '', $name); } + + $this->add_data($name.$file, $data); } } - return TRUE; } + + return TRUE; } // -------------------------------------------------------------------- @@ -262,7 +324,7 @@ class CI_Zip { * * @access public * @return binary string - */ + */ function get_zip() { // Is there any data to return? @@ -281,7 +343,7 @@ class CI_Zip { return $zip_data; } - + // -------------------------------------------------------------------- /** @@ -292,7 +354,7 @@ class CI_Zip { * @access public * @param string the file name * @return bool - */ + */ function archive($filepath) { if ( ! ($fp = @fopen($filepath, FOPEN_WRITE_CREATE_DESTRUCTIVE))) @@ -300,12 +362,12 @@ class CI_Zip { return FALSE; } - flock($fp, LOCK_EX); + flock($fp, LOCK_EX); fwrite($fp, $this->get_zip()); flock($fp, LOCK_UN); fclose($fp); - return TRUE; + return TRUE; } // -------------------------------------------------------------------- @@ -325,11 +387,13 @@ class CI_Zip { $filename .= '.zip'; } - $zip_content =& $this->get_zip(); - $CI =& get_instance(); $CI->load->helper('download'); + $get_zip = $this->get_zip(); + + $zip_content =& $get_zip; + force_download($filename, $zip_content); } @@ -343,7 +407,7 @@ class CI_Zip { * * @access public * @return void - */ + */ function clear_data() { $this->zipdata = ''; @@ -352,7 +416,7 @@ class CI_Zip { $this->file_num = 0; $this->offset = 0; } - + } /* End of file Zip.php */ diff --git a/system/libraries/index.html b/system/libraries/index.html index c942a79ce..c942a79ce 100644..100755 --- a/system/libraries/index.html +++ b/system/libraries/index.html diff --git a/system/libraries/javascript/Jquery.php b/system/libraries/javascript/Jquery.php new file mode 100755 index 000000000..baab83d25 --- /dev/null +++ b/system/libraries/javascript/Jquery.php @@ -0,0 +1,1071 @@ +<?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) 2008 - 2011, EllisLab, Inc. + * @license http://www.codeigniter.com/user_guide/license.html + * @link http://www.codeigniter.com + * @since Version 1.0 + * @filesource + */ + +/** + * Jquery Class + * + * @package CodeIgniter + * @subpackage Libraries + * @author ExpressionEngine Dev Team + * @category Loader + * @link http://www.codeigniter.com/user_guide/libraries/javascript.html + */ + +class CI_Jquery extends CI_Javascript { + + var $_javascript_folder = 'js'; + var $jquery_code_for_load = array(); + var $jquery_code_for_compile = array(); + var $jquery_corner_active = FALSE; + var $jquery_table_sorter_active = FALSE; + var $jquery_table_sorter_pager_active = FALSE; + var $jquery_ajax_img = ''; + + public function __construct($params) + { + $this->CI =& get_instance(); + extract($params); + + if ($autoload === TRUE) + { + $this->script(); + } + + log_message('debug', "Jquery Class Initialized"); + } + + // -------------------------------------------------------------------- + // Event Code + // -------------------------------------------------------------------- + + /** + * Blur + * + * Outputs a jQuery blur event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _blur($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'blur'); + } + + // -------------------------------------------------------------------- + + /** + * Change + * + * Outputs a jQuery change event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _change($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'change'); + } + + // -------------------------------------------------------------------- + + /** + * Click + * + * Outputs a jQuery click event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @param boolean whether or not to return false + * @return string + */ + function _click($element = 'this', $js = '', $ret_false = TRUE) + { + if ( ! is_array($js)) + { + $js = array($js); + } + + if ($ret_false) + { + $js[] = "return false;"; + } + + return $this->_add_event($element, $js, 'click'); + } + + // -------------------------------------------------------------------- + + /** + * Double Click + * + * Outputs a jQuery dblclick event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _dblclick($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'dblclick'); + } + + // -------------------------------------------------------------------- + + /** + * Error + * + * Outputs a jQuery error event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _error($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'error'); + } + + // -------------------------------------------------------------------- + + /** + * Focus + * + * Outputs a jQuery focus event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _focus($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'focus'); + } + + // -------------------------------------------------------------------- + + /** + * Hover + * + * Outputs a jQuery hover event + * + * @access private + * @param string - element + * @param string - Javascript code for mouse over + * @param string - Javascript code for mouse out + * @return string + */ + function _hover($element = 'this', $over, $out) + { + $event = "\n\t$(" . $this->_prep_element($element) . ").hover(\n\t\tfunction()\n\t\t{\n\t\t\t{$over}\n\t\t}, \n\t\tfunction()\n\t\t{\n\t\t\t{$out}\n\t\t});\n"; + + $this->jquery_code_for_compile[] = $event; + + return $event; + } + + // -------------------------------------------------------------------- + + /** + * Keydown + * + * Outputs a jQuery keydown event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _keydown($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'keydown'); + } + + // -------------------------------------------------------------------- + + /** + * Keyup + * + * Outputs a jQuery keydown event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _keyup($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'keyup'); + } + + // -------------------------------------------------------------------- + + /** + * Load + * + * Outputs a jQuery load event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _load($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'load'); + } + + // -------------------------------------------------------------------- + + /** + * Mousedown + * + * Outputs a jQuery mousedown event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _mousedown($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mousedown'); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Out + * + * Outputs a jQuery mouseout event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _mouseout($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mouseout'); + } + + // -------------------------------------------------------------------- + + /** + * Mouse Over + * + * Outputs a jQuery mouseover event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _mouseover($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mouseover'); + } + + // -------------------------------------------------------------------- + + /** + * Mouseup + * + * Outputs a jQuery mouseup event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _mouseup($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'mouseup'); + } + + // -------------------------------------------------------------------- + + /** + * Output + * + * Outputs script directly + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _output($array_js = '') + { + if ( ! is_array($array_js)) + { + $array_js = array($array_js); + } + + foreach ($array_js as $js) + { + $this->jquery_code_for_compile[] = "\t$js\n"; + } + } + + // -------------------------------------------------------------------- + + /** + * Resize + * + * Outputs a jQuery resize event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _resize($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'resize'); + } + + // -------------------------------------------------------------------- + + /** + * Scroll + * + * Outputs a jQuery scroll event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _scroll($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'scroll'); + } + + // -------------------------------------------------------------------- + + /** + * Unload + * + * Outputs a jQuery unload event + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @return string + */ + function _unload($element = 'this', $js = '') + { + return $this->_add_event($element, $js, 'unload'); + } + + // -------------------------------------------------------------------- + // Effects + // -------------------------------------------------------------------- + + /** + * Add Class + * + * Outputs a jQuery addClass event + * + * @access private + * @param string - element + * @return string + */ + function _addClass($element = 'this', $class='') + { + $element = $this->_prep_element($element); + $str = "$({$element}).addClass(\"$class\");"; + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Animate + * + * Outputs a jQuery animate event + * + * @access private + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _animate($element = 'this', $params = array(), $speed = '', $extra = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + $animations = "\t\t\t"; + + foreach ($params as $param=>$value) + { + $animations .= $param.': \''.$value.'\', '; + } + + $animations = substr($animations, 0, -2); // remove the last ", " + + if ($speed != '') + { + $speed = ', '.$speed; + } + + if ($extra != '') + { + $extra = ', '.$extra; + } + + $str = "$({$element}).animate({\n$animations\n\t\t}".$speed.$extra.");"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Fade In + * + * Outputs a jQuery hide event + * + * @access private + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _fadeIn($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback != '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + $str = "$({$element}).fadeIn({$speed}{$callback});"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Fade Out + * + * Outputs a jQuery hide event + * + * @access private + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _fadeOut($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback != '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + $str = "$({$element}).fadeOut({$speed}{$callback});"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Hide + * + * Outputs a jQuery hide action + * + * @access private + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _hide($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback != '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + $str = "$({$element}).hide({$speed}{$callback});"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Remove Class + * + * Outputs a jQuery remove class event + * + * @access private + * @param string - element + * @return string + */ + function _removeClass($element = 'this', $class='') + { + $element = $this->_prep_element($element); + $str = "$({$element}).removeClass(\"$class\");"; + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Slide Up + * + * Outputs a jQuery slideUp event + * + * @access private + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _slideUp($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback != '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + $str = "$({$element}).slideUp({$speed}{$callback});"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Slide Down + * + * Outputs a jQuery slideDown event + * + * @access private + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _slideDown($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback != '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + $str = "$({$element}).slideDown({$speed}{$callback});"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Slide Toggle + * + * Outputs a jQuery slideToggle event + * + * @access public + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _slideToggle($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback != '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + $str = "$({$element}).slideToggle({$speed}{$callback});"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Toggle + * + * Outputs a jQuery toggle event + * + * @access private + * @param string - element + * @return string + */ + function _toggle($element = 'this') + { + $element = $this->_prep_element($element); + $str = "$({$element}).toggle();"; + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Toggle Class + * + * Outputs a jQuery toggle class event + * + * @access private + * @param string - element + * @return string + */ + function _toggleClass($element = 'this', $class='') + { + $element = $this->_prep_element($element); + $str = "$({$element}).toggleClass(\"$class\");"; + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Show + * + * Outputs a jQuery show event + * + * @access private + * @param string - element + * @param string - One of 'slow', 'normal', 'fast', or time in milliseconds + * @param string - Javascript callback function + * @return string + */ + function _show($element = 'this', $speed = '', $callback = '') + { + $element = $this->_prep_element($element); + $speed = $this->_validate_speed($speed); + + if ($callback != '') + { + $callback = ", function(){\n{$callback}\n}"; + } + + $str = "$({$element}).show({$speed}{$callback});"; + + return $str; + } + + // -------------------------------------------------------------------- + + /** + * Updater + * + * An Ajax call that populates the designated DOM node with + * returned content + * + * @access private + * @param string The element to attach the event to + * @param string the controller to run the call against + * @param string optional parameters + * @return string + */ + + function _updater($container = 'this', $controller, $options = '') + { + $container = $this->_prep_element($container); + + $controller = (strpos('://', $controller) === FALSE) ? $controller : $this->CI->config->site_url($controller); + + // ajaxStart and ajaxStop are better choices here... but this is a stop gap + if ($this->CI->config->item('javascript_ajax_img') == '') + { + $loading_notifier = "Loading..."; + } + else + { + $loading_notifier = '<img src=\'' . $this->CI->config->slash_item('base_url') . $this->CI->config->item('javascript_ajax_img') . '\' alt=\'Loading\' />'; + } + + $updater = "$($container).empty();\n"; // anything that was in... get it out + $updater .= "\t\t$($container).prepend(\"$loading_notifier\");\n"; // to replace with an image + + $request_options = ''; + if ($options != '') + { + $request_options .= ", {"; + $request_options .= (is_array($options)) ? "'".implode("', '", $options)."'" : "'".str_replace(":", "':'", $options)."'"; + $request_options .= "}"; + } + + $updater .= "\t\t$($container).load('$controller'$request_options);"; + return $updater; + } + + + // -------------------------------------------------------------------- + // Pre-written handy stuff + // -------------------------------------------------------------------- + + /** + * Zebra tables + * + * @access private + * @param string table name + * @param string plugin location + * @return string + */ + function _zebraTables($class = '', $odd = 'odd', $hover = '') + { + $class = ($class != '') ? '.'.$class : ''; + + $zebra = "\t\$(\"table{$class} tbody tr:nth-child(even)\").addClass(\"{$odd}\");"; + + $this->jquery_code_for_compile[] = $zebra; + + if ($hover != '') + { + $hover = $this->hover("table{$class} tbody tr", "$(this).addClass('hover');", "$(this).removeClass('hover');"); + } + + return $zebra; + } + + + + // -------------------------------------------------------------------- + // Plugins + // -------------------------------------------------------------------- + + /** + * Corner Plugin + * + * http://www.malsup.com/jquery/corner/ + * + * @access public + * @param string target + * @return string + */ + function corner($element = '', $corner_style = '') + { + // may want to make this configurable down the road + $corner_location = '/plugins/jquery.corner.js'; + + if ($corner_style != '') + { + $corner_style = '"'.$corner_style.'"'; + } + + return "$(" . $this->_prep_element($element) . ").corner(".$corner_style.");"; + } + + // -------------------------------------------------------------------- + + /** + * modal window + * + * Load a thickbox modal window + * + * @access public + * @return void + */ + function modal($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + + // -------------------------------------------------------------------- + + /** + * Effect + * + * Load an Effect library + * + * @access public + * @return void + */ + function effect($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + + // -------------------------------------------------------------------- + + /** + * Plugin + * + * Load a plugin library + * + * @access public + * @return void + */ + function plugin($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + + // -------------------------------------------------------------------- + + /** + * UI + * + * Load a user interface library + * + * @access public + * @return void + */ + function ui($src, $relative = FALSE) + { + $this->jquery_code_for_load[] = $this->external($src, $relative); + } + // -------------------------------------------------------------------- + + /** + * Sortable + * + * Creates a jQuery sortable + * + * @access public + * @return void + */ + function sortable($element, $options = array()) + { + + if (count($options) > 0) + { + $sort_options = array(); + foreach ($options as $k=>$v) + { + $sort_options[] = "\n\t\t".$k.': '.$v.""; + } + $sort_options = implode(",", $sort_options); + } + else + { + $sort_options = ''; + } + + return "$(" . $this->_prep_element($element) . ").sortable({".$sort_options."\n\t});"; + } + + // -------------------------------------------------------------------- + + /** + * Table Sorter Plugin + * + * @access public + * @param string table name + * @param string plugin location + * @return string + */ + function tablesorter($table = '', $options = '') + { + $this->jquery_code_for_compile[] = "\t$(" . $this->_prep_element($table) . ").tablesorter($options);\n"; + } + + // -------------------------------------------------------------------- + // Class functions + // -------------------------------------------------------------------- + + /** + * Add Event + * + * Constructs the syntax for an event, and adds to into the array for compilation + * + * @access private + * @param string The element to attach the event to + * @param string The code to execute + * @param string The event to pass + * @return string + */ + function _add_event($element, $js, $event) + { + if (is_array($js)) + { + $js = implode("\n\t\t", $js); + + } + + $event = "\n\t$(" . $this->_prep_element($element) . ").{$event}(function(){\n\t\t{$js}\n\t});\n"; + $this->jquery_code_for_compile[] = $event; + return $event; + } + + // -------------------------------------------------------------------- + + /** + * Compile + * + * As events are specified, they are stored in an array + * This funciton compiles them all for output on a page + * + * @access private + * @return string + */ + function _compile($view_var = 'script_foot', $script_tags = TRUE) + { + // External references + $external_scripts = implode('', $this->jquery_code_for_load); + $this->CI->load->vars(array('library_src' => $external_scripts)); + + if (count($this->jquery_code_for_compile) == 0 ) + { + // no inline references, let's just return + return; + } + + // Inline references + $script = '$(document).ready(function() {' . "\n"; + $script .= implode('', $this->jquery_code_for_compile); + $script .= '});'; + + $output = ($script_tags === FALSE) ? $script : $this->inline($script); + + $this->CI->load->vars(array($view_var => $output)); + + } + + // -------------------------------------------------------------------- + + /** + * Clear Compile + * + * Clears the array of script events collected for output + * + * @access public + * @return void + */ + function _clear_compile() + { + $this->jquery_code_for_compile = array(); + } + + // -------------------------------------------------------------------- + + /** + * Document Ready + * + * A wrapper for writing document.ready() + * + * @access private + * @return string + */ + function _document_ready($js) + { + if ( ! is_array($js)) + { + $js = array ($js); + + } + + foreach ($js as $script) + { + $this->jquery_code_for_compile[] = $script; + } + } + + // -------------------------------------------------------------------- + + /** + * Script Tag + * + * Outputs the script tag that loads the jquery.js file into an HTML document + * + * @access public + * @param string + * @return string + */ + function script($library_src = '', $relative = FALSE) + { + $library_src = $this->external($library_src, $relative); + $this->jquery_code_for_load[] = $library_src; + return $library_src; + } + + // -------------------------------------------------------------------- + + /** + * Prep Element + * + * Puts HTML element in quotes for use in jQuery code + * unless the supplied element is the Javascript 'this' + * object, in which case no quotes are added + * + * @access public + * @param string + * @return string + */ + function _prep_element($element) + { + if ($element != 'this') + { + $element = '"'.$element.'"'; + } + + return $element; + } + + // -------------------------------------------------------------------- + + /** + * Validate Speed + * + * Ensures the speed parameter is valid for jQuery + * + * @access private + * @param string + * @return string + */ + function _validate_speed($speed) + { + if (in_array($speed, array('slow', 'normal', 'fast'))) + { + $speed = '"'.$speed.'"'; + } + elseif (preg_match("/[^0-9]/", $speed)) + { + $speed = ''; + } + + return $speed; + } + +} + +/* End of file Jquery.php */ +/* Location: ./system/libraries/Jquery.php */
\ No newline at end of file |