summaryrefslogtreecommitdiffstats
path: root/system/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'system/helpers')
-rw-r--r--system/helpers/array_helper.php78
-rw-r--r--system/helpers/compatibility_helper.php498
-rw-r--r--system/helpers/cookie_helper.php144
-rw-r--r--system/helpers/date_helper.php611
-rw-r--r--system/helpers/directory_helper.php84
-rw-r--r--system/helpers/download_helper.php100
-rw-r--r--system/helpers/email_helper.php62
-rw-r--r--system/helpers/file_helper.php464
-rw-r--r--system/helpers/form_helper.php1025
-rw-r--r--system/helpers/html_helper.php416
-rw-r--r--system/helpers/index.html10
-rw-r--r--system/helpers/inflector_helper.php171
-rw-r--r--system/helpers/language_helper.php58
-rw-r--r--system/helpers/number_helper.php75
-rw-r--r--system/helpers/path_helper.php72
-rw-r--r--system/helpers/security_helper.php126
-rw-r--r--system/helpers/smiley_helper.php273
-rw-r--r--system/helpers/string_helper.php273
-rw-r--r--system/helpers/text_helper.php462
-rw-r--r--system/helpers/typography_helper.php71
-rw-r--r--system/helpers/url_helper.php593
-rw-r--r--system/helpers/xml_helper.php62
22 files changed, 5728 insertions, 0 deletions
diff --git a/system/helpers/array_helper.php b/system/helpers/array_helper.php
new file mode 100644
index 000000000..39d0c88c6
--- /dev/null
+++ b/system/helpers/array_helper.php
@@ -0,0 +1,78 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Array Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/array_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Element
+ *
+ * Lets you determine whether an array index is set and whether it has a value.
+ * If the element is empty it returns FALSE (or whatever you specify as the default value.)
+ *
+ * @access public
+ * @param string
+ * @param array
+ * @param mixed
+ * @return mixed depends on what the array contains
+ */
+if ( ! function_exists('element'))
+{
+ function element($item, $array, $default = FALSE)
+ {
+ if ( ! isset($array[$item]) OR $array[$item] == "")
+ {
+ return $default;
+ }
+
+ return $array[$item];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Random Element - Takes an array as input and returns a random element
+ *
+ * @access public
+ * @param array
+ * @return mixed depends on what the array contains
+ */
+if ( ! function_exists('random_element'))
+{
+ function random_element($array)
+ {
+ if ( ! is_array($array))
+ {
+ return $array;
+ }
+ return $array[array_rand($array)];
+ }
+}
+
+
+/* End of file array_helper.php */
+/* Location: ./system/helpers/array_helper.php */ \ No newline at end of file
diff --git a/system/helpers/compatibility_helper.php b/system/helpers/compatibility_helper.php
new file mode 100644
index 000000000..c217f7f52
--- /dev/null
+++ b/system/helpers/compatibility_helper.php
@@ -0,0 +1,498 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Compatibility Helpers
+ *
+ * This helper contains some functions based on the PEAR PHP_Compat library
+ * http://pear.php.net/package/PHP_Compat
+ *
+ * The PEAR compat library is a little bloated and the code doesn't harmonize
+ * well with CodeIgniter, so those functions have been refactored.
+ * We cheat a little and use CI's _exception_handler() to output our own PHP errors
+ * so that the behavior fully mimicks the PHP 5 counterparts. -- Derek Jones
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/compatibility_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+if ( ! defined('PHP_EOL'))
+{
+ define('PHP_EOL', (DIRECTORY_SEPARATOR == '/') ? "\n" : "\r\n");
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * file_put_contents()
+ *
+ * Writes a string to a file
+ * http://us.php.net/manual/en/function.file_put_contents.php
+ * argument 4, $context, not supported
+ *
+ * @access public
+ * @param string file name
+ * @param mixed data to be written
+ * @param int flags
+ * @return int length of written string
+ */
+if ( ! function_exists('file_put_contents'))
+{
+ function file_put_contents($filename, $data, $flags = NULL)
+ {
+ if (is_scalar($data))
+ {
+ settype($data, 'STRING');
+ }
+
+ if ( ! is_string($data) && ! is_array($data) && ! is_resource($data))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'file_put_contents(): the 2nd parameter should be either a string or an array', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ // read stream if given a stream resource
+ if (is_resource($data))
+ {
+ if (get_resource_type($data) !== 'stream')
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'file_put_contents(): supplied resource is not a valid stream resource', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ $text = '';
+
+ while ( ! feof($data))
+ {
+ $text .= fread($data, 4096);
+ }
+
+ $data = $text;
+ unset($text);
+ }
+
+ // strings only please!
+ if (is_array($data))
+ {
+ $data = implode('', $data);
+ }
+
+ // Set the appropriate mode
+ if (($flags & 8) > 0) // 8 = FILE_APPEND flag
+ {
+ $mode = FOPEN_WRITE_CREATE;
+ }
+ else
+ {
+ $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE;
+ }
+
+ // Check if we're using the include path
+ if (($flags & 1) > 0) // 1 = FILE_USE_INCLUDE_PATH flag
+ {
+ $use_include_path = TRUE;
+ }
+ else
+ {
+ $use_include_path = FALSE;
+ }
+
+ $fp = @fopen($filename, $mode, $use_include_path);
+
+ if ($fp === FALSE)
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to open stream', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ if (($flags & LOCK_EX) > 0)
+ {
+ if ( ! flock($fp, LOCK_EX))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') unable to acquire an exclusive lock on file', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+ }
+
+ // write it
+ if (($written = @fwrite($fp, $data)) === FALSE)
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'file_put_contents('.htmlentities($filename).') failed to write to '.htmlentities($filename), $backtrace[0]['file'], $backtrace[0]['line']);
+ }
+
+ // Close the handle
+ @fclose($fp);
+
+ // Return length
+ return $written;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * fputcsv()
+ *
+ * Format line as CSV and write to file pointer
+ * http://us.php.net/manual/en/function.fputcsv.php
+ *
+ * @access public
+ * @param resource file pointer
+ * @param array data to be written
+ * @param string delimiter
+ * @param string enclosure
+ * @return int length of written string
+ */
+if ( ! function_exists('fputcsv'))
+{
+ function fputcsv($handle, $fields, $delimiter = ',', $enclosure = '"')
+ {
+ // Checking for a handle resource
+ if ( ! is_resource($handle))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.gettype($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ // OK, it is a resource, but is it a stream?
+ if (get_resource_type($handle) !== 'stream')
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 1 to be stream resource, '.get_resource_type($handle).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ // Checking for an array of fields
+ if ( ! is_array($fields))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'fputcsv() expects parameter 2 to be array, '.gettype($fields).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ // validate delimiter
+ if (strlen($delimiter) > 1)
+ {
+ $delimiter = substr($delimiter, 0, 1);
+ $backtrace = debug_backtrace();
+ _exception_handler(E_NOTICE, 'fputcsv() delimiter must be one character long, "'.htmlentities($delimiter).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
+ }
+
+ // validate enclosure
+ if (strlen($enclosure) > 1)
+ {
+ $enclosure = substr($enclosure, 0, 1);
+ $backtrace = debug_backtrace();
+ _exception_handler(E_NOTICE, 'fputcsv() enclosure must be one character long, "'.htmlentities($enclosure).'" used', $backtrace[0]['file'], $backtrace[0]['line']);
+
+ }
+
+ $out = '';
+
+ foreach ($fields as $cell)
+ {
+ $cell = str_replace($enclosure, $enclosure.$enclosure, $cell);
+
+ if (strpos($cell, $delimiter) !== FALSE OR strpos($cell, $enclosure) !== FALSE OR strpos($cell, "\n") !== FALSE)
+ {
+ $out .= $enclosure.$cell.$enclosure.$delimiter;
+ }
+ else
+ {
+ $out .= $cell.$delimiter;
+ }
+ }
+
+ $length = @fwrite($handle, substr($out, 0, -1)."\n");
+
+ return $length;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * stripos()
+ *
+ * Find position of first occurrence of a case-insensitive string
+ * http://us.php.net/manual/en/function.stripos.php
+ *
+ * @access public
+ * @param string haystack
+ * @param string needle
+ * @param int offset
+ * @return int numeric position of the first occurrence of needle in the haystack
+ */
+if ( ! function_exists('stripos'))
+{
+ function stripos($haystack, $needle, $offset = NULL)
+ {
+ // Cast non string scalar values
+ if (is_scalar($haystack))
+ {
+ settype($haystack, 'STRING');
+ }
+
+ if ( ! is_string($haystack))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'stripos() expects parameter 1 to be string, '.gettype($haystack).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ if ( ! is_scalar($needle))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'stripos() needle is not a string or an integer in '.$backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ if (is_float($offset))
+ {
+ $offset = (int)$offset;
+ }
+
+ if ( ! is_int($offset) && ! is_bool($offset) && ! is_null($offset))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'stripos() expects parameter 3 to be long, '.gettype($offset).' given', $backtrace[0]['file'], $backtrace[0]['line']);
+ return NULL;
+ }
+
+ return strpos(strtolower($haystack), strtolower($needle), $offset);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * str_ireplace()
+ *
+ * Find position of first occurrence of a case-insensitive string
+ * http://us.php.net/manual/en/function.str-ireplace.php
+ * (parameter 4, $count, is not supported as to do so in PHP 4 would make
+ * it a required parameter)
+ *
+ * @access public
+ * @param mixed search
+ * @param mixed replace
+ * @param mixed subject
+ * @return int numeric position of the first occurrence of needle in the haystack
+ */
+if ( ! function_exists('str_ireplace'))
+{
+ function str_ireplace($search, $replace, $subject)
+ {
+ // Nothing to do here
+ if ($search === NULL OR $subject === NULL)
+ {
+ return $subject;
+ }
+
+ // Crazy arguments
+ if (is_scalar($search) && is_array($replace))
+ {
+ $backtrace = debug_backtrace();
+
+ if (is_object($replace))
+ {
+ show_error('Object of class '.get_class($replace).' could not be converted to string in '.$backtrace[0]['file'].' on line '.$backtrace[0]['line']);
+ }
+ else
+ {
+ _exception_handler(E_USER_NOTICE, 'Array to string conversion in '.$backtrace[0]['file'], $backtrace[0]['line']);
+ }
+ }
+
+ // Searching for an array
+ if (is_array($search))
+ {
+ // Replacing with an array
+ if (is_array($replace))
+ {
+ $search = array_values($search);
+ $replace = array_values($replace);
+
+ if (count($search) >= count($replace))
+ {
+ $replace = array_pad($replace, count($search), '');
+ }
+ else
+ {
+ $replace = array_slice($replace, 0, count($search));
+ }
+ }
+ else
+ {
+ // Replacing with a string all positions
+ $replace = array_fill(0, count($search), $replace);
+ }
+ }
+ else
+ {
+ //Searching for a string and replacing with a string.
+ $search = array((string)$search);
+ $replace = array((string)$replace);
+ }
+
+ // Prepare the search array
+ foreach ($search as $search_key => $search_value)
+ {
+ $search[$search_key] = '/'.preg_quote($search_value, '/').'/i';
+ }
+
+ // Prepare the replace array (escape backreferences)
+ foreach ($replace as $k => $v)
+ {
+ $replace[$k] = str_replace(array(chr(92), '$'), array(chr(92).chr(92), '\$'), $v);
+ }
+
+ // do the replacement
+ $result = preg_replace($search, $replace, (array)$subject);
+
+ // Check if subject was initially a string and return it as a string
+ if ( ! is_array($subject))
+ {
+ return current($result);
+ }
+
+ // Otherwise, just return the array
+ return $result;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * http_build_query()
+ *
+ * Generate URL-encoded query string
+ * http://us.php.net/manual/en/function.http-build-query.php
+ *
+ * @access public
+ * @param array form data
+ * @param string numeric prefix
+ * @param string argument separator
+ * @return string URL-encoded string
+ */
+if ( ! function_exists('http_build_query'))
+{
+ function http_build_query($formdata, $numeric_prefix = NULL, $separator = NULL)
+ {
+ // Check the data
+ if ( ! is_array($formdata) && ! is_object($formdata))
+ {
+ $backtrace = debug_backtrace();
+ _exception_handler(E_USER_WARNING, 'http_build_query() Parameter 1 expected to be Array or Object. Incorrect value given', $backtrace[0]['file'], $backtrace[0]['line']);
+ return FALSE;
+ }
+
+ // Cast it as array
+ if (is_object($formdata))
+ {
+ $formdata = get_object_vars($formdata);
+ }
+
+ // If the array is empty, return NULL
+ if (empty($formdata))
+ {
+ return NULL;
+ }
+
+ // Argument separator
+ if ($separator === NULL)
+ {
+ $separator = ini_get('arg_separator.output');
+
+ if (strlen($separator) == 0)
+ {
+ $separator = '&';
+ }
+ }
+
+ // Start building the query
+ $tmp = array();
+
+ foreach ($formdata as $key => $val)
+ {
+ if ($val === NULL)
+ {
+ continue;
+ }
+
+ if (is_integer($key) && $numeric_prefix != NULL)
+ {
+ $key = $numeric_prefix.$key;
+ }
+
+ if (is_resource($val))
+ {
+ return NULL;
+ }
+
+ // hand it off to a recursive parser
+ $tmp[] = _http_build_query_helper($key, $val, $separator);
+ }
+
+ return implode($separator, $tmp);
+ }
+
+
+ // Helper helper. Remind anyone of college?
+ // Required to handle recursion in nested arrays.
+ //
+ // You could shave fractions of fractions of a second by moving where
+ // the urlencoding takes place, but it's much less intuitive, and if
+ // your application has 10,000 form fields, well, you have other problems ;)
+ function _http_build_query_helper($key, $val, $separator = '&')
+ {
+ if (is_scalar($val))
+ {
+ return urlencode($key).'='.urlencode($val);
+ }
+ else
+ {
+ // arrays please
+ if (is_object($val))
+ {
+ $val = get_object_vars($val);
+ }
+
+ foreach ($val as $k => $v)
+ {
+ $tmp[] = _http_build_query_helper($key.'['.$k.']', $v, $separator);
+ }
+ }
+
+ return implode($separator, $tmp);
+ }
+}
+
+
+/* End of file compatibility_helper.php */
+/* Location: ./system/helpers/compatibility_helper.php */ \ No newline at end of file
diff --git a/system/helpers/cookie_helper.php b/system/helpers/cookie_helper.php
new file mode 100644
index 000000000..7607ffb4a
--- /dev/null
+++ b/system/helpers/cookie_helper.php
@@ -0,0 +1,144 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Cookie Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/cookie_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set cookie
+ *
+ * Accepts six parameter, or you can submit an associative
+ * array in the first parameter containing all the values.
+ *
+ * @access public
+ * @param mixed
+ * @param string the value of the cookie
+ * @param string the number of seconds until expiration
+ * @param string the cookie domain. Usually: .yourdomain.com
+ * @param string the cookie path
+ * @param string the cookie prefix
+ * @return void
+ */
+if ( ! function_exists('set_cookie'))
+{
+ function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '')
+ {
+ if (is_array($name))
+ {
+ foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'name') as $item)
+ {
+ if (isset($name[$item]))
+ {
+ $$item = $name[$item];
+ }
+ }
+ }
+
+ // Set the config file options
+ $CI =& get_instance();
+
+ if ($prefix == '' AND $CI->config->item('cookie_prefix') != '')
+ {
+ $prefix = $CI->config->item('cookie_prefix');
+ }
+ if ($domain == '' AND $CI->config->item('cookie_domain') != '')
+ {
+ $domain = $CI->config->item('cookie_domain');
+ }
+ if ($path == '/' AND $CI->config->item('cookie_path') != '/')
+ {
+ $path = $CI->config->item('cookie_path');
+ }
+
+ if ( ! is_numeric($expire))
+ {
+ $expire = time() - 86500;
+ }
+ else
+ {
+ if ($expire > 0)
+ {
+ $expire = time() + $expire;
+ }
+ else
+ {
+ $expire = 0;
+ }
+ }
+
+ setcookie($prefix.$name, $value, $expire, $path, $domain, 0);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Fetch an item from the COOKIE array
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return mixed
+ */
+if ( ! function_exists('get_cookie'))
+{
+ function get_cookie($index = '', $xss_clean = FALSE)
+ {
+ $CI =& get_instance();
+
+ $prefix = '';
+
+ if ( ! isset($_COOKIE[$index]) && config_item('cookie_prefix') != '')
+ {
+ $prefix = config_item('cookie_prefix');
+ }
+
+ return $CI->input->cookie($prefix.$index, $xss_clean);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Delete a COOKIE
+ *
+ * @param mixed
+ * @param string the cookie domain. Usually: .yourdomain.com
+ * @param string the cookie path
+ * @param string the cookie prefix
+ * @return void
+ */
+if ( ! function_exists('delete_cookie'))
+{
+ function delete_cookie($name = '', $domain = '', $path = '/', $prefix = '')
+ {
+ set_cookie($name, '', '', $domain, $path, $prefix);
+ }
+}
+
+
+/* End of file cookie_helper.php */
+/* Location: ./system/helpers/cookie_helper.php */ \ No newline at end of file
diff --git a/system/helpers/date_helper.php b/system/helpers/date_helper.php
new file mode 100644
index 000000000..fae9e66e4
--- /dev/null
+++ b/system/helpers/date_helper.php
@@ -0,0 +1,611 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Date Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/date_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get "now" time
+ *
+ * Returns time() or its GMT equivalent based on the config file preference
+ *
+ * @access public
+ * @return integer
+ */
+if ( ! function_exists('now'))
+{
+ function now()
+ {
+ $CI =& get_instance();
+
+ if (strtolower($CI->config->item('time_reference')) == 'gmt')
+ {
+ $now = time();
+ $system_time = mktime(gmdate("H", $now), gmdate("i", $now), gmdate("s", $now), gmdate("m", $now), gmdate("d", $now), gmdate("Y", $now));
+
+ if (strlen($system_time) < 10)
+ {
+ $system_time = time();
+ log_message('error', 'The Date class could not set a proper GMT timestamp so the local time() value was used.');
+ }
+
+ return $system_time;
+ }
+ else
+ {
+ return time();
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert MySQL Style Datecodes
+ *
+ * This function is identical to PHPs date() function,
+ * except that it allows date codes to be formatted using
+ * the MySQL style, where each code letter is preceded
+ * with a percent sign: %Y %m %d etc...
+ *
+ * The benefit of doing dates this way is that you don't
+ * have to worry about escaping your text letters that
+ * match the date codes.
+ *
+ * @access public
+ * @param string
+ * @param integer
+ * @return integer
+ */
+if ( ! function_exists('mdate'))
+{
+ function mdate($datestr = '', $time = '')
+ {
+ if ($datestr == '')
+ return '';
+
+ if ($time == '')
+ $time = now();
+
+ $datestr = str_replace('%\\', '', preg_replace("/([a-z]+?){1}/i", "\\\\\\1", $datestr));
+ return date($datestr, $time);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Standard Date
+ *
+ * Returns a date formatted according to the submitted standard.
+ *
+ * @access public
+ * @param string the chosen format
+ * @param integer Unix timestamp
+ * @return string
+ */
+if ( ! function_exists('standard_date'))
+{
+ function standard_date($fmt = 'DATE_RFC822', $time = '')
+ {
+ $formats = array(
+ 'DATE_ATOM' => '%Y-%m-%dT%H:%i:%s%Q',
+ 'DATE_COOKIE' => '%l, %d-%M-%y %H:%i:%s UTC',
+ 'DATE_ISO8601' => '%Y-%m-%dT%H:%i:%s%O',
+ 'DATE_RFC822' => '%D, %d %M %y %H:%i:%s %O',
+ 'DATE_RFC850' => '%l, %d-%M-%y %H:%m:%i UTC',
+ 'DATE_RFC1036' => '%D, %d %M %y %H:%i:%s %O',
+ 'DATE_RFC1123' => '%D, %d %M %Y %H:%i:%s %O',
+ 'DATE_RSS' => '%D, %d %M %Y %H:%i:%s %O',
+ 'DATE_W3C' => '%Y-%m-%dT%H:%i:%s%Q'
+ );
+
+ if ( ! isset($formats[$fmt]))
+ {
+ return FALSE;
+ }
+
+ return mdate($formats[$fmt], $time);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Timespan
+ *
+ * Returns a span of seconds in this format:
+ * 10 days 14 hours 36 minutes 47 seconds
+ *
+ * @access public
+ * @param integer a number of seconds
+ * @param integer Unix timestamp
+ * @return integer
+ */
+if ( ! function_exists('timespan'))
+{
+ function timespan($seconds = 1, $time = '')
+ {
+ $CI =& get_instance();
+ $CI->lang->load('date');
+
+ if ( ! is_numeric($seconds))
+ {
+ $seconds = 1;
+ }
+
+ if ( ! is_numeric($time))
+ {
+ $time = time();
+ }
+
+ if ($time <= $seconds)
+ {
+ $seconds = 1;
+ }
+ else
+ {
+ $seconds = $time - $seconds;
+ }
+
+ $str = '';
+ $years = floor($seconds / 31536000);
+
+ if ($years > 0)
+ {
+ $str .= $years.' '.$CI->lang->line((($years > 1) ? 'date_years' : 'date_year')).', ';
+ }
+
+ $seconds -= $years * 31536000;
+ $months = floor($seconds / 2628000);
+
+ if ($years > 0 OR $months > 0)
+ {
+ if ($months > 0)
+ {
+ $str .= $months.' '.$CI->lang->line((($months > 1) ? 'date_months' : 'date_month')).', ';
+ }
+
+ $seconds -= $months * 2628000;
+ }
+
+ $weeks = floor($seconds / 604800);
+
+ if ($years > 0 OR $months > 0 OR $weeks > 0)
+ {
+ if ($weeks > 0)
+ {
+ $str .= $weeks.' '.$CI->lang->line((($weeks > 1) ? 'date_weeks' : 'date_week')).', ';
+ }
+
+ $seconds -= $weeks * 604800;
+ }
+
+ $days = floor($seconds / 86400);
+
+ if ($months > 0 OR $weeks > 0 OR $days > 0)
+ {
+ if ($days > 0)
+ {
+ $str .= $days.' '.$CI->lang->line((($days > 1) ? 'date_days' : 'date_day')).', ';
+ }
+
+ $seconds -= $days * 86400;
+ }
+
+ $hours = floor($seconds / 3600);
+
+ if ($days > 0 OR $hours > 0)
+ {
+ if ($hours > 0)
+ {
+ $str .= $hours.' '.$CI->lang->line((($hours > 1) ? 'date_hours' : 'date_hour')).', ';
+ }
+
+ $seconds -= $hours * 3600;
+ }
+
+ $minutes = floor($seconds / 60);
+
+ if ($days > 0 OR $hours > 0 OR $minutes > 0)
+ {
+ if ($minutes > 0)
+ {
+ $str .= $minutes.' '.$CI->lang->line((($minutes > 1) ? 'date_minutes' : 'date_minute')).', ';
+ }
+
+ $seconds -= $minutes * 60;
+ }
+
+ if ($str == '')
+ {
+ $str .= $seconds.' '.$CI->lang->line((($seconds > 1) ? 'date_seconds' : 'date_second')).', ';
+ }
+
+ return substr(trim($str), 0, -1);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Number of days in a month
+ *
+ * Takes a month/year as input and returns the number of days
+ * for the given month/year. Takes leap years into consideration.
+ *
+ * @access public
+ * @param integer a numeric month
+ * @param integer a numeric year
+ * @return integer
+ */
+if ( ! function_exists('days_in_month'))
+{
+ function days_in_month($month = 0, $year = '')
+ {
+ if ($month < 1 OR $month > 12)
+ {
+ return 0;
+ }
+
+ if ( ! is_numeric($year) OR strlen($year) != 4)
+ {
+ $year = date('Y');
+ }
+
+ if ($month == 2)
+ {
+ if ($year % 400 == 0 OR ($year % 4 == 0 AND $year % 100 != 0))
+ {
+ return 29;
+ }
+ }
+
+ $days_in_month = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
+ return $days_in_month[$month - 1];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Converts a local Unix timestamp to GMT
+ *
+ * @access public
+ * @param integer Unix timestamp
+ * @return integer
+ */
+if ( ! function_exists('local_to_gmt'))
+{
+ function local_to_gmt($time = '')
+ {
+ if ($time == '')
+ $time = time();
+
+ return mktime( gmdate("H", $time), gmdate("i", $time), gmdate("s", $time), gmdate("m", $time), gmdate("d", $time), gmdate("Y", $time));
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Converts GMT time to a localized value
+ *
+ * Takes a Unix timestamp (in GMT) as input, and returns
+ * at the local value based on the timezone and DST setting
+ * submitted
+ *
+ * @access public
+ * @param integer Unix timestamp
+ * @param string timezone
+ * @param bool whether DST is active
+ * @return integer
+ */
+if ( ! function_exists('gmt_to_local'))
+{
+ function gmt_to_local($time = '', $timezone = 'UTC', $dst = FALSE)
+ {
+ if ($time == '')
+ {
+ return now();
+ }
+
+ $time += timezones($timezone) * 3600;
+
+ if ($dst == TRUE)
+ {
+ $time += 3600;
+ }
+
+ return $time;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Converts a MySQL Timestamp to Unix
+ *
+ * @access public
+ * @param integer Unix timestamp
+ * @return integer
+ */
+if ( ! function_exists('mysql_to_unix'))
+{
+ function mysql_to_unix($time = '')
+ {
+ // We'll remove certain characters for backward compatibility
+ // since the formatting changed with MySQL 4.1
+ // YYYY-MM-DD HH:MM:SS
+
+ $time = str_replace('-', '', $time);
+ $time = str_replace(':', '', $time);
+ $time = str_replace(' ', '', $time);
+
+ // YYYYMMDDHHMMSS
+ return mktime(
+ substr($time, 8, 2),
+ substr($time, 10, 2),
+ substr($time, 12, 2),
+ substr($time, 4, 2),
+ substr($time, 6, 2),
+ substr($time, 0, 4)
+ );
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Unix to "Human"
+ *
+ * Formats Unix timestamp to the following prototype: 2006-08-21 11:35 PM
+ *
+ * @access public
+ * @param integer Unix timestamp
+ * @param bool whether to show seconds
+ * @param string format: us or euro
+ * @return string
+ */
+if ( ! function_exists('unix_to_human'))
+{
+ function unix_to_human($time = '', $seconds = FALSE, $fmt = 'us')
+ {
+ $r = date('Y', $time).'-'.date('m', $time).'-'.date('d', $time).' ';
+
+ if ($fmt == 'us')
+ {
+ $r .= date('h', $time).':'.date('i', $time);
+ }
+ else
+ {
+ $r .= date('H', $time).':'.date('i', $time);
+ }
+
+ if ($seconds)
+ {
+ $r .= ':'.date('s', $time);
+ }
+
+ if ($fmt == 'us')
+ {
+ $r .= ' '.date('A', $time);
+ }
+
+ return $r;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert "human" date to GMT
+ *
+ * Reverses the above process
+ *
+ * @access public
+ * @param string format: us or euro
+ * @return integer
+ */
+if ( ! function_exists('human_to_unix'))
+{
+ function human_to_unix($datestr = '')
+ {
+ if ($datestr == '')
+ {
+ return FALSE;
+ }
+
+ $datestr = trim($datestr);
+ $datestr = preg_replace("/\040+/", "\040", $datestr);
+
+ if ( ! preg_match('/^[0-9]{2,4}\-[0-9]{1,2}\-[0-9]{1,2}\s[0-9]{1,2}:[0-9]{1,2}(?::[0-9]{1,2})?(?:\s[AP]M)?$/i', $datestr))
+ {
+ return FALSE;
+ }
+
+ $split = preg_split("/\040/", $datestr);
+
+ $ex = explode("-", $split['0']);
+
+ $year = (strlen($ex['0']) == 2) ? '20'.$ex['0'] : $ex['0'];
+ $month = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];
+ $day = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];
+
+ $ex = explode(":", $split['1']);
+
+ $hour = (strlen($ex['0']) == 1) ? '0'.$ex['0'] : $ex['0'];
+ $min = (strlen($ex['1']) == 1) ? '0'.$ex['1'] : $ex['1'];
+
+ if (isset($ex['2']) && preg_match('/[0-9]{1,2}/', $ex['2']))
+ {
+ $sec = (strlen($ex['2']) == 1) ? '0'.$ex['2'] : $ex['2'];
+ }
+ else
+ {
+ // Unless specified, seconds get set to zero.
+ $sec = '00';
+ }
+
+ if (isset($split['2']))
+ {
+ $ampm = strtolower($split['2']);
+
+ if (substr($ampm, 0, 1) == 'p' AND $hour < 12)
+ $hour = $hour + 12;
+
+ if (substr($ampm, 0, 1) == 'a' AND $hour == 12)
+ $hour = '00';
+
+ if (strlen($hour) == 1)
+ $hour = '0'.$hour;
+ }
+
+ return mktime($hour, $min, $sec, $month, $day, $year);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Timezone Menu
+ *
+ * Generates a drop-down menu of timezones.
+ *
+ * @access public
+ * @param string timezone
+ * @param string classname
+ * @param string menu name
+ * @return string
+ */
+if ( ! function_exists('timezone_menu'))
+{
+ function timezone_menu($default = 'UTC', $class = "", $name = 'timezones')
+ {
+ $CI =& get_instance();
+ $CI->lang->load('date');
+
+ if ($default == 'GMT')
+ $default = 'UTC';
+
+ $menu = '<select name="'.$name.'"';
+
+ if ($class != '')
+ {
+ $menu .= ' class="'.$class.'"';
+ }
+
+ $menu .= ">\n";
+
+ foreach (timezones() as $key => $val)
+ {
+ $selected = ($default == $key) ? " selected='selected'" : '';
+ $menu .= "<option value='{$key}'{$selected}>".$CI->lang->line($key)."</option>\n";
+ }
+
+ $menu .= "</select>";
+
+ return $menu;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Timezones
+ *
+ * Returns an array of timezones. This is a helper function
+ * for various other ones in this library
+ *
+ * @access public
+ * @param string timezone
+ * @return string
+ */
+if ( ! function_exists('timezones'))
+{
+ function timezones($tz = '')
+ {
+ // Note: Don't change the order of these even though
+ // some items appear to be in the wrong order
+
+ $zones = array(
+ 'UM12' => -12,
+ 'UM11' => -11,
+ 'UM10' => -10,
+ 'UM95' => -9.5,
+ 'UM9' => -9,
+ 'UM8' => -8,
+ 'UM7' => -7,
+ 'UM6' => -6,
+ 'UM5' => -5,
+ 'UM45' => -4.5,
+ 'UM4' => -4,
+ 'UM35' => -3.5,
+ 'UM3' => -3,
+ 'UM2' => -2,
+ 'UM1' => -1,
+ 'UTC' => 0,
+ 'UP1' => +1,
+ 'UP2' => +2,
+ 'UP3' => +3,
+ 'UP35' => +3.5,
+ 'UP4' => +4,
+ 'UP45' => +4.5,
+ 'UP5' => +5,
+ 'UP55' => +5.5,
+ 'UP575' => +5.75,
+ 'UP6' => +6,
+ 'UP65' => +6.5,
+ 'UP7' => +7,
+ 'UP8' => +8,
+ 'UP875' => +8.75,
+ 'UP9' => +9,
+ 'UP95' => +9.5,
+ 'UP10' => +10,
+ 'UP105' => +10.5,
+ 'UP11' => +11,
+ 'UP115' => +11.5,
+ 'UP12' => +12,
+ 'UP1275' => +12.75,
+ 'UP13' => +13,
+ 'UP14' => +14
+ );
+
+ if ($tz == '')
+ {
+ return $zones;
+ }
+
+ if ($tz == 'GMT')
+ $tz = 'UTC';
+
+ return ( ! isset($zones[$tz])) ? 0 : $zones[$tz];
+ }
+}
+
+
+/* End of file date_helper.php */
+/* Location: ./system/helpers/date_helper.php */ \ No newline at end of file
diff --git a/system/helpers/directory_helper.php b/system/helpers/directory_helper.php
new file mode 100644
index 000000000..a6fb7841e
--- /dev/null
+++ b/system/helpers/directory_helper.php
@@ -0,0 +1,84 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Directory Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/directory_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Create a Directory Map
+ *
+ * Reads the specified directory and builds an array
+ * representation of it. Sub-folders contained with the
+ * directory will be mapped as well.
+ *
+ * @access public
+ * @param string path to source
+ * @param bool whether to limit the result to the top level only
+ * @return array
+ */
+if ( ! function_exists('directory_map'))
+{
+ function directory_map($source_dir, $top_level_only = FALSE, $hidden = FALSE)
+ {
+ if ($fp = @opendir($source_dir))
+ {
+ $source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+ $filedata = array();
+
+ while (FALSE !== ($file = readdir($fp)))
+ {
+ if (($hidden == FALSE && strncmp($file, '.', 1) == 0) OR ($file == '.' OR $file == '..'))
+ {
+ continue;
+ }
+
+ if ($top_level_only == FALSE && @is_dir($source_dir.$file))
+ {
+ $temp_array = array();
+
+ $temp_array = directory_map($source_dir.$file.DIRECTORY_SEPARATOR, $top_level_only, $hidden);
+
+ $filedata[$file] = $temp_array;
+ }
+ else
+ {
+ $filedata[] = $file;
+ }
+ }
+
+ closedir($fp);
+ return $filedata;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+
+/* End of file directory_helper.php */
+/* Location: ./system/helpers/directory_helper.php */ \ No newline at end of file
diff --git a/system/helpers/download_helper.php b/system/helpers/download_helper.php
new file mode 100644
index 000000000..a8f7b1a7f
--- /dev/null
+++ b/system/helpers/download_helper.php
@@ -0,0 +1,100 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Download Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/download_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Force Download
+ *
+ * Generates headers that force a download to happen
+ *
+ * @access public
+ * @param string filename
+ * @param mixed the data to be downloaded
+ * @return void
+ */
+if ( ! function_exists('force_download'))
+{
+ function force_download($filename = '', $data = '')
+ {
+ if ($filename == '' OR $data == '')
+ {
+ return FALSE;
+ }
+
+ // Try to determine if the filename includes a file extension.
+ // We need it in order to set the MIME type
+ if (FALSE === strpos($filename, '.'))
+ {
+ return FALSE;
+ }
+
+ // Grab the file extension
+ $x = explode('.', $filename);
+ $extension = end($x);
+
+ // Load the mime types
+ @include(APPPATH.'config/mimes'.EXT);
+
+ // Set a default mime if we can't find it
+ if ( ! isset($mimes[$extension]))
+ {
+ $mime = 'application/octet-stream';
+ }
+ else
+ {
+ $mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
+ }
+
+ // Generate the server headers
+ if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
+ {
+ header('Content-Type: "'.$mime.'"');
+ header('Content-Disposition: attachment; filename="'.$filename.'"');
+ header('Expires: 0');
+ header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
+ header("Content-Transfer-Encoding: binary");
+ header('Pragma: public');
+ header("Content-Length: ".strlen($data));
+ }
+ else
+ {
+ header('Content-Type: "'.$mime.'"');
+ header('Content-Disposition: attachment; filename="'.$filename.'"');
+ header("Content-Transfer-Encoding: binary");
+ header('Expires: 0');
+ header('Pragma: no-cache');
+ header("Content-Length: ".strlen($data));
+ }
+
+ exit($data);
+ }
+}
+
+
+/* End of file download_helper.php */
+/* Location: ./system/helpers/download_helper.php */ \ No newline at end of file
diff --git a/system/helpers/email_helper.php b/system/helpers/email_helper.php
new file mode 100644
index 000000000..df602b115
--- /dev/null
+++ b/system/helpers/email_helper.php
@@ -0,0 +1,62 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Email Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/email_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Validate email address
+ *
+ * @access public
+ * @return bool
+ */
+if ( ! function_exists('valid_email'))
+{
+ function valid_email($address)
+ {
+ return ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $address)) ? FALSE : TRUE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Send an email
+ *
+ * @access public
+ * @return bool
+ */
+if ( ! function_exists('send_email'))
+{
+ function send_email($recipient, $subject = 'Test email', $message = 'Hello World')
+ {
+ return mail($recipient, $subject, $message);
+ }
+}
+
+
+/* End of file email_helper.php */
+/* Location: ./system/helpers/email_helper.php */ \ No newline at end of file
diff --git a/system/helpers/file_helper.php b/system/helpers/file_helper.php
new file mode 100644
index 000000000..0d7b5d5aa
--- /dev/null
+++ b/system/helpers/file_helper.php
@@ -0,0 +1,464 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter File Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/file_helpers.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Read File
+ *
+ * Opens the file specfied in the path and returns it as a string.
+ *
+ * @access public
+ * @param string path to file
+ * @return string
+ */
+if ( ! function_exists('read_file'))
+{
+ function read_file($file)
+ {
+ if ( ! file_exists($file))
+ {
+ return FALSE;
+ }
+
+ if (function_exists('file_get_contents'))
+ {
+ return file_get_contents($file);
+ }
+
+ if ( ! $fp = @fopen($file, FOPEN_READ))
+ {
+ return FALSE;
+ }
+
+ flock($fp, LOCK_SH);
+
+ $data = '';
+ if (filesize($file) > 0)
+ {
+ $data =& fread($fp, filesize($file));
+ }
+
+ flock($fp, LOCK_UN);
+ fclose($fp);
+
+ return $data;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Write File
+ *
+ * Writes data to the file specified in the path.
+ * Creates a new file if non-existent.
+ *
+ * @access public
+ * @param string path to file
+ * @param string file data
+ * @return bool
+ */
+if ( ! function_exists('write_file'))
+{
+ function write_file($path, $data, $mode = FOPEN_WRITE_CREATE_DESTRUCTIVE)
+ {
+ if ( ! $fp = @fopen($path, $mode))
+ {
+ return FALSE;
+ }
+
+ flock($fp, LOCK_EX);
+ fwrite($fp, $data);
+ flock($fp, LOCK_UN);
+ fclose($fp);
+
+ return TRUE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Delete Files
+ *
+ * Deletes all files contained in the supplied directory path.
+ * Files must be writable or owned by the system in order to be deleted.
+ * If the second parameter is set to TRUE, any directories contained
+ * within the supplied base directory will be nuked as well.
+ *
+ * @access public
+ * @param string path to file
+ * @param bool whether to delete any directories found in the path
+ * @return bool
+ */
+if ( ! function_exists('delete_files'))
+{
+ function delete_files($path, $del_dir = FALSE, $level = 0)
+ {
+ // Trim the trailing slash
+ $path = rtrim($path, DIRECTORY_SEPARATOR);
+
+ if ( ! $current_dir = @opendir($path))
+ return;
+
+ while(FALSE !== ($filename = @readdir($current_dir)))
+ {
+ if ($filename != "." and $filename != "..")
+ {
+ if (is_dir($path.DIRECTORY_SEPARATOR.$filename))
+ {
+ // Ignore empty folders
+ if (substr($filename, 0, 1) != '.')
+ {
+ delete_files($path.DIRECTORY_SEPARATOR.$filename, $del_dir, $level + 1);
+ }
+ }
+ else
+ {
+ unlink($path.DIRECTORY_SEPARATOR.$filename);
+ }
+ }
+ }
+ @closedir($current_dir);
+
+ if ($del_dir == TRUE AND $level > 0)
+ {
+ @rmdir($path);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get Filenames
+ *
+ * Reads the specified directory and builds an array containing the filenames.
+ * Any sub-folders contained within the specified path are read as well.
+ *
+ * @access public
+ * @param string path to source
+ * @param bool whether to include the path as part of the filename
+ * @param bool internal variable to determine recursion status - do not use in calls
+ * @return array
+ */
+if ( ! function_exists('get_filenames'))
+{
+ function get_filenames($source_dir, $include_path = FALSE, $_recursion = FALSE)
+ {
+ static $_filedata = array();
+
+ if ($fp = @opendir($source_dir))
+ {
+ // reset the array and make sure $source_dir has a trailing slash on the initial call
+ if ($_recursion === FALSE)
+ {
+ $_filedata = array();
+ $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+ }
+
+ while (FALSE !== ($file = readdir($fp)))
+ {
+ if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)
+ {
+ get_filenames($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
+ }
+ elseif (strncmp($file, '.', 1) !== 0)
+ {
+ $_filedata[] = ($include_path == TRUE) ? $source_dir.$file : $file;
+ }
+ }
+ return $_filedata;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Get Directory File Information
+ *
+ * Reads the specified directory and builds an array containing the filenames,
+ * filesize, dates, and permissions
+ *
+ * Any sub-folders contained within the specified path are read as well.
+ *
+ * @access public
+ * @param string path to source
+ * @param bool whether to include the path as part of the filename
+ * @param bool internal variable to determine recursion status - do not use in calls
+ * @return array
+ */
+if ( ! function_exists('get_dir_file_info'))
+{
+ function get_dir_file_info($source_dir, $include_path = FALSE, $_recursion = FALSE)
+ {
+ static $_filedata = array();
+ $relative_path = $source_dir;
+
+ if ($fp = @opendir($source_dir))
+ {
+ // reset the array and make sure $source_dir has a trailing slash on the initial call
+ if ($_recursion === FALSE)
+ {
+ $_filedata = array();
+ $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+ }
+
+ while (FALSE !== ($file = readdir($fp)))
+ {
+ if (@is_dir($source_dir.$file) && strncmp($file, '.', 1) !== 0)
+ {
+ get_dir_file_info($source_dir.$file.DIRECTORY_SEPARATOR, $include_path, TRUE);
+ }
+ elseif (strncmp($file, '.', 1) !== 0)
+ {
+ $_filedata[$file] = get_file_info($source_dir.$file);
+ $_filedata[$file]['relative_path'] = $relative_path;
+ }
+ }
+ return $_filedata;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+* Get File Info
+*
+* Given a file and path, returns the name, path, size, date modified
+* Second parameter allows you to explicitly declare what information you want returned
+* Options are: name, server_path, size, date, readable, writable, executable, fileperms
+* Returns FALSE if the file cannot be found.
+*
+* @access public
+* @param string path to file
+* @param mixed array or comma separated string of information returned
+* @return array
+*/
+if ( ! function_exists('get_file_info'))
+{
+ function get_file_info($file, $returned_values = array('name', 'server_path', 'size', 'date'))
+ {
+
+ if ( ! file_exists($file))
+ {
+ return FALSE;
+ }
+
+ if (is_string($returned_values))
+ {
+ $returned_values = explode(',', $returned_values);
+ }
+
+ foreach ($returned_values as $key)
+ {
+ switch ($key)
+ {
+ case 'name':
+ $fileinfo['name'] = substr(strrchr($file, DIRECTORY_SEPARATOR), 1);
+ break;
+ case 'server_path':
+ $fileinfo['server_path'] = $file;
+ break;
+ case 'size':
+ $fileinfo['size'] = filesize($file);
+ break;
+ case 'date':
+ $fileinfo['date'] = filectime($file);
+ break;
+ case 'readable':
+ $fileinfo['readable'] = is_readable($file);
+ break;
+ case 'writable':
+ // There are known problems using is_weritable on IIS. It may not be reliable - consider fileperms()
+ $fileinfo['writable'] = is_writable($file);
+ break;
+ case 'executable':
+ $fileinfo['executable'] = is_executable($file);
+ break;
+ case 'fileperms':
+ $fileinfo['fileperms'] = fileperms($file);
+ break;
+ }
+ }
+
+ return $fileinfo;
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Get Mime by Extension
+ *
+ * Translates a file extension into a mime type based on config/mimes.php.
+ * Returns FALSE if it can't determine the type, or open the mime config file
+ *
+ * Note: this is NOT an accurate way of determining file mime types, and is here strictly as a convenience
+ * It should NOT be trusted, and should certainly NOT be used for security
+ *
+ * @access public
+ * @param string path to file
+ * @return mixed
+ */
+if ( ! function_exists('get_mime_by_extension'))
+{
+ function get_mime_by_extension($file)
+ {
+ $extension = substr(strrchr($file, '.'), 1);
+
+ global $mimes;
+
+ if ( ! is_array($mimes))
+ {
+ if ( ! require_once(APPPATH.'config/mimes.php'))
+ {
+ return FALSE;
+ }
+ }
+
+ if (array_key_exists($extension, $mimes))
+ {
+ if (is_array($mimes[$extension]))
+ {
+ // Multiple mime types, just give the first one
+ return current($mimes[$extension]);
+ }
+ else
+ {
+ return $mimes[$extension];
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Symbolic Permissions
+ *
+ * Takes a numeric value representing a file's permissions and returns
+ * standard symbolic notation representing that value
+ *
+ * @access public
+ * @param int
+ * @return string
+ */
+if ( ! function_exists('symbolic_permissions'))
+{
+ function symbolic_permissions($perms)
+ {
+ if (($perms & 0xC000) == 0xC000)
+ {
+ $symbolic = 's'; // Socket
+ }
+ elseif (($perms & 0xA000) == 0xA000)
+ {
+ $symbolic = 'l'; // Symbolic Link
+ }
+ elseif (($perms & 0x8000) == 0x8000)
+ {
+ $symbolic = '-'; // Regular
+ }
+ elseif (($perms & 0x6000) == 0x6000)
+ {
+ $symbolic = 'b'; // Block special
+ }
+ elseif (($perms & 0x4000) == 0x4000)
+ {
+ $symbolic = 'd'; // Directory
+ }
+ elseif (($perms & 0x2000) == 0x2000)
+ {
+ $symbolic = 'c'; // Character special
+ }
+ elseif (($perms & 0x1000) == 0x1000)
+ {
+ $symbolic = 'p'; // FIFO pipe
+ }
+ else
+ {
+ $symbolic = 'u'; // Unknown
+ }
+
+ // Owner
+ $symbolic .= (($perms & 0x0100) ? 'r' : '-');
+ $symbolic .= (($perms & 0x0080) ? 'w' : '-');
+ $symbolic .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x' ) : (($perms & 0x0800) ? 'S' : '-'));
+
+ // Group
+ $symbolic .= (($perms & 0x0020) ? 'r' : '-');
+ $symbolic .= (($perms & 0x0010) ? 'w' : '-');
+ $symbolic .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x' ) : (($perms & 0x0400) ? 'S' : '-'));
+
+ // World
+ $symbolic .= (($perms & 0x0004) ? 'r' : '-');
+ $symbolic .= (($perms & 0x0002) ? 'w' : '-');
+ $symbolic .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x' ) : (($perms & 0x0200) ? 'T' : '-'));
+
+ return $symbolic;
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Octal Permissions
+ *
+ * Takes a numeric value representing a file's permissions and returns
+ * a three character string representing the file's octal permissions
+ *
+ * @access public
+ * @param int
+ * @return string
+ */
+if ( ! function_exists('octal_permissions'))
+{
+ function octal_permissions($perms)
+ {
+ return substr(sprintf('%o', $perms), -3);
+ }
+}
+
+
+/* End of file file_helper.php */
+/* Location: ./system/helpers/file_helper.php */ \ No newline at end of file
diff --git a/system/helpers/form_helper.php b/system/helpers/form_helper.php
new file mode 100644
index 000000000..c5e977a40
--- /dev/null
+++ b/system/helpers/form_helper.php
@@ -0,0 +1,1025 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Form Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/form_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Declaration
+ *
+ * Creates the opening portion of the form.
+ *
+ * @access public
+ * @param string the URI segments of the form destination
+ * @param array a key/value pair of attributes
+ * @param array a key/value pair hidden data
+ * @return string
+ */
+if ( ! function_exists('form_open'))
+{
+ function form_open($action = '', $attributes = '', $hidden = array())
+ {
+ $CI =& get_instance();
+
+ if ($attributes == '')
+ {
+ $attributes = 'method="post"';
+ }
+
+ $action = ( strpos($action, '://') === FALSE) ? $CI->config->site_url($action) : $action;
+
+ $form = '<form action="'.$action.'"';
+
+ $form .= _attributes_to_string($attributes, TRUE);
+
+ $form .= '>';
+
+ if (is_array($hidden) AND count($hidden) > 0)
+ {
+ $form .= form_hidden($hidden);
+ }
+
+ return $form;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Declaration - Multipart type
+ *
+ * Creates the opening portion of the form, but with "multipart/form-data".
+ *
+ * @access public
+ * @param string the URI segments of the form destination
+ * @param array a key/value pair of attributes
+ * @param array a key/value pair hidden data
+ * @return string
+ */
+if ( ! function_exists('form_open_multipart'))
+{
+ function form_open_multipart($action, $attributes = array(), $hidden = array())
+ {
+ $attributes['enctype'] = 'multipart/form-data';
+ return form_open($action, $attributes, $hidden);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Hidden Input Field
+ *
+ * Generates hidden fields. You can pass a simple key/value string or an associative
+ * array with multiple values.
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_hidden'))
+{
+ function form_hidden($name, $value = '', $recursing = FALSE)
+ {
+ static $form;
+
+ if ($recursing === FALSE)
+ {
+ $form = "\n";
+ }
+
+ if (is_array($name))
+ {
+ foreach ($name as $key => $val)
+ {
+ form_hidden($key, $val, TRUE);
+ }
+ return $form;
+ }
+
+ if ( ! is_array($value))
+ {
+ $form .= '<input type="hidden" name="'.$name.'" value="'.form_prep($value, $name).'" />'."\n";
+ }
+ else
+ {
+ foreach ($value as $k => $v)
+ {
+ $k = (is_int($k)) ? '' : $k;
+ form_hidden($name.'['.$k.']', $v, TRUE);
+ }
+ }
+
+ return $form;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Text Input Field
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_input'))
+{
+ function form_input($data = '', $value = '', $extra = '')
+ {
+ $defaults = array('type' => 'text', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+ return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Password Field
+ *
+ * Identical to the input function but adds the "password" type
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_password'))
+{
+ function form_password($data = '', $value = '', $extra = '')
+ {
+ if ( ! is_array($data))
+ {
+ $data = array('name' => $data);
+ }
+
+ $data['type'] = 'password';
+ return form_input($data, $value, $extra);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Upload Field
+ *
+ * Identical to the input function but adds the "file" type
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_upload'))
+{
+ function form_upload($data = '', $value = '', $extra = '')
+ {
+ if ( ! is_array($data))
+ {
+ $data = array('name' => $data);
+ }
+
+ $data['type'] = 'file';
+ return form_input($data, $value, $extra);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Textarea field
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_textarea'))
+{
+ function form_textarea($data = '', $value = '', $extra = '')
+ {
+ $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'cols' => '90', 'rows' => '12');
+
+ if ( ! is_array($data) OR ! isset($data['value']))
+ {
+ $val = $value;
+ }
+ else
+ {
+ $val = $data['value'];
+ unset($data['value']); // textareas don't use the value attribute
+ }
+
+ $name = (is_array($data)) ? $data['name'] : $data;
+ return "<textarea "._parse_form_attributes($data, $defaults).$extra.">".form_prep($val, $name)."</textarea>";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Multi-select menu
+ *
+ * @access public
+ * @param string
+ * @param array
+ * @param mixed
+ * @param string
+ * @return type
+ */
+if (! function_exists('form_multiselect'))
+{
+ function form_multiselect($name = '', $options = array(), $selected = array(), $extra = '')
+ {
+ if ( ! strpos($extra, 'multiple'))
+ {
+ $extra .= ' multiple="multiple"';
+ }
+
+ return form_dropdown($name, $options, $selected, $extra);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Drop-down Menu
+ *
+ * @access public
+ * @param string
+ * @param array
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_dropdown'))
+{
+ function form_dropdown($name = '', $options = array(), $selected = array(), $extra = '')
+ {
+ if ( ! is_array($selected))
+ {
+ $selected = array($selected);
+ }
+
+ // If no selected state was submitted we will attempt to set it automatically
+ if (count($selected) === 0)
+ {
+ // If the form name appears in the $_POST array we have a winner!
+ if (isset($_POST[$name]))
+ {
+ $selected = array($_POST[$name]);
+ }
+ }
+
+ if ($extra != '') $extra = ' '.$extra;
+
+ $multiple = (count($selected) > 1 && strpos($extra, 'multiple') === FALSE) ? ' multiple="multiple"' : '';
+
+ $form = '<select name="'.$name.'"'.$extra.$multiple.">\n";
+
+ foreach ($options as $key => $val)
+ {
+ $key = (string) $key;
+
+ if (is_array($val))
+ {
+ $form .= '<optgroup label="'.$key.'">'."\n";
+
+ foreach ($val as $optgroup_key => $optgroup_val)
+ {
+ $sel = (in_array($optgroup_key, $selected)) ? ' selected="selected"' : '';
+
+ $form .= '<option value="'.$optgroup_key.'"'.$sel.'>'.(string) $optgroup_val."</option>\n";
+ }
+
+ $form .= '</optgroup>'."\n";
+ }
+ else
+ {
+ $sel = (in_array($key, $selected)) ? ' selected="selected"' : '';
+
+ $form .= '<option value="'.$key.'"'.$sel.'>'.(string) $val."</option>\n";
+ }
+ }
+
+ $form .= '</select>';
+
+ return $form;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Checkbox Field
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param bool
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_checkbox'))
+{
+ function form_checkbox($data = '', $value = '', $checked = FALSE, $extra = '')
+ {
+ $defaults = array('type' => 'checkbox', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+ if (is_array($data) AND array_key_exists('checked', $data))
+ {
+ $checked = $data['checked'];
+
+ if ($checked == FALSE)
+ {
+ unset($data['checked']);
+ }
+ else
+ {
+ $data['checked'] = 'checked';
+ }
+ }
+
+ if ($checked == TRUE)
+ {
+ $defaults['checked'] = 'checked';
+ }
+ else
+ {
+ unset($defaults['checked']);
+ }
+
+ return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Radio Button
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param bool
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_radio'))
+{
+ function form_radio($data = '', $value = '', $checked = FALSE, $extra = '')
+ {
+ if ( ! is_array($data))
+ {
+ $data = array('name' => $data);
+ }
+
+ $data['type'] = 'radio';
+ return form_checkbox($data, $value, $checked, $extra);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Submit Button
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_submit'))
+{
+ function form_submit($data = '', $value = '', $extra = '')
+ {
+ $defaults = array('type' => 'submit', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+ return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Reset Button
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_reset'))
+{
+ function form_reset($data = '', $value = '', $extra = '')
+ {
+ $defaults = array('type' => 'reset', 'name' => (( ! is_array($data)) ? $data : ''), 'value' => $value);
+
+ return "<input "._parse_form_attributes($data, $defaults).$extra." />";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Button
+ *
+ * @access public
+ * @param mixed
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_button'))
+{
+ function form_button($data = '', $content = '', $extra = '')
+ {
+ $defaults = array('name' => (( ! is_array($data)) ? $data : ''), 'type' => 'button');
+
+ if ( is_array($data) AND isset($data['content']))
+ {
+ $content = $data['content'];
+ unset($data['content']); // content is not an attribute
+ }
+
+ return "<button "._parse_form_attributes($data, $defaults).$extra.">".$content."</button>";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Label Tag
+ *
+ * @access public
+ * @param string The text to appear onscreen
+ * @param string The id the label applies to
+ * @param string Additional attributes
+ * @return string
+ */
+if ( ! function_exists('form_label'))
+{
+ function form_label($label_text = '', $id = '', $attributes = array())
+ {
+
+ $label = '<label';
+
+ if ($id != '')
+ {
+ $label .= " for=\"$id\"";
+ }
+
+ if (is_array($attributes) AND count($attributes) > 0)
+ {
+ foreach ($attributes as $key => $val)
+ {
+ $label .= ' '.$key.'="'.$val.'"';
+ }
+ }
+
+ $label .= ">$label_text</label>";
+
+ return $label;
+ }
+}
+
+// ------------------------------------------------------------------------
+/**
+ * Fieldset Tag
+ *
+ * Used to produce <fieldset><legend>text</legend>. To close fieldset
+ * use form_fieldset_close()
+ *
+ * @access public
+ * @param string The legend text
+ * @param string Additional attributes
+ * @return string
+ */
+if ( ! function_exists('form_fieldset'))
+{
+ function form_fieldset($legend_text = '', $attributes = array())
+ {
+ $fieldset = "<fieldset";
+
+ $fieldset .= _attributes_to_string($attributes, FALSE);
+
+ $fieldset .= ">\n";
+
+ if ($legend_text != '')
+ {
+ $fieldset .= "<legend>$legend_text</legend>\n";
+ }
+
+ return $fieldset;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Fieldset Close Tag
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_fieldset_close'))
+{
+ function form_fieldset_close($extra = '')
+ {
+ return "</fieldset>".$extra;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Close Tag
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_close'))
+{
+ function form_close($extra = '')
+ {
+ return "</form>".$extra;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Prep
+ *
+ * Formats text so that it can be safely placed in a form field in the event it has HTML tags.
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_prep'))
+{
+ function form_prep($str = '', $field_name = '')
+ {
+ static $prepped_fields = array();
+
+ // if the field name is an array we do this recursively
+ if (is_array($str))
+ {
+ foreach ($str as $key => $val)
+ {
+ $str[$key] = form_prep($val);
+ }
+
+ return $str;
+ }
+
+ if ($str === '')
+ {
+ return '';
+ }
+
+ // we've already prepped a field with this name
+ // @todo need to figure out a way to namespace this so
+ // that we know the *exact* field and not just one with
+ // the same name
+ if (isset($prepped_fields[$field_name]))
+ {
+ return $str;
+ }
+
+ $str = htmlspecialchars($str);
+
+ // In case htmlspecialchars misses these.
+ $str = str_replace(array("'", '"'), array("&#39;", "&quot;"), $str);
+
+ if ($field_name != '')
+ {
+ $prepped_fields[$field_name] = $str;
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Value
+ *
+ * Grabs a value from the POST array for the specified field so you can
+ * re-populate an input field or textarea. If Form Validation
+ * is active it retrieves the info from the validation class
+ *
+ * @access public
+ * @param string
+ * @return mixed
+ */
+if ( ! function_exists('set_value'))
+{
+ function set_value($field = '', $default = '')
+ {
+ if (FALSE === ($OBJ =& _get_validation_object()))
+ {
+ if ( ! isset($_POST[$field]))
+ {
+ return $default;
+ }
+
+ return form_prep($_POST[$field], $field);
+ }
+
+ return form_prep($OBJ->set_value($field, $default), $field);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Select
+ *
+ * Let's you set the selected value of a <select> menu via data in the POST array.
+ * If Form Validation is active it retrieves the info from the validation class
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @param bool
+ * @return string
+ */
+if ( ! function_exists('set_select'))
+{
+ function set_select($field = '', $value = '', $default = FALSE)
+ {
+ $OBJ =& _get_validation_object();
+
+ if ($OBJ === FALSE)
+ {
+ if ( ! isset($_POST[$field]))
+ {
+ if (count($_POST) === 0 AND $default == TRUE)
+ {
+ return ' selected="selected"';
+ }
+ return '';
+ }
+
+ $field = $_POST[$field];
+
+ if (is_array($field))
+ {
+ if ( ! in_array($value, $field))
+ {
+ return '';
+ }
+ }
+ else
+ {
+ if (($field == '' OR $value == '') OR ($field != $value))
+ {
+ return '';
+ }
+ }
+
+ return ' selected="selected"';
+ }
+
+ return $OBJ->set_select($field, $value, $default);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Checkbox
+ *
+ * Let's you set the selected value of a checkbox via the value in the POST array.
+ * If Form Validation is active it retrieves the info from the validation class
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @param bool
+ * @return string
+ */
+if ( ! function_exists('set_checkbox'))
+{
+ function set_checkbox($field = '', $value = '', $default = FALSE)
+ {
+ $OBJ =& _get_validation_object();
+
+ if ($OBJ === FALSE)
+ {
+ if ( ! isset($_POST[$field]))
+ {
+ if (count($_POST) === 0 AND $default == TRUE)
+ {
+ return ' checked="checked"';
+ }
+ return '';
+ }
+
+ $field = $_POST[$field];
+
+ if (is_array($field))
+ {
+ if ( ! in_array($value, $field))
+ {
+ return '';
+ }
+ }
+ else
+ {
+ if (($field == '' OR $value == '') OR ($field != $value))
+ {
+ return '';
+ }
+ }
+
+ return ' checked="checked"';
+ }
+
+ return $OBJ->set_checkbox($field, $value, $default);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Radio
+ *
+ * Let's you set the selected value of a radio field via info in the POST array.
+ * If Form Validation is active it retrieves the info from the validation class
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @param bool
+ * @return string
+ */
+if ( ! function_exists('set_radio'))
+{
+ function set_radio($field = '', $value = '', $default = FALSE)
+ {
+ $OBJ =& _get_validation_object();
+
+ if ($OBJ === FALSE)
+ {
+ if ( ! isset($_POST[$field]))
+ {
+ if (count($_POST) === 0 AND $default == TRUE)
+ {
+ return ' checked="checked"';
+ }
+ return '';
+ }
+
+ $field = $_POST[$field];
+
+ if (is_array($field))
+ {
+ if ( ! in_array($value, $field))
+ {
+ return '';
+ }
+ }
+ else
+ {
+ if (($field == '' OR $value == '') OR ($field != $value))
+ {
+ return '';
+ }
+ }
+
+ return ' checked="checked"';
+ }
+
+ return $OBJ->set_radio($field, $value, $default);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Form Error
+ *
+ * Returns the error for a specific form field. This is a helper for the
+ * form validation class.
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('form_error'))
+{
+ function form_error($field = '', $prefix = '', $suffix = '')
+ {
+ if (FALSE === ($OBJ =& _get_validation_object()))
+ {
+ return '';
+ }
+
+ return $OBJ->error($field, $prefix, $suffix);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Validation Error String
+ *
+ * Returns all the errors associated with a form submission. This is a helper
+ * function for the form validation class.
+ *
+ * @access public
+ * @param string
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('validation_errors'))
+{
+ function validation_errors($prefix = '', $suffix = '')
+ {
+ if (FALSE === ($OBJ =& _get_validation_object()))
+ {
+ return '';
+ }
+
+ return $OBJ->error_string($prefix, $suffix);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse the form attributes
+ *
+ * Helper function used by some of the form helpers
+ *
+ * @access private
+ * @param array
+ * @param array
+ * @return string
+ */
+if ( ! function_exists('_parse_form_attributes'))
+{
+ function _parse_form_attributes($attributes, $default)
+ {
+ if (is_array($attributes))
+ {
+ foreach ($default as $key => $val)
+ {
+ if (isset($attributes[$key]))
+ {
+ $default[$key] = $attributes[$key];
+ unset($attributes[$key]);
+ }
+ }
+
+ if (count($attributes) > 0)
+ {
+ $default = array_merge($default, $attributes);
+ }
+ }
+
+ $att = '';
+
+ foreach ($default as $key => $val)
+ {
+ if ($key == 'value')
+ {
+ $val = form_prep($val, $default['name']);
+ }
+
+ $att .= $key . '="' . $val . '" ';
+ }
+
+ return $att;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Attributes To String
+ *
+ * Helper function used by some of the form helpers
+ *
+ * @access private
+ * @param mixed
+ * @param bool
+ * @return string
+ */
+if ( ! function_exists('_attributes_to_string'))
+{
+ function _attributes_to_string($attributes, $formtag = FALSE)
+ {
+ if (is_string($attributes) AND strlen($attributes) > 0)
+ {
+ if ($formtag == TRUE AND strpos($attributes, 'method=') === FALSE)
+ {
+ $attributes .= ' method="post"';
+ }
+
+ return ' '.$attributes;
+ }
+
+ if (is_object($attributes) AND count($attributes) > 0)
+ {
+ $attributes = (array)$attributes;
+ }
+
+ if (is_array($attributes) AND count($attributes) > 0)
+ {
+ $atts = '';
+
+ if ( ! isset($attributes['method']) AND $formtag === TRUE)
+ {
+ $atts .= ' method="post"';
+ }
+
+ foreach ($attributes as $key => $val)
+ {
+ $atts .= ' '.$key.'="'.$val.'"';
+ }
+
+ return $atts;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Validation Object
+ *
+ * Determines what the form validation class was instantiated as, fetches
+ * the object and returns it.
+ *
+ * @access private
+ * @return mixed
+ */
+if ( ! function_exists('_get_validation_object'))
+{
+ function &_get_validation_object()
+ {
+ $CI =& get_instance();
+
+ // We set this as a variable since we're returning by reference
+ $return = FALSE;
+
+ if ( ! isset($CI->load->_ci_classes) OR ! isset($CI->load->_ci_classes['form_validation']))
+ {
+ return $return;
+ }
+
+ $object = $CI->load->_ci_classes['form_validation'];
+
+ if ( ! isset($CI->$object) OR ! is_object($CI->$object))
+ {
+ return $return;
+ }
+
+ return $CI->$object;
+ }
+}
+
+
+/* End of file form_helper.php */
+/* Location: ./system/helpers/form_helper.php */ \ No newline at end of file
diff --git a/system/helpers/html_helper.php b/system/helpers/html_helper.php
new file mode 100644
index 000000000..427d1ce3f
--- /dev/null
+++ b/system/helpers/html_helper.php
@@ -0,0 +1,416 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter HTML Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/html_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Heading
+ *
+ * Generates an HTML heading tag. First param is the data.
+ * Second param is the size of the heading tag.
+ *
+ * @access public
+ * @param string
+ * @param integer
+ * @return string
+ */
+if ( ! function_exists('heading'))
+{
+ function heading($data = '', $h = '1')
+ {
+ return "<h".$h.">".$data."</h".$h.">";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Unordered List
+ *
+ * Generates an HTML unordered list from an single or multi-dimensional array.
+ *
+ * @access public
+ * @param array
+ * @param mixed
+ * @return string
+ */
+if ( ! function_exists('ul'))
+{
+ function ul($list, $attributes = '')
+ {
+ return _list('ul', $list, $attributes);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Ordered List
+ *
+ * Generates an HTML ordered list from an single or multi-dimensional array.
+ *
+ * @access public
+ * @param array
+ * @param mixed
+ * @return string
+ */
+if ( ! function_exists('ol'))
+{
+ function ol($list, $attributes = '')
+ {
+ return _list('ol', $list, $attributes);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates the list
+ *
+ * Generates an HTML ordered list from an single or multi-dimensional array.
+ *
+ * @access private
+ * @param string
+ * @param mixed
+ * @param mixed
+ * @param intiger
+ * @return string
+ */
+if ( ! function_exists('_list'))
+{
+ function _list($type = 'ul', $list, $attributes = '', $depth = 0)
+ {
+ // If an array wasn't submitted there's nothing to do...
+ if ( ! is_array($list))
+ {
+ return $list;
+ }
+
+ // Set the indentation based on the depth
+ $out = str_repeat(" ", $depth);
+
+ // Were any attributes submitted? If so generate a string
+ if (is_array($attributes))
+ {
+ $atts = '';
+ foreach ($attributes as $key => $val)
+ {
+ $atts .= ' ' . $key . '="' . $val . '"';
+ }
+ $attributes = $atts;
+ }
+
+ // Write the opening list tag
+ $out .= "<".$type.$attributes.">\n";
+
+ // Cycle through the list elements. If an array is
+ // encountered we will recursively call _list()
+
+ static $_last_list_item = '';
+ foreach ($list as $key => $val)
+ {
+ $_last_list_item = $key;
+
+ $out .= str_repeat(" ", $depth + 2);
+ $out .= "<li>";
+
+ if ( ! is_array($val))
+ {
+ $out .= $val;
+ }
+ else
+ {
+ $out .= $_last_list_item."\n";
+ $out .= _list($type, $val, '', $depth + 4);
+ $out .= str_repeat(" ", $depth + 2);
+ }
+
+ $out .= "</li>\n";
+ }
+
+ // Set the indentation for the closing tag
+ $out .= str_repeat(" ", $depth);
+
+ // Write the closing list tag
+ $out .= "</".$type.">\n";
+
+ return $out;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates HTML BR tags based on number supplied
+ *
+ * @access public
+ * @param integer
+ * @return string
+ */
+if ( ! function_exists('br'))
+{
+ function br($num = 1)
+ {
+ return str_repeat("<br />", $num);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Image
+ *
+ * Generates an <img /> element
+ *
+ * @access public
+ * @param mixed
+ * @return string
+ */
+if ( ! function_exists('img'))
+{
+ function img($src = '', $index_page = FALSE)
+ {
+ if ( ! is_array($src) )
+ {
+ $src = array('src' => $src);
+ }
+
+ $img = '<img';
+
+ foreach ($src as $k=>$v)
+ {
+
+ if ($k == 'src' AND strpos($v, '://') === FALSE)
+ {
+ $CI =& get_instance();
+
+ if ($index_page === TRUE)
+ {
+ $img .= ' src="'.$CI->config->site_url($v).'" ';
+ }
+ else
+ {
+ $img .= ' src="'.$CI->config->slash_item('base_url').$v.'" ';
+ }
+ }
+ else
+ {
+ $img .= " $k=\"$v\" ";
+ }
+ }
+
+ $img .= '/>';
+
+ return $img;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Doctype
+ *
+ * Generates a page document type declaration
+ *
+ * Valid options are xhtml-11, xhtml-strict, xhtml-trans, xhtml-frame,
+ * html4-strict, html4-trans, and html4-frame. Values are saved in the
+ * doctypes config file.
+ *
+ * @access public
+ * @param string type The doctype to be generated
+ * @return string
+ */
+if ( ! function_exists('doctype'))
+{
+ function doctype($type = 'xhtml1-strict')
+ {
+ global $_doctypes;
+
+ if ( ! is_array($_doctypes))
+ {
+ if ( ! require_once(APPPATH.'config/doctypes.php'))
+ {
+ return FALSE;
+ }
+ }
+
+ if (isset($_doctypes[$type]))
+ {
+ return $_doctypes[$type];
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Link
+ *
+ * Generates link to a CSS file
+ *
+ * @access public
+ * @param mixed stylesheet hrefs or an array
+ * @param string rel
+ * @param string type
+ * @param string title
+ * @param string media
+ * @param boolean should index_page be added to the css path
+ * @return string
+ */
+if ( ! function_exists('link_tag'))
+{
+ function link_tag($href = '', $rel = 'stylesheet', $type = 'text/css', $title = '', $media = '', $index_page = FALSE)
+ {
+ $CI =& get_instance();
+
+ $link = '<link ';
+
+ if (is_array($href))
+ {
+ foreach ($href as $k=>$v)
+ {
+ if ($k == 'href' AND strpos($v, '://') === FALSE)
+ {
+ if ($index_page === TRUE)
+ {
+ $link .= ' href="'.$CI->config->site_url($v).'" ';
+ }
+ else
+ {
+ $link .= ' href="'.$CI->config->slash_item('base_url').$v.'" ';
+ }
+ }
+ else
+ {
+ $link .= "$k=\"$v\" ";
+ }
+ }
+
+ $link .= "/>";
+ }
+ else
+ {
+ if ( strpos($href, '://') !== FALSE)
+ {
+ $link .= ' href="'.$href.'" ';
+ }
+ elseif ($index_page === TRUE)
+ {
+ $link .= ' href="'.$CI->config->site_url($href).'" ';
+ }
+ else
+ {
+ $link .= ' href="'.$CI->config->slash_item('base_url').$href.'" ';
+ }
+
+ $link .= 'rel="'.$rel.'" type="'.$type.'" ';
+
+ if ($media != '')
+ {
+ $link .= 'media="'.$media.'" ';
+ }
+
+ if ($title != '')
+ {
+ $link .= 'title="'.$title.'" ';
+ }
+
+ $link .= '/>';
+ }
+
+
+ return $link;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates meta tags from an array of key/values
+ *
+ * @access public
+ * @param array
+ * @return string
+ */
+if ( ! function_exists('meta'))
+{
+ function meta($name = '', $content = '', $type = 'name', $newline = "\n")
+ {
+ // Since we allow the data to be passes as a string, a simple array
+ // or a multidimensional one, we need to do a little prepping.
+ if ( ! is_array($name))
+ {
+ $name = array(array('name' => $name, 'content' => $content, 'type' => $type, 'newline' => $newline));
+ }
+ else
+ {
+ // Turn single array into multidimensional
+ if (isset($name['name']))
+ {
+ $name = array($name);
+ }
+ }
+
+ $str = '';
+ foreach ($name as $meta)
+ {
+ $type = ( ! isset($meta['type']) OR $meta['type'] == 'name') ? 'name' : 'http-equiv';
+ $name = ( ! isset($meta['name'])) ? '' : $meta['name'];
+ $content = ( ! isset($meta['content'])) ? '' : $meta['content'];
+ $newline = ( ! isset($meta['newline'])) ? "\n" : $meta['newline'];
+
+ $str .= '<meta '.$type.'="'.$name.'" content="'.$content.'" />'.$newline;
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Generates non-breaking space entities based on number supplied
+ *
+ * @access public
+ * @param integer
+ * @return string
+ */
+if ( ! function_exists('nbs'))
+{
+ function nbs($num = 1)
+ {
+ return str_repeat("&nbsp;", $num);
+ }
+}
+
+
+/* End of file html_helper.php */
+/* Location: ./system/helpers/html_helper.php */ \ No newline at end of file
diff --git a/system/helpers/index.html b/system/helpers/index.html
new file mode 100644
index 000000000..c942a79ce
--- /dev/null
+++ b/system/helpers/index.html
@@ -0,0 +1,10 @@
+<html>
+<head>
+ <title>403 Forbidden</title>
+</head>
+<body>
+
+<p>Directory access is forbidden.</p>
+
+</body>
+</html> \ No newline at end of file
diff --git a/system/helpers/inflector_helper.php b/system/helpers/inflector_helper.php
new file mode 100644
index 000000000..e65968a9d
--- /dev/null
+++ b/system/helpers/inflector_helper.php
@@ -0,0 +1,171 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Inflector Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/directory_helper.html
+ */
+
+
+// --------------------------------------------------------------------
+
+/**
+ * Singular
+ *
+ * Takes a plural word and makes it singular
+ *
+ * @access public
+ * @param string
+ * @return str
+ */
+if ( ! function_exists('singular'))
+{
+ function singular($str)
+ {
+ $str = strtolower(trim($str));
+ $end = substr($str, -3);
+
+ if ($end == 'ies')
+ {
+ $str = substr($str, 0, strlen($str)-3).'y';
+ }
+ elseif ($end == 'ses')
+ {
+ $str = substr($str, 0, strlen($str)-2);
+ }
+ else
+ {
+ $end = substr($str, -1);
+
+ if ($end == 's')
+ {
+ $str = substr($str, 0, strlen($str)-1);
+ }
+ }
+
+ return $str;
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Plural
+ *
+ * Takes a singular word and makes it plural
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return str
+ */
+if ( ! function_exists('plural'))
+{
+ function plural($str, $force = FALSE)
+ {
+ $str = strtolower(trim($str));
+ $end = substr($str, -1);
+
+ if ($end == 'y')
+ {
+ // Y preceded by vowel => regular plural
+ $vowels = array('a', 'e', 'i', 'o', 'u');
+ $str = in_array(substr($str, -2, 1), $vowels) ? $str.'s' : substr($str, 0, -1).'ies';
+ }
+ elseif ($end == 's')
+ {
+ if ($force == TRUE)
+ {
+ $str .= 'es';
+ }
+ }
+ else
+ {
+ $str .= 's';
+ }
+
+ return $str;
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Camelize
+ *
+ * Takes multiple words separated by spaces or underscores and camelizes them
+ *
+ * @access public
+ * @param string
+ * @return str
+ */
+if ( ! function_exists('camelize'))
+{
+ function camelize($str)
+ {
+ $str = 'x'.strtolower(trim($str));
+ $str = ucwords(preg_replace('/[\s_]+/', ' ', $str));
+ return substr(str_replace(' ', '', $str), 1);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Underscore
+ *
+ * Takes multiple words separated by spaces and underscores them
+ *
+ * @access public
+ * @param string
+ * @return str
+ */
+if ( ! function_exists('underscore'))
+{
+ function underscore($str)
+ {
+ return preg_replace('/[\s]+/', '_', strtolower(trim($str)));
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Humanize
+ *
+ * Takes multiple words separated by underscores and changes them to spaces
+ *
+ * @access public
+ * @param string
+ * @return str
+ */
+if ( ! function_exists('humanize'))
+{
+ function humanize($str)
+ {
+ return ucwords(preg_replace('/[_]+/', ' ', strtolower(trim($str))));
+ }
+}
+
+
+/* End of file inflector_helper.php */
+/* Location: ./system/helpers/inflector_helper.php */ \ No newline at end of file
diff --git a/system/helpers/language_helper.php b/system/helpers/language_helper.php
new file mode 100644
index 000000000..e97a8c78b
--- /dev/null
+++ b/system/helpers/language_helper.php
@@ -0,0 +1,58 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Language Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/language_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Lang
+ *
+ * Fetches a language variable and optionally outputs a form label
+ *
+ * @access public
+ * @param string the language line
+ * @param string the id of the form element
+ * @return string
+ */
+if ( ! function_exists('lang'))
+{
+ function lang($line, $id = '')
+ {
+ $CI =& get_instance();
+ $line = $CI->lang->line($line);
+
+ if ($id != '')
+ {
+ $line = '<label for="'.$id.'">'.$line."</label>";
+ }
+
+ return $line;
+ }
+}
+
+// ------------------------------------------------------------------------
+/* End of file language_helper.php */
+/* Location: ./system/helpers/language_helper.php */ \ No newline at end of file
diff --git a/system/helpers/number_helper.php b/system/helpers/number_helper.php
new file mode 100644
index 000000000..a041a60b7
--- /dev/null
+++ b/system/helpers/number_helper.php
@@ -0,0 +1,75 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Number Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/number_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Formats a numbers as bytes, based on size, and adds the appropriate suffix
+ *
+ * @access public
+ * @param mixed // will be cast as int
+ * @return string
+ */
+if ( ! function_exists('byte_format'))
+{
+ function byte_format($num)
+ {
+ $CI =& get_instance();
+ $CI->lang->load('number');
+
+ if ($num >= 1000000000000)
+ {
+ $num = round($num / 1099511627776, 1);
+ $unit = $CI->lang->line('terabyte_abbr');
+ }
+ elseif ($num >= 1000000000)
+ {
+ $num = round($num / 1073741824, 1);
+ $unit = $CI->lang->line('gigabyte_abbr');
+ }
+ elseif ($num >= 1000000)
+ {
+ $num = round($num / 1048576, 1);
+ $unit = $CI->lang->line('megabyte_abbr');
+ }
+ elseif ($num >= 1000)
+ {
+ $num = round($num / 1024, 1);
+ $unit = $CI->lang->line('kilobyte_abbr');
+ }
+ else
+ {
+ $unit = $CI->lang->line('bytes');
+ return number_format($num).' '.$unit;
+ }
+
+ return number_format($num, 1).' '.$unit;
+ }
+}
+
+/* End of file number_helper.php */
+/* Location: ./system/helpers/number_helper.php */ \ No newline at end of file
diff --git a/system/helpers/path_helper.php b/system/helpers/path_helper.php
new file mode 100644
index 000000000..502fae4b3
--- /dev/null
+++ b/system/helpers/path_helper.php
@@ -0,0 +1,72 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Path Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/xml_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set Realpath
+ *
+ * @access public
+ * @param string
+ * @param bool checks to see if the path exists
+ * @return string
+ */
+if ( ! function_exists('set_realpath'))
+{
+ function set_realpath($path, $check_existance = FALSE)
+ {
+ // Security check to make sure the path is NOT a URL. No remote file inclusion!
+ if (preg_match("#^(http:\/\/|https:\/\/|www\.|ftp|[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})#i", $path))
+ {
+ show_error('The path you submitted must be a local server path, not a URL');
+ }
+
+ // Resolve the path
+ if (function_exists('realpath') AND @realpath($path) !== FALSE)
+ {
+ $path = realpath($path).'/';
+ }
+
+ // Add a trailing slash
+ $path = preg_replace("#([^/])/*$#", "\\1/", $path);
+
+ // Make sure the path exists
+ if ($check_existance == TRUE)
+ {
+ if ( ! is_dir($path))
+ {
+ show_error('Not a valid path: '.$path);
+ }
+ }
+
+ return $path;
+ }
+}
+
+
+/* End of file path_helper.php */
+/* Location: ./system/helpers/path_helper.php */ \ No newline at end of file
diff --git a/system/helpers/security_helper.php b/system/helpers/security_helper.php
new file mode 100644
index 000000000..9cc70aaff
--- /dev/null
+++ b/system/helpers/security_helper.php
@@ -0,0 +1,126 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Security Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/security_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * XSS Filtering
+ *
+ * @access public
+ * @param string
+ * @param bool whether or not the content is an image file
+ * @return string
+ */
+if ( ! function_exists('xss_clean'))
+{
+ function xss_clean($str, $is_image = FALSE)
+ {
+ $CI =& get_instance();
+ return $CI->input->xss_clean($str, $is_image);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Hash encode a string
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('dohash'))
+{
+ function dohash($str, $type = 'sha1')
+ {
+ if ($type == 'sha1')
+ {
+ if ( ! function_exists('sha1'))
+ {
+ if ( ! function_exists('mhash'))
+ {
+ require_once(BASEPATH.'libraries/Sha1'.EXT);
+ $SH = new CI_SHA;
+ return $SH->generate($str);
+ }
+ else
+ {
+ return bin2hex(mhash(MHASH_SHA1, $str));
+ }
+ }
+ else
+ {
+ return sha1($str);
+ }
+ }
+ else
+ {
+ return md5($str);
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Image Tags
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('strip_image_tags'))
+{
+ function strip_image_tags($str)
+ {
+ $str = preg_replace("#<img\s+.*?src\s*=\s*[\"'](.+?)[\"'].*?\>#", "\\1", $str);
+ $str = preg_replace("#<img\s+.*?src\s*=\s*(.+?).*?\>#", "\\1", $str);
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert PHP tags to entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('encode_php_tags'))
+{
+ function encode_php_tags($str)
+ {
+ return str_replace(array('<?php', '<?PHP', '<?', '?>'), array('&lt;?php', '&lt;?PHP', '&lt;?', '?&gt;'), $str);
+ }
+}
+
+
+/* End of file security_helper.php */
+/* Location: ./system/helpers/security_helper.php */ \ No newline at end of file
diff --git a/system/helpers/smiley_helper.php b/system/helpers/smiley_helper.php
new file mode 100644
index 000000000..f085e53b1
--- /dev/null
+++ b/system/helpers/smiley_helper.php
@@ -0,0 +1,273 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Smiley Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/smiley_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Smiley Javascript
+ *
+ * Returns the javascript required for the smiley insertion. Optionally takes
+ * an array of aliases to loosely couple the smiley array to the view.
+ *
+ * @access public
+ * @param mixed alias name or array of alias->field_id pairs
+ * @param string field_id if alias name was passed in
+ * @return array
+ */
+if ( ! function_exists('smiley_js'))
+{
+ function smiley_js($alias = '', $field_id = '')
+ {
+ static $do_setup = TRUE;
+
+ $r = '';
+
+ if ($alias != '' && ! is_array($alias))
+ {
+ $alias = array($alias => $field_id);
+ }
+
+ if ($do_setup === TRUE)
+ {
+ $do_setup = FALSE;
+
+ $m = array();
+
+ if (is_array($alias))
+ {
+ foreach($alias as $name => $id)
+ {
+ $m[] = '"'.$name.'" : "'.$id.'"';
+ }
+ }
+
+ $m = '{'.implode(',', $m).'}';
+
+ $r .= <<<EOF
+
+ var smiley_map = {$m};
+
+ function insert_smiley(smiley, field_id) {
+ var el = document.getElementById(field_id), newStart;
+
+ if ( ! el && smiley_map[field_id]) {
+ el = document.getElementById(smiley_map[field_id]);
+
+ if ( ! el)
+ return false;
+ }
+
+ el.focus();
+ smiley = " " + smiley;
+
+ if ('selectionStart' in el) {
+ newStart = el.selectionStart + smiley.length;
+
+ el.value = el.value.substr(0, el.selectionStart) +
+ smiley +
+ el.value.substr(el.selectionEnd, el.value.length);
+ el.setSelectionRange(newStart, newStart);
+ }
+ else if (document.selection) {
+ document.selection.createRange().text = text;
+ }
+ }
+EOF;
+ }
+ else
+ {
+ if (is_array($alias))
+ {
+ foreach($alias as $name => $id)
+ {
+ $r .= 'smiley_map["'.$name.'"] = "'.$id.'";'."\n";
+ }
+ }
+ }
+
+ return '<script type="text/javascript" charset="utf-8">'.$r.'</script>';
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get Clickable Smileys
+ *
+ * Returns an array of image tag links that can be clicked to be inserted
+ * into a form field.
+ *
+ * @access public
+ * @param string the URL to the folder containing the smiley images
+ * @return array
+ */
+if ( ! function_exists('get_clickable_smileys'))
+{
+ function get_clickable_smileys($image_url, $alias = '', $smileys = NULL)
+ {
+ // For backward compatibility with js_insert_smiley
+
+ if (is_array($alias))
+ {
+ $smileys = $alias;
+ }
+
+ if ( ! is_array($smileys))
+ {
+ if (FALSE === ($smileys = _get_smiley_array()))
+ {
+ return $smileys;
+ }
+ }
+
+ // Add a trailing slash to the file path if needed
+ $image_url = rtrim($image_url, '/').'/';
+
+ $used = array();
+ foreach ($smileys as $key => $val)
+ {
+ // Keep duplicates from being used, which can happen if the
+ // mapping array contains multiple identical replacements. For example:
+ // :-) and :) might be replaced with the same image so both smileys
+ // will be in the array.
+ if (isset($used[$smileys[$key][0]]))
+ {
+ continue;
+ }
+
+ $link[] = "<a href=\"javascript:void(0);\" onClick=\"insert_smiley('".$key."', '".$alias."')\"><img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" /></a>";
+
+ $used[$smileys[$key][0]] = TRUE;
+ }
+
+ return $link;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse Smileys
+ *
+ * Takes a string as input and swaps any contained smileys for the actual image
+ *
+ * @access public
+ * @param string the text to be parsed
+ * @param string the URL to the folder containing the smiley images
+ * @return string
+ */
+if ( ! function_exists('parse_smileys'))
+{
+ function parse_smileys($str = '', $image_url = '', $smileys = NULL)
+ {
+ if ($image_url == '')
+ {
+ return $str;
+ }
+
+ if ( ! is_array($smileys))
+ {
+ if (FALSE === ($smileys = _get_smiley_array()))
+ {
+ return $str;
+ }
+ }
+
+ // Add a trailing slash to the file path if needed
+ $image_url = preg_replace("/(.+?)\/*$/", "\\1/", $image_url);
+
+ foreach ($smileys as $key => $val)
+ {
+ $str = str_replace($key, "<img src=\"".$image_url.$smileys[$key][0]."\" width=\"".$smileys[$key][1]."\" height=\"".$smileys[$key][2]."\" alt=\"".$smileys[$key][3]."\" style=\"border:0;\" />", $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Get Smiley Array
+ *
+ * Fetches the config/smiley.php file
+ *
+ * @access private
+ * @return mixed
+ */
+if ( ! function_exists('_get_smiley_array'))
+{
+ function _get_smiley_array()
+ {
+ if ( ! file_exists(APPPATH.'config/smileys'.EXT))
+ {
+ return FALSE;
+ }
+
+ include(APPPATH.'config/smileys'.EXT);
+
+ if ( ! isset($smileys) OR ! is_array($smileys))
+ {
+ return FALSE;
+ }
+
+ return $smileys;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * JS Insert Smiley
+ *
+ * Generates the javascript function needed to insert smileys into a form field
+ *
+ * DEPRECATED as of version 1.7.2, use smiley_js instead
+ *
+ * @access public
+ * @param string form name
+ * @param string field name
+ * @return string
+ */
+if ( ! function_exists('js_insert_smiley'))
+{
+ function js_insert_smiley($form_name = '', $form_field = '')
+ {
+ return <<<EOF
+<script type="text/javascript">
+ function insert_smiley(smiley)
+ {
+ document.{$form_name}.{$form_field}.value += " " + smiley;
+ }
+</script>
+EOF;
+ }
+}
+
+
+/* End of file smiley_helper.php */
+/* Location: ./system/helpers/smiley_helper.php */ \ No newline at end of file
diff --git a/system/helpers/string_helper.php b/system/helpers/string_helper.php
new file mode 100644
index 000000000..3f7f09a15
--- /dev/null
+++ b/system/helpers/string_helper.php
@@ -0,0 +1,273 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter String Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/string_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Trim Slashes
+ *
+ * Removes any leading/traling slashes from a string:
+ *
+ * /this/that/theother/
+ *
+ * becomes:
+ *
+ * this/that/theother
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('trim_slashes'))
+{
+ function trim_slashes($str)
+ {
+ return trim($str, '/');
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Slashes
+ *
+ * Removes slashes contained in a string or in an array
+ *
+ * @access public
+ * @param mixed string or array
+ * @return mixed string or array
+ */
+if ( ! function_exists('strip_slashes'))
+{
+ function strip_slashes($str)
+ {
+ if (is_array($str))
+ {
+ foreach ($str as $key => $val)
+ {
+ $str[$key] = strip_slashes($val);
+ }
+ }
+ else
+ {
+ $str = stripslashes($str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Strip Quotes
+ *
+ * Removes single and double quotes from a string
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('strip_quotes'))
+{
+ function strip_quotes($str)
+ {
+ return str_replace(array('"', "'"), '', $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Quotes to Entities
+ *
+ * Converts single and double quotes to entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('quotes_to_entities'))
+{
+ function quotes_to_entities($str)
+ {
+ return str_replace(array("\'","\"","'",'"'), array("&#39;","&quot;","&#39;","&quot;"), $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+/**
+ * Reduce Double Slashes
+ *
+ * Converts double slashes in a string to a single slash,
+ * except those found in http://
+ *
+ * http://www.some-site.com//index.php
+ *
+ * becomes:
+ *
+ * http://www.some-site.com/index.php
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('reduce_double_slashes'))
+{
+ function reduce_double_slashes($str)
+ {
+ return preg_replace("#([^:])//+#", "\\1/", $str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Reduce Multiples
+ *
+ * Reduces multiple instances of a particular character. Example:
+ *
+ * Fred, Bill,, Joe, Jimmy
+ *
+ * becomes:
+ *
+ * Fred, Bill, Joe, Jimmy
+ *
+ * @access public
+ * @param string
+ * @param string the character you wish to reduce
+ * @param bool TRUE/FALSE - whether to trim the character from the beginning/end
+ * @return string
+ */
+if ( ! function_exists('reduce_multiples'))
+{
+ function reduce_multiples($str, $character = ',', $trim = FALSE)
+ {
+ $str = preg_replace('#'.preg_quote($character, '#').'{2,}#', $character, $str);
+
+ if ($trim === TRUE)
+ {
+ $str = trim($str, $character);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Create a Random String
+ *
+ * Useful for generating passwords or hashes.
+ *
+ * @access public
+ * @param string type of random string. Options: alunum, numeric, nozero, unique
+ * @param integer number of characters
+ * @return string
+ */
+if ( ! function_exists('random_string'))
+{
+ function random_string($type = 'alnum', $len = 8)
+ {
+ switch($type)
+ {
+ case 'alnum' :
+ case 'numeric' :
+ case 'nozero' :
+
+ switch ($type)
+ {
+ case 'alnum' : $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ break;
+ case 'numeric' : $pool = '0123456789';
+ break;
+ case 'nozero' : $pool = '123456789';
+ break;
+ }
+
+ $str = '';
+ for ($i=0; $i < $len; $i++)
+ {
+ $str .= substr($pool, mt_rand(0, strlen($pool) -1), 1);
+ }
+ return $str;
+ break;
+ case 'unique' : return md5(uniqid(mt_rand()));
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Alternator
+ *
+ * Allows strings to be alternated. See docs...
+ *
+ * @access public
+ * @param string (as many parameters as needed)
+ * @return string
+ */
+if ( ! function_exists('alternator'))
+{
+ function alternator()
+ {
+ static $i;
+
+ if (func_num_args() == 0)
+ {
+ $i = 0;
+ return '';
+ }
+ $args = func_get_args();
+ return $args[($i++ % count($args))];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Repeater function
+ *
+ * @access public
+ * @param string
+ * @param integer number of repeats
+ * @return string
+ */
+if ( ! function_exists('repeater'))
+{
+ function repeater($data, $num = 1)
+ {
+ return (($num > 0) ? str_repeat($data, $num) : '');
+ }
+}
+
+
+/* End of file string_helper.php */
+/* Location: ./system/helpers/string_helper.php */ \ No newline at end of file
diff --git a/system/helpers/text_helper.php b/system/helpers/text_helper.php
new file mode 100644
index 000000000..06910e411
--- /dev/null
+++ b/system/helpers/text_helper.php
@@ -0,0 +1,462 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Text Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/text_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Limiter
+ *
+ * Limits a string to X number of words.
+ *
+ * @access public
+ * @param string
+ * @param integer
+ * @param string the end character. Usually an ellipsis
+ * @return string
+ */
+if ( ! function_exists('word_limiter'))
+{
+ function word_limiter($str, $limit = 100, $end_char = '&#8230;')
+ {
+ if (trim($str) == '')
+ {
+ return $str;
+ }
+
+ preg_match('/^\s*+(?:\S++\s*+){1,'.(int) $limit.'}/', $str, $matches);
+
+ if (strlen($str) == strlen($matches[0]))
+ {
+ $end_char = '';
+ }
+
+ return rtrim($matches[0]).$end_char;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Character Limiter
+ *
+ * Limits the string based on the character count. Preserves complete words
+ * so the character count may not be exactly as specified.
+ *
+ * @access public
+ * @param string
+ * @param integer
+ * @param string the end character. Usually an ellipsis
+ * @return string
+ */
+if ( ! function_exists('character_limiter'))
+{
+ function character_limiter($str, $n = 500, $end_char = '&#8230;')
+ {
+ if (strlen($str) < $n)
+ {
+ return $str;
+ }
+
+ $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.' ';
+
+ if (strlen($out) >= $n)
+ {
+ $out = trim($out);
+ return (strlen($out) == strlen($str)) ? $out : $out.$end_char;
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * High ASCII to Entities
+ *
+ * Converts High ascii text and MS Word special characters to character entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('ascii_to_entities'))
+{
+ function ascii_to_entities($str)
+ {
+ $count = 1;
+ $out = '';
+ $temp = array();
+
+ for ($i = 0, $s = strlen($str); $i < $s; $i++)
+ {
+ $ordinal = ord($str[$i]);
+
+ if ($ordinal < 128)
+ {
+ /*
+ If the $temp array has a value but we have moved on, then it seems only
+ fair that we output that entity and restart $temp before continuing. -Paul
+ */
+ if (count($temp) == 1)
+ {
+ $out .= '&#'.array_shift($temp).';';
+ $count = 1;
+ }
+
+ $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;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Entities to ASCII
+ *
+ * Converts character entities back to ASCII
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return string
+ */
+if ( ! function_exists('entities_to_ascii'))
+{
+ function entities_to_ascii($str, $all = TRUE)
+ {
+ if (preg_match_all('/\&#(\d+)\;/', $str, $matches))
+ {
+ for ($i = 0, $s = count($matches['0']); $i < $s; $i++)
+ {
+ $digits = $matches['1'][$i];
+
+ $out = '';
+
+ if ($digits < 128)
+ {
+ $out .= chr($digits);
+
+ }
+ elseif ($digits < 2048)
+ {
+ $out .= chr(192 + (($digits - ($digits % 64)) / 64));
+ $out .= chr(128 + ($digits % 64));
+ }
+ else
+ {
+ $out .= chr(224 + (($digits - ($digits % 4096)) / 4096));
+ $out .= chr(128 + ((($digits % 4096) - ($digits % 64)) / 64));
+ $out .= chr(128 + ($digits % 64));
+ }
+
+ $str = str_replace($matches['0'][$i], $out, $str);
+ }
+ }
+
+ if ($all)
+ {
+ $str = str_replace(array("&amp;", "&lt;", "&gt;", "&quot;", "&apos;", "&#45;"),
+ array("&","<",">","\"", "'", "-"),
+ $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Censoring Function
+ *
+ * Supply a string and an array of disallowed words and any
+ * matched words will be converted to #### or to the replacement
+ * word you've submitted.
+ *
+ * @access public
+ * @param string the text string
+ * @param string the array of censoered words
+ * @param string the optional replacement value
+ * @return string
+ */
+if ( ! function_exists('word_censor'))
+{
+ function word_censor($str, $censored, $replacement = '')
+ {
+ if ( ! is_array($censored))
+ {
+ return $str;
+ }
+
+ $str = ' '.$str.' ';
+
+ // \w, \b and a few others do not match on a unicode character
+ // set for performance reasons. As a result words like über
+ // will not match on a word boundary. Instead, we'll assume that
+ // a bad word will be bookended by any of these characters.
+ $delim = '[-_\'\"`(){}<>\[\]|!?@#%&,.:;^~*+=\/ 0-9\n\r\t]';
+
+ foreach ($censored as $badword)
+ {
+ if ($replacement != '')
+ {
+ $str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/i", "\\1{$replacement}\\3", $str);
+ }
+ else
+ {
+ $str = preg_replace("/({$delim})(".str_replace('\*', '\w*?', preg_quote($badword, '/')).")({$delim})/ie", "'\\1'.str_repeat('#', strlen('\\2')).'\\3'", $str);
+ }
+ }
+
+ return trim($str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Code Highlighter
+ *
+ * Colorizes code strings
+ *
+ * @access public
+ * @param string the text string
+ * @return string
+ */
+if ( ! function_exists('highlight_code'))
+{
+ function highlight_code($str)
+ {
+ // The highlight string function encodes and highlights
+ // brackets so we need them to start raw
+ $str = str_replace(array('&lt;', '&gt;'), array('<', '>'), $str);
+
+ // Replace any existing PHP tags to temporary markers so they don't accidentally
+ // break the string out of PHP, and thus, thwart the highlighting.
+
+ $str = str_replace(array('<?', '?>', '<%', '%>', '\\', '</script>'),
+ array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'), $str);
+
+ // The highlight_string function requires that the text be surrounded
+ // by PHP tags, which we will remove later
+ $str = '<?php '.$str.' ?>'; // <?
+
+ // All the magic happens here, baby!
+ $str = highlight_string($str, TRUE);
+
+ // Prior to PHP 5, the highligh function used icky <font> tags
+ // so we'll replace them with <span> tags.
+
+ if (abs(PHP_VERSION) < 5)
+ {
+ $str = str_replace(array('<font ', '</font>'), array('<span ', '</span>'), $str);
+ $str = preg_replace('#color="(.*?)"#', 'style="color: \\1"', $str);
+ }
+
+ // Remove our artificially added PHP, and the syntax highlighting that came with it
+ $str = preg_replace('/<span style="color: #([A-Z0-9]+)">&lt;\?php(&nbsp;| )/i', '<span style="color: #$1">', $str);
+ $str = preg_replace('/(<span style="color: #[A-Z0-9]+">.*?)\?&gt;<\/span>\n<\/span>\n<\/code>/is', "$1</span>\n</span>\n</code>", $str);
+ $str = preg_replace('/<span style="color: #[A-Z0-9]+"\><\/span>/i', '', $str);
+
+ // Replace our markers back to PHP tags.
+ $str = str_replace(array('phptagopen', 'phptagclose', 'asptagopen', 'asptagclose', 'backslashtmp', 'scriptclose'),
+ array('&lt;?', '?&gt;', '&lt;%', '%&gt;', '\\', '&lt;/script&gt;'), $str);
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Phrase Highlighter
+ *
+ * Highlights a phrase within a text string
+ *
+ * @access public
+ * @param string the text string
+ * @param string the phrase you'd like to highlight
+ * @param string the openging tag to precede the phrase with
+ * @param string the closing tag to end the phrase with
+ * @return string
+ */
+if ( ! function_exists('highlight_phrase'))
+{
+ function highlight_phrase($str, $phrase, $tag_open = '<strong>', $tag_close = '</strong>')
+ {
+ if ($str == '')
+ {
+ return '';
+ }
+
+ if ($phrase != '')
+ {
+ return preg_replace('/('.preg_quote($phrase, '/').')/i', $tag_open."\\1".$tag_close, $str);
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Word Wrap
+ *
+ * Wraps text at the specified character. Maintains the integrity of words.
+ * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor
+ * will URLs.
+ *
+ * @access public
+ * @param string the text string
+ * @param integer the number of characters to wrap at
+ * @return string
+ */
+if ( ! function_exists('word_wrap'))
+{
+ function word_wrap($str, $charlim = '76')
+ {
+ // Se the character limit
+ if ( ! is_numeric($charlim))
+ $charlim = 76;
+
+ // Reduce multiple spaces
+ $str = preg_replace("| +|", " ", $str);
+
+ // Standardize newlines
+ if (strpos($str, "\r") !== FALSE)
+ {
+ $str = str_replace(array("\r\n", "\r"), "\n", $str);
+ }
+
+ // If the current word is surrounded by {unwrap} tags we'll
+ // strip the entire chunk and replace it with a marker.
+ $unwrap = array();
+ if (preg_match_all("|(\{unwrap\}.+?\{/unwrap\})|s", $str, $matches))
+ {
+ for ($i = 0; $i < count($matches['0']); $i++)
+ {
+ $unwrap[] = $matches['1'][$i];
+ $str = str_replace($matches['1'][$i], "{{unwrapped".$i."}}", $str);
+ }
+ }
+
+ // Use PHP's native 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);
+
+ // Split the string into individual lines of text and cycle through them
+ $output = "";
+ foreach (explode("\n", $str) as $line)
+ {
+ // Is the line within the allowed character count?
+ // If so we'll join it to the output and continue
+ if (strlen($line) <= $charlim)
+ {
+ $output .= $line."\n";
+ continue;
+ }
+
+ $temp = '';
+ while((strlen($line)) > $charlim)
+ {
+ // If the over-length word is a URL we won't wrap it
+ if (preg_match("!\[url.+\]|://|wwww.!", $line))
+ {
+ break;
+ }
+
+ // Trim the word down
+ $temp .= substr($line, 0, $charlim-1);
+ $line = substr($line, $charlim-1);
+ }
+
+ // If $temp contains data it means we had to split up an over-length
+ // word into smaller chunks so we'll add it back to our current line
+ if ($temp != '')
+ {
+ $output .= $temp . "\n" . $line;
+ }
+ else
+ {
+ $output .= $line;
+ }
+
+ $output .= "\n";
+ }
+
+ // Put our markers back
+ if (count($unwrap) > 0)
+ {
+ foreach ($unwrap as $key => $val)
+ {
+ $output = str_replace("{{unwrapped".$key."}}", $val, $output);
+ }
+ }
+
+ // Remove the unwrap tags
+ $output = str_replace(array('{unwrap}', '{/unwrap}'), '', $output);
+
+ return $output;
+ }
+}
+
+
+/* End of file text_helper.php */
+/* Location: ./system/helpers/text_helper.php */ \ No newline at end of file
diff --git a/system/helpers/typography_helper.php b/system/helpers/typography_helper.php
new file mode 100644
index 000000000..2706d53b0
--- /dev/null
+++ b/system/helpers/typography_helper.php
@@ -0,0 +1,71 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter Typography Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/typography_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert newlines to HTML line breaks except within PRE tags
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('nl2br_except_pre'))
+{
+ function nl2br_except_pre($str)
+ {
+ $CI =& get_instance();
+
+ $CI->load->library('typography');
+
+ return $CI->typography->nl2br_except_pre($str);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Auto Typography Wrapper Function
+ *
+ *
+ * @access public
+ * @param string
+ * @param bool whether to reduce multiple instances of double newlines to two
+ * @return string
+ */
+if ( ! function_exists('auto_typography'))
+{
+ function auto_typography($str, $reduce_linebreaks = FALSE)
+ {
+ $CI =& get_instance();
+ $CI->load->library('typography');
+ return $CI->typography->auto_typography($str, $reduce_linebreaks);
+ }
+}
+
+/* End of file typography_helper.php */
+/* Location: ./system/helpers/typography_helper.php */ \ No newline at end of file
diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php
new file mode 100644
index 000000000..546552a69
--- /dev/null
+++ b/system/helpers/url_helper.php
@@ -0,0 +1,593 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter URL Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/url_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Site URL
+ *
+ * Create a local URL based on your basepath. Segments can be passed via the
+ * first parameter either as a string or an array.
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('site_url'))
+{
+ function site_url($uri = '')
+ {
+ $CI =& get_instance();
+ return $CI->config->site_url($uri);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Base URL
+ *
+ * Returns the "base_url" item from your config file
+ *
+ * @access public
+ * @return string
+ */
+if ( ! function_exists('base_url'))
+{
+ function base_url()
+ {
+ $CI =& get_instance();
+ return $CI->config->slash_item('base_url');
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Current URL
+ *
+ * Returns the full URL (including segments) of the page where this
+ * function is placed
+ *
+ * @access public
+ * @return string
+ */
+if ( ! function_exists('current_url'))
+{
+ function current_url()
+ {
+ $CI =& get_instance();
+ return $CI->config->site_url($CI->uri->uri_string());
+ }
+}
+
+// ------------------------------------------------------------------------
+/**
+ * URL String
+ *
+ * Returns the URI segments.
+ *
+ * @access public
+ * @return string
+ */
+if ( ! function_exists('uri_string'))
+{
+ function uri_string()
+ {
+ $CI =& get_instance();
+ return $CI->uri->uri_string();
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Index page
+ *
+ * Returns the "index_page" from your config file
+ *
+ * @access public
+ * @return string
+ */
+if ( ! function_exists('index_page'))
+{
+ function index_page()
+ {
+ $CI =& get_instance();
+ return $CI->config->item('index_page');
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Anchor Link
+ *
+ * Creates an anchor based on the local URL.
+ *
+ * @access public
+ * @param string the URL
+ * @param string the link title
+ * @param mixed any attributes
+ * @return string
+ */
+if ( ! function_exists('anchor'))
+{
+ function anchor($uri = '', $title = '', $attributes = '')
+ {
+ $title = (string) $title;
+
+ if ( ! is_array($uri))
+ {
+ $site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;
+ }
+ else
+ {
+ $site_url = site_url($uri);
+ }
+
+ if ($title == '')
+ {
+ $title = $site_url;
+ }
+
+ if ($attributes != '')
+ {
+ $attributes = _parse_attributes($attributes);
+ }
+
+ return '<a href="'.$site_url.'"'.$attributes.'>'.$title.'</a>';
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Anchor Link - Pop-up version
+ *
+ * Creates an anchor based on the local URL. The link
+ * opens a new window based on the attributes specified.
+ *
+ * @access public
+ * @param string the URL
+ * @param string the link title
+ * @param mixed any attributes
+ * @return string
+ */
+if ( ! function_exists('anchor_popup'))
+{
+ function anchor_popup($uri = '', $title = '', $attributes = FALSE)
+ {
+ $title = (string) $title;
+
+ $site_url = ( ! preg_match('!^\w+://! i', $uri)) ? site_url($uri) : $uri;
+
+ if ($title == '')
+ {
+ $title = $site_url;
+ }
+
+ if ($attributes === FALSE)
+ {
+ return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank');\">".$title."</a>";
+ }
+
+ if ( ! is_array($attributes))
+ {
+ $attributes = array();
+ }
+
+ foreach (array('width' => '800', 'height' => '600', 'scrollbars' => 'yes', 'status' => 'yes', 'resizable' => 'yes', 'screenx' => '0', 'screeny' => '0', ) as $key => $val)
+ {
+ $atts[$key] = ( ! isset($attributes[$key])) ? $val : $attributes[$key];
+ unset($attributes[$key]);
+ }
+
+ if ($attributes != '')
+ {
+ $attributes = _parse_attributes($attributes);
+ }
+
+ return "<a href='javascript:void(0);' onclick=\"window.open('".$site_url."', '_blank', '"._parse_attributes($atts, TRUE)."');\"$attributes>".$title."</a>";
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Mailto Link
+ *
+ * @access public
+ * @param string the email address
+ * @param string the link title
+ * @param mixed any attributes
+ * @return string
+ */
+if ( ! function_exists('mailto'))
+{
+ function mailto($email, $title = '', $attributes = '')
+ {
+ $title = (string) $title;
+
+ if ($title == "")
+ {
+ $title = $email;
+ }
+
+ $attributes = _parse_attributes($attributes);
+
+ return '<a href="mailto:'.$email.'"'.$attributes.'>'.$title.'</a>';
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Encoded Mailto Link
+ *
+ * Create a spam-protected mailto link written in Javascript
+ *
+ * @access public
+ * @param string the email address
+ * @param string the link title
+ * @param mixed any attributes
+ * @return string
+ */
+if ( ! function_exists('safe_mailto'))
+{
+ function safe_mailto($email, $title = '', $attributes = '')
+ {
+ $title = (string) $title;
+
+ if ($title == "")
+ {
+ $title = $email;
+ }
+
+ for ($i = 0; $i < 16; $i++)
+ {
+ $x[] = substr('<a href="mailto:', $i, 1);
+ }
+
+ for ($i = 0; $i < strlen($email); $i++)
+ {
+ $x[] = "|".ord(substr($email, $i, 1));
+ }
+
+ $x[] = '"';
+
+ if ($attributes != '')
+ {
+ if (is_array($attributes))
+ {
+ foreach ($attributes as $key => $val)
+ {
+ $x[] = ' '.$key.'="';
+ for ($i = 0; $i < strlen($val); $i++)
+ {
+ $x[] = "|".ord(substr($val, $i, 1));
+ }
+ $x[] = '"';
+ }
+ }
+ else
+ {
+ for ($i = 0; $i < strlen($attributes); $i++)
+ {
+ $x[] = substr($attributes, $i, 1);
+ }
+ }
+ }
+
+ $x[] = '>';
+
+ $temp = array();
+ for ($i = 0; $i < strlen($title); $i++)
+ {
+ $ordinal = ord($title[$i]);
+
+ if ($ordinal < 128)
+ {
+ $x[] = "|".$ordinal;
+ }
+ 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);
+ $x[] = "|".$number;
+ $count = 1;
+ $temp = array();
+ }
+ }
+ }
+
+ $x[] = '<'; $x[] = '/'; $x[] = 'a'; $x[] = '>';
+
+ $x = array_reverse($x);
+ ob_start();
+
+ ?><script type="text/javascript">
+ //<![CDATA[
+ var l=new Array();
+ <?php
+ $i = 0;
+ foreach ($x as $val){ ?>l[<?php echo $i++; ?>]='<?php echo $val; ?>';<?php } ?>
+
+ for (var i = l.length-1; i >= 0; i=i-1){
+ if (l[i].substring(0, 1) == '|') document.write("&#"+unescape(l[i].substring(1))+";");
+ else document.write(unescape(l[i]));}
+ //]]>
+ </script><?php
+
+ $buffer = ob_get_contents();
+ ob_end_clean();
+ return $buffer;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Auto-linker
+ *
+ * Automatically links URL and Email addresses.
+ * Note: There's a bit of extra code here to deal with
+ * URLs or emails that end in a period. We'll strip these
+ * off and add them after the link.
+ *
+ * @access public
+ * @param string the string
+ * @param string the type: email, url, or both
+ * @param bool whether to create pop-up links
+ * @return string
+ */
+if ( ! function_exists('auto_link'))
+{
+ function auto_link($str, $type = 'both', $popup = FALSE)
+ {
+ if ($type != 'email')
+ {
+ if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches))
+ {
+ $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
+
+ for ($i = 0; $i < count($matches['0']); $i++)
+ {
+ $period = '';
+ if (preg_match("|\.$|", $matches['6'][$i]))
+ {
+ $period = '.';
+ $matches['6'][$i] = substr($matches['6'][$i], 0, -1);
+ }
+
+ $str = str_replace($matches['0'][$i],
+ $matches['1'][$i].'<a href="http'.
+ $matches['4'][$i].'://'.
+ $matches['5'][$i].
+ $matches['6'][$i].'"'.$pop.'>http'.
+ $matches['4'][$i].'://'.
+ $matches['5'][$i].
+ $matches['6'][$i].'</a>'.
+ $period, $str);
+ }
+ }
+ }
+
+ if ($type != 'url')
+ {
+ if (preg_match_all("/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches))
+ {
+ for ($i = 0; $i < count($matches['0']); $i++)
+ {
+ $period = '';
+ if (preg_match("|\.$|", $matches['3'][$i]))
+ {
+ $period = '.';
+ $matches['3'][$i] = substr($matches['3'][$i], 0, -1);
+ }
+
+ $str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str);
+ }
+ }
+ }
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Prep URL
+ *
+ * Simply adds the http:// part if missing
+ *
+ * @access public
+ * @param string the URL
+ * @return string
+ */
+if ( ! function_exists('prep_url'))
+{
+ 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;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Create URL Title
+ *
+ * Takes a "title" string as input and creates a
+ * human-friendly URL string with either a dash
+ * or an underscore as the word separator.
+ *
+ * @access public
+ * @param string the string
+ * @param string the separator: dash, or underscore
+ * @return string
+ */
+if ( ! function_exists('url_title'))
+{
+ function url_title($str, $separator = 'dash', $lowercase = FALSE)
+ {
+ if ($separator == 'dash')
+ {
+ $search = '_';
+ $replace = '-';
+ }
+ else
+ {
+ $search = '-';
+ $replace = '_';
+ }
+
+ $trans = array(
+ '&\#\d+?;' => '',
+ '&\S+?;' => '',
+ '\s+' => $replace,
+ '[^a-z0-9\-\._]' => '',
+ $replace.'+' => $replace,
+ $replace.'$' => $replace,
+ '^'.$replace => $replace,
+ '\.+$' => ''
+ );
+
+ $str = strip_tags($str);
+
+ foreach ($trans as $key => $val)
+ {
+ $str = preg_replace("#".$key."#i", $val, $str);
+ }
+
+ if ($lowercase === TRUE)
+ {
+ $str = strtolower($str);
+ }
+
+ return trim(stripslashes($str));
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Header Redirect
+ *
+ * Header redirect in two flavors
+ * For very fine grained control over headers, you could use the Output
+ * Library's set_header() function.
+ *
+ * @access public
+ * @param string the URL
+ * @param string the method: location or redirect
+ * @return string
+ */
+if ( ! function_exists('redirect'))
+{
+ function redirect($uri = '', $method = 'location', $http_response_code = 302)
+ {
+ if ( ! preg_match('#^https?://#i', $uri))
+ {
+ $uri = site_url($uri);
+ }
+
+ switch($method)
+ {
+ case 'refresh' : header("Refresh:0;url=".$uri);
+ break;
+ default : header("Location: ".$uri, TRUE, $http_response_code);
+ break;
+ }
+ exit;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Parse out the attributes
+ *
+ * Some of the functions use this
+ *
+ * @access private
+ * @param array
+ * @param bool
+ * @return string
+ */
+if ( ! function_exists('_parse_attributes'))
+{
+ function _parse_attributes($attributes, $javascript = FALSE)
+ {
+ if (is_string($attributes))
+ {
+ return ($attributes != '') ? ' '.$attributes : '';
+ }
+
+ $att = '';
+ foreach ($attributes as $key => $val)
+ {
+ if ($javascript == TRUE)
+ {
+ $att .= $key . '=' . $val . ',';
+ }
+ else
+ {
+ $att .= ' ' . $key . '="' . $val . '"';
+ }
+ }
+
+ if ($javascript == TRUE AND $att != '')
+ {
+ $att = substr($att, 0, -1);
+ }
+
+ return $att;
+ }
+}
+
+
+/* End of file url_helper.php */
+/* Location: ./system/helpers/url_helper.php */ \ No newline at end of file
diff --git a/system/helpers/xml_helper.php b/system/helpers/xml_helper.php
new file mode 100644
index 000000000..2a4c808ce
--- /dev/null
+++ b/system/helpers/xml_helper.php
@@ -0,0 +1,62 @@
+<?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 - 2009, EllisLab, Inc.
+ * @license http://codeigniter.com/user_guide/license.html
+ * @link http://codeigniter.com
+ * @since Version 1.0
+ * @filesource
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * CodeIgniter XML Helpers
+ *
+ * @package CodeIgniter
+ * @subpackage Helpers
+ * @category Helpers
+ * @author ExpressionEngine Dev Team
+ * @link http://codeigniter.com/user_guide/helpers/xml_helper.html
+ */
+
+// ------------------------------------------------------------------------
+
+/**
+ * Convert Reserved XML characters to Entities
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('xml_convert'))
+{
+ function xml_convert($str)
+ {
+ $temp = '__TEMP_AMPERSANDS__';
+
+ // Replace entities to temporary markers so that
+ // ampersands won't get messed up
+ $str = preg_replace("/&#(\d+);/", "$temp\\1;", $str);
+ $str = preg_replace("/&(\w+);/", "$temp\\1;", $str);
+
+ $str = str_replace(array("&","<",">","\"", "'", "-"),
+ array("&amp;", "&lt;", "&gt;", "&quot;", "&#39;", "&#45;"),
+ $str);
+
+ // Decode the temp markers back to entities
+ $str = preg_replace("/$temp(\d+);/","&#\\1;",$str);
+ $str = preg_replace("/$temp(\w+);/","&\\1;", $str);
+
+ return $str;
+ }
+}
+
+
+/* End of file xml_helper.php */
+/* Location: ./system/helpers/xml_helper.php */ \ No newline at end of file