diff --git a/OpenVBX/config/autoload.php b/OpenVBX/config/autoload.php
index f38b7359..997b55a2 100644
--- a/OpenVBX/config/autoload.php
+++ b/OpenVBX/config/autoload.php
@@ -8,7 +8,7 @@
| In order to keep the framework as light-weight as possible only the
| absolute minimal resources are loaded by default. For example,
| the database is not connected to automatically since no assumption
-| is made regarding whether you intend to use it. This file lets
+| is made regarding whether you intend to use it. This file lets
| you globally define which systems you would like loaded with every
| request.
|
@@ -18,15 +18,28 @@
|
| These are the things you can load automatically:
|
-| 1. Libraries
-| 2. Helper files
-| 3. Plugins
-| 4. Custom config files
-| 5. Language files
-| 6. Models
+| 1. Packages
+| 2. Libraries
+| 3. Drivers
+| 4. Helper files
+| 5. Custom config files
+| 6. Language files
+| 7. Models
|
*/
+/*
+| -------------------------------------------------------------------
+| Auto-load Packages
+| -------------------------------------------------------------------
+| Prototype:
+|
+| $autoload['packages'] = array(APPPATH.'third_party', '/usr/local/shared');
+|
+*/
+
+$autoload['packages'] = array();
+
/*
| -------------------------------------------------------------------
| Auto-load Libraries
@@ -43,26 +56,29 @@
/*
| -------------------------------------------------------------------
-| Auto-load Helper Files
+| Auto-load Drivers
| -------------------------------------------------------------------
+| These classes are located in the system/libraries folder or in your
+| application/libraries folder within their own subdirectory. They
+| offer multiple interchangeable driver options.
+|
| Prototype:
|
-| $autoload['helper'] = array('url', 'file');
+| $autoload['drivers'] = array('session', 'cache');
*/
-$autoload['helper'] = array('applet', 'url', 'format', 'form', 'mail', 'json', 'model', 'banner');
-
+$autoload['drivers'] = array();
/*
| -------------------------------------------------------------------
-| Auto-load Plugins
+| Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|
-| $autoload['plugin'] = array('captcha', 'js_calendar');
+| $autoload['helper'] = array('url', 'file');
*/
-$autoload['plugin'] = array();
+$autoload['helper'] = array('applet', 'url', 'format', 'form', 'mail', 'json', 'model', 'banner');
/*
diff --git a/OpenVBX/config/cache.php b/OpenVBX/config/cache.php
index 2b1b4815..473964ff 100644
--- a/OpenVBX/config/cache.php
+++ b/OpenVBX/config/cache.php
@@ -53,4 +53,4 @@
*/
if (is_file(APPPATH.'config/cache-local.php')) {
include_once(APPPATH.'config/cache-local.php');
-}
\ No newline at end of file
+}
diff --git a/OpenVBX/config/config.php b/OpenVBX/config/config.php
index 958c0c70..d0c93db5 100755
--- a/OpenVBX/config/config.php
+++ b/OpenVBX/config/config.php
@@ -317,7 +317,7 @@
| enabled you MUST set an encryption key. See the user guide for info.
|
*/
-$config['encryption_key'] = "";
+$config['encryption_key'] = '';
/*
|--------------------------------------------------------------------------
@@ -337,6 +337,7 @@
$config['sess_use_database'] = FALSE;
$config['sess_table_name'] = 'sessions';
$config['sess_match_ip'] = FALSE;
+$config['sess_match_useragent'] = FALSE;
$config['sess_time_to_update'] = 300;
/*
diff --git a/OpenVBX/config/foreign_chars.php b/OpenVBX/config/foreign_chars.php
new file mode 100644
index 00000000..14b0d737
--- /dev/null
+++ b/OpenVBX/config/foreign_chars.php
@@ -0,0 +1,64 @@
+ 'ae',
+ '/ö|œ/' => 'oe',
+ '/ü/' => 'ue',
+ '/Ä/' => 'Ae',
+ '/Ü/' => 'Ue',
+ '/Ö/' => 'Oe',
+ '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ/' => 'A',
+ '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª/' => 'a',
+ '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
+ '/ç|ć|ĉ|ċ|č/' => 'c',
+ '/Ð|Ď|Đ/' => 'D',
+ '/ð|ď|đ/' => 'd',
+ '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě/' => 'E',
+ '/è|é|ê|ë|ē|ĕ|ė|ę|ě/' => 'e',
+ '/Ĝ|Ğ|Ġ|Ģ/' => 'G',
+ '/ĝ|ğ|ġ|ģ/' => 'g',
+ '/Ĥ|Ħ/' => 'H',
+ '/ĥ|ħ/' => 'h',
+ '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ/' => 'I',
+ '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı/' => 'i',
+ '/Ĵ/' => 'J',
+ '/ĵ/' => 'j',
+ '/Ķ/' => 'K',
+ '/ķ/' => 'k',
+ '/Ĺ|Ļ|Ľ|Ŀ|Ł/' => 'L',
+ '/ĺ|ļ|ľ|ŀ|ł/' => 'l',
+ '/Ñ|Ń|Ņ|Ň/' => 'N',
+ '/ñ|ń|ņ|ň|ʼn/' => 'n',
+ '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ/' => 'O',
+ '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º/' => 'o',
+ '/Ŕ|Ŗ|Ř/' => 'R',
+ '/ŕ|ŗ|ř/' => 'r',
+ '/Ś|Ŝ|Ş|Š/' => 'S',
+ '/ś|ŝ|ş|š|ſ/' => 's',
+ '/Ţ|Ť|Ŧ/' => 'T',
+ '/ţ|ť|ŧ/' => 't',
+ '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ/' => 'U',
+ '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ/' => 'u',
+ '/Ý|Ÿ|Ŷ/' => 'Y',
+ '/ý|ÿ|ŷ/' => 'y',
+ '/Ŵ/' => 'W',
+ '/ŵ/' => 'w',
+ '/Ź|Ż|Ž/' => 'Z',
+ '/ź|ż|ž/' => 'z',
+ '/Æ|Ǽ/' => 'AE',
+ '/ß/'=> 'ss',
+ '/IJ/' => 'IJ',
+ '/ij/' => 'ij',
+ '/Œ/' => 'OE',
+ '/ƒ/' => 'f'
+);
+
+/* End of file foreign_chars.php */
+/* Location: ./application/config/foreign_chars.php */
\ No newline at end of file
diff --git a/OpenVBX/config/mimes.php b/OpenVBX/config/mimes.php
index 438f610c..100f7d44 100644
--- a/OpenVBX/config/mimes.php
+++ b/OpenVBX/config/mimes.php
@@ -10,12 +10,12 @@
$mimes = array( 'hqx' => 'application/mac-binhex40',
'cpt' => 'application/mac-compactpro',
- 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),
+ 'csv' => array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel'),
'bin' => 'application/macbinary',
'dms' => 'application/octet-stream',
'lha' => 'application/octet-stream',
'lzh' => 'application/octet-stream',
- 'exe' => 'application/octet-stream',
+ 'exe' => array('application/octet-stream', 'application/x-msdownload'),
'class' => 'application/octet-stream',
'psd' => 'application/x-photoshop',
'so' => 'application/octet-stream',
@@ -48,7 +48,7 @@
'swf' => 'application/x-shockwave-flash',
'sit' => 'application/x-stuffit',
'tar' => 'application/x-tar',
- 'tgz' => 'application/x-tar',
+ 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
'xhtml' => 'application/xhtml+xml',
'xht' => 'application/xhtml+xml',
'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed'),
@@ -56,7 +56,7 @@
'midi' => 'audio/midi',
'mpga' => 'audio/mpeg',
'mp2' => 'audio/mpeg',
- 'mp3' => array('audio/mpeg', 'audio/mpg'),
+ 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
'aif' => 'audio/x-aiff',
'aiff' => 'audio/x-aiff',
'aifc' => 'audio/x-aiff',
@@ -65,8 +65,8 @@
'rpm' => 'audio/x-pn-realaudio-plugin',
'ra' => 'audio/x-realaudio',
'rv' => 'video/vnd.rn-realvideo',
- 'wav' => 'audio/x-wav',
- 'bmp' => 'image/bmp',
+ 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'),
+ 'bmp' => array('image/bmp', 'image/x-windows-bmp'),
'gif' => 'image/gif',
'jpeg' => array('image/jpeg', 'image/pjpeg'),
'jpg' => array('image/jpeg', 'image/pjpeg'),
@@ -93,13 +93,14 @@
'avi' => 'video/x-msvideo',
'movie' => 'video/x-sgi-movie',
'doc' => 'application/msword',
- 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip'),
+ 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip'),
'word' => array('application/msword', 'application/octet-stream'),
'xl' => 'application/excel',
- 'eml' => 'message/rfc822'
+ 'eml' => 'message/rfc822',
+ 'json' => array('application/json', 'text/json')
);
/* End of file mimes.php */
-/* Location: ./system/application/config/mimes.php */
\ No newline at end of file
+/* Location: ./application/config/mimes.php */
diff --git a/OpenVBX/config/profiler.php b/OpenVBX/config/profiler.php
new file mode 100644
index 00000000..f8a5b1a1
--- /dev/null
+++ b/OpenVBX/config/profiler.php
@@ -0,0 +1,17 @@
+ 'Flock',
+ 'Chrome' => 'Chrome',
'Opera' => 'Opera',
'MSIE' => 'Internet Explorer',
'Internet Explorer' => 'Internet Explorer',
@@ -59,8 +61,8 @@
'Camino' => 'Camino',
'Netscape' => 'Netscape',
'OmniWeb' => 'OmniWeb',
- 'Mozilla' => 'Mozilla',
'Safari' => 'Safari',
+ 'Mozilla' => 'Mozilla',
'Konqueror' => 'Konqueror',
'icab' => 'iCab',
'Lynx' => 'Lynx',
@@ -92,6 +94,7 @@
'nokia' => "Nokia",
'palm' => "Palm",
'iphone' => "Apple iPhone",
+ 'ipad' => "iPad",
'ipod' => "Apple iPod Touch",
'sony' => "Sony Ericsson",
'ericsson' => "Sony Ericsson",
@@ -111,7 +114,7 @@
'benq' => "BenQ",
'ipaq' => "HP iPaq",
'mot-' => "Motorola",
- 'playstation portable' => "PlayStation Portable",
+ 'playstation portable' => "PlayStation Portable",
'hiptop' => "Danger Hiptop",
'nec-' => "NEC",
'panasonic' => "Panasonic",
@@ -124,7 +127,7 @@
// Operating Systems
'symbian' => "Symbian",
- 'SymbianOS' => "SymbianOS",
+ 'SymbianOS' => "SymbianOS",
'elaine' => "Palm",
'palm' => "Palm",
'series60' => "Symbian S60",
@@ -149,7 +152,7 @@
// Fallback
'mobile' => "Generic Mobile",
- 'wireless' => "Generic Mobile",
+ 'wireless' => "Generic Mobile",
'j2me' => "Generic Mobile",
'midp' => "Generic Mobile",
'cldc' => "Generic Mobile",
@@ -172,4 +175,4 @@
);
/* End of file user_agents.php */
-/* Location: ./system/application/config/user_agents.php */
\ No newline at end of file
+/* Location: ./application/config/user_agents.php */
\ No newline at end of file
diff --git a/OpenVBX/core/MY_Config.php b/OpenVBX/core/MY_Config.php
new file mode 100644
index 00000000..d70c01fe
--- /dev/null
+++ b/OpenVBX/core/MY_Config.php
@@ -0,0 +1,117 @@
+router->tenant))
+ {
+ $url = $ci->router->tenant . '/' . $url;
+ }
+
+ return self::url_trim(parent::site_url($url));
+ }
+
+ public function real_site_url($uri)
+ {
+ return self::url_trim(parent::site_url($uri));
+ }
+}
+
+function real_site_url($uri)
+{
+ $CI =& get_instance();
+ return $CI->config->real_site_url($uri);
+}
+
+function asset_url($uri)
+{
+ $CI = &get_instance();
+ $url = $CI->config->real_site_url($uri);
+ $index_page = $CI->config->item('index_page');
+ if(strlen($index_page))
+ {
+ $url = str_replace('/'.$index_page, '', $url);
+ }
+
+ return $url;
+}
+
+function iphone_handler_url($uri)
+{
+ $CI =& get_instance();
+ return 'openvbx://'.$CI->config->item('server_name').'/'.$uri;
+}
+
+function tenant_url($uri, $tenant_id = NULL)
+{
+ $CI = & get_instance();
+ if(!$tenant_id)
+ $tenant_id = $CI->tenant->id;
+ $tenant = $CI->settings->get_tenant_by_id($tenant_id);
+ return $CI->config->real_site_url($tenant->url_prefix . '/' . $uri);
+}
+
+function current_url()
+{
+ $CI =& get_instance();
+ return $CI->config->site_url($CI->uri->uri_string());
+}
+
+function redirect($uri = '', $method = 'location', $http_response_code = 302)
+{
+ if(!headers_sent())
+ {
+ $ci = &get_instance();
+ if(is_object($ci)
+ && isset($ci->session)
+ && is_object($ci->session))
+ $ci->session->persist();
+ }
+ else
+ {
+ error_log('Unable to write session, headers already sent');
+ }
+
+ 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;
+}
+
diff --git a/OpenVBX/libraries/MY_Controller.php b/OpenVBX/core/MY_Controller.php
similarity index 99%
rename from OpenVBX/libraries/MY_Controller.php
rename to OpenVBX/core/MY_Controller.php
index 42c637bf..a591f317 100644
--- a/OpenVBX/libraries/MY_Controller.php
+++ b/OpenVBX/core/MY_Controller.php
@@ -33,7 +33,7 @@
require_once BASEPATH . '../OpenVBX/libraries/AppletInstance.php';
require_once BASEPATH . '../OpenVBX/libraries/Caches/Abstract.php';
-class MY_Controller extends Controller
+class MY_Controller extends CI_Controller
{
protected $user_id;
protected $section;
diff --git a/OpenVBX/libraries/MY_Model.php b/OpenVBX/core/MY_Model.php
similarity index 99%
rename from OpenVBX/libraries/MY_Model.php
rename to OpenVBX/core/MY_Model.php
index d4699991..44904e4a 100644
--- a/OpenVBX/libraries/MY_Model.php
+++ b/OpenVBX/core/MY_Model.php
@@ -36,7 +36,7 @@ public function __toString()
}
}
-class MY_Model extends Model
+class MY_Model extends CI_Model
{
public static $caching = true;
protected static $__CLASS__ = __CLASS__;
diff --git a/OpenVBX/core/MY_Pagination.php b/OpenVBX/core/MY_Pagination.php
new file mode 100644
index 00000000..7dface0a
--- /dev/null
+++ b/OpenVBX/core/MY_Pagination.php
@@ -0,0 +1,164 @@
+total_rows == 0 OR $this->per_page == 0)
+ {
+ return '';
+ }
+
+ // Calculate the total number of pages
+ $num_pages = ceil($this->total_rows / $this->per_page);
+
+ // Is there only one page? Hm... nothing more to do here then.
+ if ($num_pages == 1)
+ {
+ return '';
+ }
+
+ // Determine the current page number.
+ $CI =& get_instance();
+
+ if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE)
+ {
+ if ($CI->input->get($this->query_string_segment) != 0)
+ {
+ $this->cur_page = $CI->input->get($this->query_string_segment);
+
+ // Prep the current page - no funny business!
+ $this->cur_page = (int) $this->cur_page;
+ }
+ }
+ else
+ {
+ if ($CI->uri->segment($this->uri_segment) != 0)
+ {
+ $this->cur_page = $CI->uri->segment($this->uri_segment);
+
+ // Prep the current page - no funny business!
+ $this->cur_page = (int) $this->cur_page;
+ }
+ }
+
+ $this->num_links = (int)$this->num_links;
+
+ if ($this->num_links < 1)
+ {
+ show_error('Your number of links must be a positive number.');
+ }
+
+ if ( ! is_numeric($this->cur_page))
+ {
+ $this->cur_page = 0;
+ }
+
+ // Is the page number beyond the result range?
+ // If so we show the last page
+ if ($this->cur_page > $this->total_rows)
+ {
+ $this->cur_page = ($num_pages - 1) * $this->per_page;
+ }
+
+ $uri_page_number = $this->cur_page;
+ $this->cur_page = floor(($this->cur_page/$this->per_page) + 1);
+
+ // Calculate the start and end numbers. These determine
+ // which number to start and end the digit links with
+ $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
+ $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
+
+ $this->base_url = rtrim($this->base_url).'?';
+
+ // And here we go...
+ $output = '';
+
+ $page_args = array('offset' => '',
+ 'max' => $this->per_page);
+
+
+ // Render the "First" link
+ if ($this->cur_page > ($this->num_links + 1))
+ {
+ $output .= $this->first_tag_open.''.$this->first_link.''.$this->first_tag_close;
+ }
+
+ // Render the "previous" link
+ if ($this->cur_page != 1)
+ {
+ $i = $uri_page_number - $this->per_page;
+ if ($i == 0) $i = '';
+ $page_args['offset'] = $i;
+ $output .= $this->prev_tag_open.''.$this->prev_link.''.$this->prev_tag_close;
+ }
+
+ // Write the digit links
+ for ($loop = $start -1; $loop <= $end; $loop++)
+ {
+ $i = ($loop * $this->per_page) - $this->per_page;
+
+ if ($i >= 0)
+ {
+ if ($this->cur_page == $loop)
+ {
+ $output .= $this->cur_tag_open.$loop.$this->cur_tag_close; // Current page
+ }
+ else
+ {
+ $n = ($i == 0) ? '' : $i;
+ $page_args['offset'] = $n;
+ $output .= $this->num_tag_open.''.$loop.''.$this->num_tag_close;
+ }
+ }
+ }
+
+ // Render the "next" link
+ if ($this->cur_page < $num_pages)
+ {
+ $page_args['offset'] = $this->cur_page * $this->per_page;
+ $output .= $this->next_tag_open.''.$this->next_link.''.$this->next_tag_close;
+ }
+
+ // Render the "Last" link
+ if (($this->cur_page + $this->num_links) < $num_pages)
+ {
+ $i = (($num_pages * $this->per_page) - $this->per_page);
+ $page_args['offset'] = $i;
+ $output .= $this->last_tag_open.''.$this->last_link.''.$this->last_tag_close;
+ }
+
+ // Kill double slashes. Note: Sometimes we can end up with a double slash
+ // in the penultimate link so we'll kill all double slashes.
+ $output = preg_replace("#([^:])//+#", "\\1/", $output);
+
+ // Add the wrapper HTML if exists
+ $output = $this->full_tag_open.$output.$this->full_tag_close;
+
+ return $output;
+ }
+}
\ No newline at end of file
diff --git a/OpenVBX/core/MY_Router.php b/OpenVBX/core/MY_Router.php
new file mode 100644
index 00000000..4a1aa9df
--- /dev/null
+++ b/OpenVBX/core/MY_Router.php
@@ -0,0 +1,339 @@
+routes)))
+ {
+ return false;
+ }
+
+ if($controller &&
+ !in_array($controller, array_keys($this->routes)))
+ {
+ return false;
+ }
+
+ if(is_null($controller)
+ && !empty($tenant))
+ {
+ return $segments;
+ }
+
+
+ return $segments;
+ }
+
+ function _validate_api($segments)
+ {
+ $api_prefix = isset($segments[0])? $segments[0] : null;
+ $api_version = isset($segments[1])? $segments[1] : null;
+
+ if(!$api_prefix)
+ {
+ return false;
+ }
+
+ if($api_prefix != 'api')
+ {
+ return false;
+ }
+
+ switch($api_version)
+ {
+ case '2009-12-01':
+ break;
+ default:
+ return false;
+ }
+ return true;
+ }
+
+ function _validate_tenant_api($segments)
+ {
+ $tenant = isset($segments[0])? $segments[0] : null;
+ $api_prefix = isset($segments[1])? $segments[1] : null;
+ $api_version = isset($segments[2])? $segments[2] : null;
+ $controller = isset($segments[3])? $segments[3] : null;
+
+ if(!$api_prefix)
+ {
+ return false;
+ }
+
+ if($api_prefix != 'api')
+ {
+ return false;
+ }
+
+ switch($api_version)
+ {
+ case '2009-12-01':
+ break;
+ default:
+ return false;
+ }
+
+ if(is_string($tenant)
+ && in_array($tenant, array_keys($this->routes)))
+ {
+ return false;
+ }
+
+ if($controller &&
+ !in_array($controller, array_keys($this->routes)))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ function set_tenant($tenant)
+ {
+ $this->tenant = $tenant;
+ }
+
+ function set_api_version($api_version)
+ {
+ $this->api_version = $api_version;
+ }
+
+ function _get_relative_segments($segments)
+ {
+ if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
+ {
+ return $segments;
+ }
+
+ // Is the controller in a sub-folder?
+ if (is_dir(APPPATH.'controllers/'.$segments[0]))
+ {
+ // Set the directory and remove it from the segment array
+ $this->set_directory($segments[0]);
+
+ $segments = array_slice($segments, 1);
+
+ if (count($segments) > 0 &&
+ file_exists(APPPATH.'controllers/'.$this->directory
+ .'/'.$segments[0].EXT))
+ {
+ return $segments;
+ }
+ else
+ {
+ $this->set_class($this->default_controller);
+ $this->set_method($this->default_method);
+
+ // Does the default controller exist in the sub-folder?
+ if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
+ {
+ $this->directory = '';
+ return array();
+ }
+
+ }
+
+ return $segments;
+ }
+
+ return false;
+ }
+
+ function _validate_request($segments)
+ {
+ // Does the requested controller exist in the root folder?
+ if (!empty($segments[0]) && file_exists(APPPATH.'controllers/'.$segments[0].EXT))
+ {
+ return $segments;
+ }
+
+ // Is the controller in a sub-folder?
+ $segment = (!empty($segments[0])) ? $segments[0] : null;
+ if (is_dir(APPPATH.'controllers/'.$segment))
+ {
+ // Set the directory and remove it from the segment array
+ $this->set_directory($segment);
+ $segments = array_slice($segments, 1);
+
+ if (count($segments) > 0)
+ {
+ // Does the requested controller exist in the sub-folder?
+ if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))
+ {
+ show_404($this->fetch_directory().$segments[0]);
+ }
+ }
+ else
+ {
+ $this->set_class($this->default_controller);
+ $this->set_method('index');
+
+ // Does the default controller exist in the sub-folder?
+ if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
+ {
+ $this->directory = '';
+ return array();
+ }
+
+ }
+
+ return $segments;
+ }
+
+ // Can't find the requested controller...
+ show_404($segment);
+ }
+
+ private function _parse_segments($rel_segments, $segments)
+ {
+ $new_segments = array(
+ $rel_segments[0]
+ );
+
+ if(isset($rel_segments[1])
+ && ($rel_segments[1] > 0
+ || $rel_segments[1] == '0')
+ )
+ {
+ $new_segments[] = $this->default_method;
+ $new_segments[] = $rel_segments[1];
+
+ if(count($rel_segments) > 2)
+ {
+ foreach(array_slice($segments, 3) as $seg)
+ {
+ $new_segments[] = $seg;
+ }
+ }
+ $this->set_method($this->default_method);
+ }
+ else
+ {
+ if(isset($rel_segments[1]))
+ {
+ $new_segments[] = $rel_segments[1];
+ }
+
+ foreach(array_slice($rel_segments, 2) as $seg)
+ {
+ $new_segments[] = $seg;
+ }
+ }
+
+ $rel_segments = $new_segments;
+
+ return $rel_segments;
+ }
+
+ function _parse_routes()
+ {
+ // Do we even have any custom routing to deal with?
+ // There is a default scaffolding trigger, so we'll look just for 1
+ if (count($this->routes) == 1)
+ {
+ $this->_set_request($this->uri->segments);
+ return;
+ }
+
+ $segments = $this->uri->segments;
+ if($this->_validate_api($segments))
+ {
+ $api = $segments[0];
+ $api_version = $segments[1];
+ $segments = array_slice($segments, 2);
+ $this->set_api_version($api_version);
+ $this->uri->segments = $segments;
+ }
+
+ if(($tenant_segments = $this->_validate_tenant($segments)))
+ {
+ $tenant = $segments[0];
+ $segments = array_slice($segments, 1);
+ $this->set_tenant($tenant);
+ if(empty($segments))
+ {
+ $this->set_directory('iframe');
+ $this->uri->segments = array();
+ }
+ else
+ {
+ $this->uri->segments = $segments;
+ }
+ }
+
+ if($this->_validate_tenant_api($segments))
+ {
+ $tenant = $segments[0];
+ $api = $segments[1];
+ $api_version = $segments[2];
+ $this->set_tenant($tenant);
+ $this->set_api_version($api_version);
+
+ $segments = array_slice($segments, 3);
+
+ $this->uri->segments = $segments;
+ }
+
+ // Turn the segment array into a URI string
+ $uri = implode('/', $this->uri->segments);
+
+ // Is there a literal match? If so we're done
+ if (isset($this->routes[$uri]))
+ {
+ $this->_set_request(explode('/', $this->routes[$uri]));
+ return;
+ }
+
+ // Loop through the route array looking for wild-cards
+ foreach ($this->routes as $key => $val)
+ {
+ // Convert wild-cards to RegEx
+ $key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
+
+ // Does the RegEx match?
+ if (preg_match('#^'.$key.'$#', $uri))
+ {
+ // Do we have a back-reference?
+ if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
+ {
+ $val = preg_replace('#^'.$key.'$#', $val, $uri);
+ }
+ $this->_set_request(explode('/', $val));
+ return;
+ }
+ }
+
+ // If we got this far it means we didn't encounter a
+ // matching route so we'll set the site default route
+ $this->_set_request($this->uri->segments);
+ }
+}
\ No newline at end of file
diff --git a/OpenVBX/core/MY_Session.lazy.php b/OpenVBX/core/MY_Session.lazy.php
new file mode 100644
index 00000000..a2d91acf
--- /dev/null
+++ b/OpenVBX/core/MY_Session.lazy.php
@@ -0,0 +1,64 @@
+ $newval);
+ }
+
+ if (count($newdata) > 0)
+ {
+ foreach ($newdata as $key => $val)
+ {
+ $this->userdata[$key] = $val;
+ }
+ }
+
+ }
+
+ function unset_userdata($newdata = array())
+ {
+ if (is_string($newdata))
+ {
+ $newdata = array($newdata => '');
+ }
+
+ if (count($newdata) > 0)
+ {
+ foreach ($newdata as $key => $val)
+ {
+ unset($this->userdata[$key]);
+ }
+ }
+
+ }
+
+ public function persist()
+ {
+ $this->sess_write();
+ }
+}
\ No newline at end of file
diff --git a/OpenVBX/core/MY_Session.php b/OpenVBX/core/MY_Session.php
new file mode 100644
index 00000000..56e871c4
--- /dev/null
+++ b/OpenVBX/core/MY_Session.php
@@ -0,0 +1,26 @@
+id = empty($id) ? 'table_' . uniqid() : $id;
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Add a table row
+ *
+ * The first parameter will be the {ID} value that is replaced on each row template.
+ * Data can be passed as an array or discreet params
+ *
+ * @access public
+ * @param mixed
+ * @return void
+ */
+ function add_id_row($id, $data)
+ {
+ $args = func_get_args();
+ array_shift($args);
+ $this->rows[] = (is_array($data)) ? $data : $args;
+
+ $index = count($this->rows) - 1;
+ $this->row_ids[$index] = $id;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generate the table
+ *
+ * @access public
+ * @param mixed
+ * @return string
+ */
+ function generate($table_data = NULL)
+ {
+ // The table data can optionally be passed to this function
+ // either as a database result object or an array
+ if ( ! is_null($table_data))
+ {
+ if (is_object($table_data))
+ {
+ $this->_set_from_object($table_data);
+ }
+ elseif (is_array($table_data))
+ {
+ $set_heading = (count($this->heading) == 0 AND $this->auto_heading == FALSE) ? FALSE : TRUE;
+ $this->_set_from_array($table_data, $set_heading);
+ }
+ }
+
+ // Is there anything to display? No? Smite them!
+ if (count($this->heading) == 0 AND count($this->rows) == 0)
+ {
+ return 'Undefined table data';
+ }
+
+ // Compile and validate the template date
+ $this->_compile_template();
+
+
+ // Build the table!
+
+ $out = str_replace('{ID}', $this->id, $this->template['table_open']);
+ $out .= $this->newline;
+
+ // Add any caption here
+ if ($this->caption)
+ {
+ $out .= $this->newline;
+ $out .= '
' . $this->caption . '';
+ $out .= $this->newline;
+ }
+
+ // Is there a table heading to display?
+ if (count($this->heading) > 0)
+ {
+ $out .= $this->template['heading_row_start'];
+ $out .= $this->newline;
+
+ for($col = 0; $col < count($this->heading); $col++)
+ {
+ $out .= str_replace('{COL}', $col, $this->template['heading_cell_start']);
+ $out .= $this->heading[$col];
+ $out .= $this->template['heading_cell_end'];
+ }
+
+ $out .= $this->template['heading_row_end'];
+ $out .= $this->newline;
+ }
+
+ // Build the table rows
+ if (count($this->rows) > 0)
+ {
+ $i = 1;
+ $row_find = array('{ROW}', '{ID}');
+ for($r = 0; $r < count($this->rows); $r++)
+ {
+ $row = $this->rows[$r];
+ if ( ! is_array($row)) break;
+ $row_id = isset($this->row_ids[$r]) ? $this->row_ids[$r] : '';
+
+ // We use modulus to alternate the row colors
+ $name = (fmod($i++, 2)) ? '' : 'alt_';
+
+ $out .= str_replace($row_find, array($r, $row_id), $this->template['row_'.$name.'start']);
+ $out .= $this->newline;
+
+ for($col = 0; $col < count($row); $col++)
+ {
+ $out .= str_replace('{COL}', $col, $this->template['cell_'.$name.'start']);
+
+ $cell = $row[$col];
+ if ($cell === "")
+ {
+ $out .= $this->empty_cells;
+ }
+ else
+ {
+ $out .= $cell;
+ }
+
+ $out .= $this->template['cell_'.$name.'end'];
+ }
+
+ $out .= $this->template['row_'.$name.'end'];
+ $out .= $this->newline;
+ }
+ }
+
+ $out .= $this->template['table_close'];
+
+ return $out;
+ }
+
+ function clear()
+ {
+ parent::clear();
+ $this->row_ids = array();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Default Template
+ *
+ * @access private
+ * @return void
+ */
+ function _default_template()
+ {
+ return array (
+ 'table_open' => '',
+
+ 'heading_row_start' => '',
+ 'heading_row_end' => '
',
+ 'heading_cell_start' => '',
+ 'heading_cell_end' => ' | ',
+
+ 'row_start' => '',
+ 'row_end' => '
',
+ 'cell_start' => '',
+ 'cell_end' => ' | ',
+
+ 'row_alt_start' => '',
+ 'row_alt_end' => '
',
+ 'cell_alt_start' => '',
+ 'cell_alt_end' => ' | ',
+
+ 'table_close' => '
'
+ );
+ }
+
+}
diff --git a/OpenVBX/core/MY_URI.php b/OpenVBX/core/MY_URI.php
new file mode 100644
index 00000000..d8988c11
--- /dev/null
+++ b/OpenVBX/core/MY_URI.php
@@ -0,0 +1,48 @@
+tenant && $ci->tenant->id > 1)
+ {
+ $uri = preg_replace('/^\/'.$ci->tenant->url_prefix.'/i', '', $uri);
+ }
+ return $uri;
+ }
+
+ function _explode_segments()
+ {
+ foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
+ {
+ // Filter segments for security
+ $val = trim($this->_filter_uri($val));
+ $val = preg_replace('/\?.*$/','', $val);
+ if ($val != '')
+ {
+ $this->segments[] = $val;
+ }
+ }
+ }
+}
diff --git a/OpenVBX/core/User_Controller.php b/OpenVBX/core/User_Controller.php
new file mode 100644
index 00000000..d09cbe69
--- /dev/null
+++ b/OpenVBX/core/User_Controller.php
@@ -0,0 +1,394 @@
+config_check();
+
+ $this->config->load('openvbx');
+
+ // check for required configuration values
+ $this->load->database();
+ $this->load->library('ErrorMessages'); // deprecated in 1.2
+ $this->load->model('vbx_rest_access');
+ $this->load->model('vbx_message');
+
+ // When we're in testing mode, allow access to set Hiccup configuration
+ $this->testing_mode = !empty($_REQUEST['vbx_testing_key'])? $_REQUEST['vbx_testing_key'] == $this->config->item('testing-key') : false;
+ $this->config->set_item('sess_cookie_name', $this->tenant->id . '-' . $this->config->item('sess_cookie_name'));
+ $this->load->library('session');
+
+ $keys = array('base_url', 'salt');
+ foreach($keys as $key)
+ {
+ $item[$key] = $this->config->item($key);
+ if(empty($item[$key]))
+ {
+ redirect('install');
+ }
+ }
+
+ /* Rest API Authentication - one time pass only */
+ $singlepass = $this->input->cookie('singlepass');
+ if(!empty($singlepass))
+ {
+ $ra = new VBX_Rest_Access();
+ $user_id = $ra->auth_key($singlepass);
+ unset($_COOKIE['singlepass']);
+ if($user_id)
+ {
+ $this->session->set_userdata('user_id', $user_id);
+ $this->session->set_userdata('loggedin', true);
+ $this->session->set_userdata('signature', VBX_User::signature($user_id));
+ }
+ }
+
+ $user_id = $this->session->userdata('user_id');
+
+ // Signature check
+ if (!empty($user_id))
+ {
+ $signature = $this->session->userdata('signature');
+ if (!VBX_User::check_signature($user_id, $signature))
+ {
+ $this->session->set_flashdata('error', 'Your session has expired');
+ $this->session->set_userdata('loggedin', false);
+ }
+ }
+
+ if($this->response_type == 'json')
+ {
+ $this->attempt_digest_auth();
+ }
+
+ if (!$this->session->userdata('loggedin') && $this->response_type != 'json')
+ {
+ $redirect = site_url($this->uri->uri_string());
+ if (!empty($_COOKIE['last_known_url']))
+ {
+ $redirect = $_COOKIE['last_known_url'];
+ set_last_known_url('', time() - 3600);
+ }
+ return redirect('auth/login?redirect='.urlencode($redirect));
+ }
+
+ $this->user_id = $this->session->userdata('user_id');
+ $this->set_request_method();
+
+ /* Mark the user as seen */
+ if (!empty($this->user_id))
+ {
+ try
+ {
+ $user = VBX_User::get($this->user_id);
+ $user->setting_set('last_seen', new MY_ModelLiteral('UTC_TIMESTAMP()'));
+ }
+ catch(VBX_UserException $e)
+ {
+ /* Handle this gracefully, but report the error. */
+ error_log($e->getMessage());
+ }
+
+ $this->connect_check();
+
+ /* Check for first run */
+ if ($this->session->userdata('is_admin') && $this->uri->segment(1) != 'welcome')
+ {
+ $this->welcome_check();
+ }
+
+ /* Check for updates if an admin */
+ if($this->session->userdata('is_admin') && $this->uri->segment(1) != "upgrade")
+ {
+ $this->upgrade_check();
+ }
+
+ }
+ }
+
+ protected function redirect($url)
+ {
+ redirect($url);
+ }
+
+ private function config_check()
+ {
+ $vbx_config = APPPATH.'config/openvbx.php';
+ $db_config = APPPATH.'config/database.php';
+ if(!file_exists($vbx_config) || !file_exists($db_config))
+ {
+ redirect('install');
+ }
+ }
+
+ private function upgrade_check()
+ {
+ $currentSchemaVersion = OpenVBX::schemaVersion(false);
+ $upgradingToSchemaVersion = OpenVBX::getLatestSchemaVersion();
+ if($currentSchemaVersion != $upgradingToSchemaVersion)
+ {
+ redirect('upgrade');
+ }
+ }
+
+ private function welcome_check()
+ {
+ if ($this->router->class == 'iframe' || $this->router->class == 'welcome')
+ {
+ return false;
+ }
+
+ if ($this->settings->get('tenant_first_run', $this->tenant->id))
+ {
+ redirect('welcome');
+ }
+ }
+
+ private function connect_check() {
+ $section = $this->uri->segment(1);
+ if (!in_array($section, array('welcome', 'auth', 'connect')))
+ {
+ if ($this->twilio_sid == 'unauthorized_client')
+ {
+ $redirect_path = 'welcome';
+ }
+
+ if ($this->twilio_sid == 'deauthorized_client') {
+ if ($this->session->userdata('is_admin')) {
+ $redirect_path = 'welcome';
+ }
+ else {
+ $redirect_path = 'auth/connect/account_deauthorized';
+ }
+ }
+
+ if (!empty($redirect_path)) {
+ redirect($redirect_path);
+ }
+ }
+ }
+
+ function digest_parse($digest)
+ {
+ // protect against missing data
+ $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
+ $data = array();
+
+ preg_match_all('@(\w+)=(?:(?:\'([^\']+)\'|"([^"]+)")|([^\s,]+))@', $digest, $matches, PREG_SET_ORDER);
+
+ foreach ($matches as $m) {
+ $data[$m[1]] = $m[2] ? $m[2] : ($m[3] ? $m[3] : $m[4]);
+ unset($needed_parts[$m[1]]);
+ }
+
+ return $needed_parts ? false : $data;
+ }
+
+
+ function attempt_digest_auth()
+ {
+ $message = '';
+
+ if(isset($_SERVER['Authorization'])) {
+ // Just in case they ever fix Apache to send the Authorization header on, the following code is included
+ $headers['Authorization'] = $_SERVER['Authorization'];
+ }
+
+ if(function_exists('apache_request_headers')) {
+ // We are running PHP as an Apache module, so we can get the Authorization header this way
+ $headers = apache_request_headers();
+ }
+
+ // Support cgi based auth via rewrite hack:
+ // ---------------------
+ // RewriteEngine on
+ // RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
+ // $_SERVER['PHP_AUTH_USER'] = '';
+ // $_SERVER['PHP_AUTH_PW'] = '';
+ if(isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
+ $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
+ }
+
+ if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
+ if(preg_match('/Basic (.*)$/', $_SERVER['HTTP_AUTHORIZATION'], $matches))
+ list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) =
+ explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
+
+ }
+
+ // Support standard PHP Authorization magic with apache
+ if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
+ // Basic authentication information can be retrieved from these server variables
+ $username = $_SERVER['PHP_AUTH_USER'];
+ $password = $_SERVER['PHP_AUTH_PW'];
+ }
+
+ if(isset($headers['Authorization'])) {
+ $_SERVER['PHP_AUTH_DIGEST'] = $headers['Authorization'];
+ $data = $this->digest_parse($_SERVER['PHP_AUTH_DIGEST']);
+ }
+
+ $captcha = '';
+ if(isset($headers['Captcha']))
+ {
+ $captcha = $headers['Captcha'];
+ }
+
+ $captcha_token = '';
+ if(isset($headers['CaptchaToken']))
+ {
+ $captcha_token = $headers['CaptchaToken'];
+ }
+
+ if (isset($username) && isset($password))
+ {
+ log_message('info', 'Logging in user: '.var_export($username, true));
+
+ $u = VBX_User::login($username, $password, $captcha, $captcha_token);
+ if($u)
+ {
+ $next = $this->session->userdata('next');
+ $this->session->unset_userdata('next');
+ $userdata = array(
+ 'email' => $u->email,
+ 'user_id' => $u->id,
+ 'is_admin' => $u->is_admin,
+ 'loggedin' => TRUE,
+ 'signature' => VBX_User::signature($u->id),
+ );
+
+ $this->session->set_userdata($userdata);
+ }
+ }
+
+ if(!$this->session->userdata('loggedin'))
+ {
+ header("WWW-Authenticate: Basic realm=\"OpenVBX\"");
+ header("HTTP/1.0 401 Unauthorized");
+ exit;
+ }
+
+ return $message;
+ }
+
+ // make sure this page or function can only be accessed by admins
+ function admin_only($page_name = 'this page')
+ {
+ if (!$this->session->userdata('is_admin')) {
+ $this->session->set_userdata('next', uri_string());
+ $this->session->set_flashdata('error', "You must be an administrator to access $page_name.");
+ redirect('auth/login');
+ }
+ }
+
+ protected function init_view_data($full_view = true)
+ {
+ $data = array();
+
+ if($full_view)
+ {
+ $data['counts'] = $counts = $this->message_counts();
+ }
+
+ try
+ {
+ $data['callerid_numbers'] = $this->get_twilio_numbers();
+ }
+ catch(User_ControllerException $e)
+ {
+ // @todo - set a "same page view" error message
+ // $this->session->set_flashdata('error', $e->getMessage());
+ error_log($e->getMessage());
+ }
+
+ $data['user_numbers'] = $this->get_user_numbers();
+ $data['error'] = $this->session->flashdata('error');
+ if(!empty($data['error']))
+ {
+ log_message('error', $data['error']);
+ }
+ $data['section'] = $this->section;
+
+ return $data;
+ }
+
+ protected function get_user_numbers()
+ {
+ $this->load->model('vbx_device');
+ $numbers = $this->vbx_device->get_by_user($this->user_id);
+
+ return $numbers;
+ }
+
+ protected function message_counts()
+ {
+ $groups = VBX_User::get_group_ids($this->user_id);
+ $counts = $this->vbx_message->get_folders($this->user_id, $groups);
+ return $counts;
+ }
+
+ protected function get_twilio_numbers()
+ {
+ $this->load->model('vbx_incoming_numbers');
+ $numbers = array();
+ try
+ {
+ /* Retrieve twilio numbers w/o sandbox */
+ $numbers = $this->vbx_incoming_numbers->get_numbers();
+ }
+ catch(VBX_IncomingNumberException $e)
+ {
+ error_log($e->getMessage());
+ throw new User_ControllerException($e->getMessage());
+ /* Silent fail */
+ }
+
+ return $numbers;
+ }
+
+ /* Used to give access to internals via rest-based calls */
+ protected function make_rest_access()
+ {
+ /* Set a cookie for Rest Access */
+ $this->load->model('vbx_rest_access');
+ return $this->vbx_rest_access->make_key($this->session->userdata('user_id'));
+ }
+
+ public function get_tenant()
+ {
+ return $this->tenant;
+ }
+}
diff --git a/OpenVBX/helpers/mail_helper.php b/OpenVBX/helpers/mail_helper.php
index 9453556f..c25c6e98 100644
--- a/OpenVBX/helpers/mail_helper.php
+++ b/OpenVBX/helpers/mail_helper.php
@@ -18,25 +18,30 @@
* Contributor(s):
**/
-
+
function openvbx_mail($recipient, $subject, $template, $maildata = array())
-{
+{
$ci = &get_instance();
-
+
$from_email = $ci->settings->get('from_email', $ci->tenant->id);
if(empty($from_email))
{
$domain = $ci->config->item('server_name');
- $from_email = "$from ";
+ $from_email = "do-not-reply@$domain";
}
-
- $headers = 'From: '.$from_email."\r\n";
- $headers .= 'Reply-To: '.$from_email."\r\n";
- $headers .= 'Return-Path: '.$from_email."\r\n";
- $headers .= 'User-Agent: OpenVBX-'.OpenVBX::version();
-
+
$message = $ci->load->view('emails/'.$template, $maildata, true);
-
+
+ $ci->load->library('email');
+ $ci->email->useragent = 'OpenVBX-' . OpenVBX::version();
+ $ci->email->clear()
+ ->from($from_email)
+ ->reply_to($from_email)
+ ->to($recipient)
+ ->subject($subject)
+ ->message($message);
+
log_message('debug', 'MAILING -- to: '.$recipient.' -- body: '.$message);
- return mail($recipient, '[OpenVBX] '.$subject, $message, $headers);
-}
\ No newline at end of file
+
+ return $ci->email->send();
+}
diff --git a/OpenVBX/libraries/OpenVBX.php b/OpenVBX/libraries/OpenVBX.php
index f0409943..71719d20 100644
--- a/OpenVBX/libraries/OpenVBX.php
+++ b/OpenVBX/libraries/OpenVBX.php
@@ -223,18 +223,15 @@ public static function schemaVersion()
$ci =& get_instance();
if ($ci->db)
{
- $reenable_cache = false;
-
$ci->load->model('vbx_settings');
- if (isset($ci->cache) && $ci->cache->enabled())
+ $reenable_cache = false;
+ if (!$ci->cache && $ci->cache->enabled())
{
$ci->cache->enabled(false);
$reenable_cache = true;
}
-
self::$schemaVersion = $ci->vbx_settings->get('schema-version', VBX_PARENT_TENANT);
-
- if ($reenable_cache)
+ if ($reenable_cache)
{
$ci->cache->enabled(true);
}
@@ -379,7 +376,7 @@ protected static function get_http_opts()
// optionally load in the included cert for api communication
if ($use_certificate = $ci->config->item('twilio_use_certificate')) {
- $_http_opts['opts']['curlopts'][CURLOPT_CAINFO] = APPPATH . 'libraries/Services/twilio_ssl_certificate.crt';
+ $_http_opts['opts']['curlopts'][CURLOPT_CAINFO] = APPPATH . 'libraries/Services/cacert.pem';
}
// internal api development override, you'll never need this
@@ -474,7 +471,7 @@ public static function validateRequest($url = false, $post_vars = false)
// we weren't handed post-vars, use the default
$post_vars = $_POST;
}
-
+
return self::$_twilioValidator->validate(self::getRequestSignature(), $url, $post_vars);
}
diff --git a/OpenVBX/libraries/Services/Twilio.php b/OpenVBX/libraries/Services/Twilio.php
index 5aa957fc..26e68bc9 100755
--- a/OpenVBX/libraries/Services/Twilio.php
+++ b/OpenVBX/libraries/Services/Twilio.php
@@ -1,5 +1,11 @@
`_
+ * :param string $version: API version to use
+ * :param $_http: A HTTP client for making requests.
+ * :type $_http: :php:class:`Services_Twilio_TinyHttp`
+ * :param int $retryAttempts:
+ * Number of times to retry failed requests. Currently only idempotent
+ * requests (GET's and DELETE's) are retried.
+ *
+ * Here's an example:
*
- * @category Services
- * @package Services_Twilio
- * @author Neuman Vong
- * @license http://creativecommons.org/licenses/MIT/ MIT
- * @link http://pear.php.net/package/Services_Twilio
+ * .. code-block:: php
+ *
+ * require('Services/Twilio.php');
+ * $client = new Services_Twilio('AC123', '456bef', null, null, 3);
+ * // Take some action with the client, etc.
*/
class Services_Twilio extends Services_Twilio_Resource
{
- const USER_AGENT = 'twilio-php/3.9.0';
+ const USER_AGENT = 'twilio-php/3.12.1';
protected $http;
protected $retryAttempts;
+ protected $last_response;
protected $version;
protected $versions = array('2008-08-01', '2010-04-01');
- /**
- * Constructor.
- *
- * @param string $sid Account SID
- * @param string $token Account auth token
- * @param string $version API version
- * @param Services_Twilio_Http $_http A HTTP client
- * @param int $retryAttempts Number of times to retry failed requests
- */
public function __construct(
$sid,
$token,
@@ -49,22 +60,36 @@ public function __construct(
$version : end($this->versions);
if (null === $_http) {
- if (!in_array('curl', get_loaded_extensions())) {
- trigger_error("It looks like you do not have curl installed.\n".
- "Curl is required to make HTTP requests using the twilio-php\n" .
- "library. For install instructions, visit the following page:\n" .
- "http://php.net/manual/en/curl.installation.php",
- E_USER_WARNING
+ if (!in_array('openssl', get_loaded_extensions())) {
+ throw new Services_Twilio_HttpException("The OpenSSL extension is required but not currently enabled. For more information, see http://php.net/manual/en/book.openssl.php");
+ }
+ if (in_array('curl', get_loaded_extensions())) {
+ $_http = new Services_Twilio_TinyHttp(
+ "https://api.twilio.com",
+ array("curlopts" => array(
+ CURLOPT_USERAGENT => self::USER_AGENT,
+ CURLOPT_HTTPHEADER => array('Accept-Charset: utf-8'),
+ CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem',
+ ))
+ );
+ } else {
+ $_http = new Services_Twilio_HttpStream(
+ "https://api.twilio.com",
+ array(
+ "http_options" => array(
+ "http" => array(
+ "user_agent" => self::USER_AGENT,
+ "header" => "Accept-Charset: utf-8\r\n",
+ ),
+ "ssl" => array(
+ 'verify_peer' => true,
+ 'cafile' => dirname(__FILE__) . '/cacert.pem',
+ 'verify_depth' => 5,
+ ),
+ ),
+ )
);
}
- $_http = new Services_Twilio_TinyHttp(
- "https://api.twilio.com",
- array("curlopts" => array(
- CURLOPT_USERAGENT => self::USER_AGENT,
- CURLOPT_HTTPHEADER => array('Accept-Charset: utf-8'),
- CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem',
- ))
- );
}
$_http->authenticate($sid, $token);
$this->http = $_http;
@@ -76,7 +101,8 @@ public function __construct(
/**
* Get the api version used by the rest client
*
- * @return string the API version in use
+ * :return: the API version in use
+ * :returntype: string
*/
public function getVersion() {
return $this->version;
@@ -85,25 +111,27 @@ public function getVersion() {
/**
* Get the retry attempt limit used by the rest client
*
- * @return int the number of retry attempts
+ * :return: the number of retry attempts
+ * :rtype: int
*/
public function getRetryAttempts() {
return $this->retryAttempts;
}
/**
- * Construct a URI based on initial path, query params, and paging
+ * Construct a URI based on initial path, query params, and paging
* information
*
- * We want to use the query params, unless we have a next_page_uri from the
+ * We want to use the query params, unless we have a next_page_uri from the
* API.
*
- * @param string $path The request path (may contain query params if it's
+ * :param string $path: The request path (may contain query params if it's
* a next_page_uri)
- * @param array $params Query parameters to use with the request
- * @param boolean $full_uri Whether the $path contains the full uri
+ * :param array $params: Query parameters to use with the request
+ * :param boolean $full_uri: Whether the $path contains the full uri
*
- * @return string the URI that should be requested by the library
+ * :return: the URI that should be requested by the library
+ * :returntype: string
*/
public static function getRequestUri($path, $params, $full_uri = false) {
$json_path = $full_uri ? $path : "$path.json";
@@ -118,11 +146,12 @@ public static function getRequestUri($path, $params, $full_uri = false) {
/**
* Helper method for implementing request retry logic
*
- * @param array $callable The function that makes an HTTP request
- * @param string $uri The URI to request
- * @param int $retriesLeft Number of times to retry
+ * :param array $callable: The function that makes an HTTP request
+ * :param string $uri: The URI to request
+ * :param int $retriesLeft: Number of times to retry
*
- * @return object The object representation of the resource
+ * :return: The object representation of the resource
+ * :rtype: object
*/
protected function _makeIdempotentRequest($callable, $uri, $retriesLeft) {
$response = call_user_func_array($callable, array($uri));
@@ -137,61 +166,111 @@ protected function _makeIdempotentRequest($callable, $uri, $retriesLeft) {
/**
* GET the resource at the specified path.
*
- * @param string $path Path to the resource
- * @param array $params Query string parameters
- * @param boolean $full_uri Whether the full URI has been passed as an
+ * :param string $path: Path to the resource
+ * :param array $params: Query string parameters
+ * :param boolean $full_uri: Whether the full URI has been passed as an
* argument
*
- * @return object The object representation of the resource
+ * :return: The object representation of the resource
+ * :rtype: object
*/
- public function retrieveData($path, array $params = array(),
+ public function retrieveData($path, $params = array(),
$full_uri = false
) {
$uri = self::getRequestUri($path, $params, $full_uri);
- return $this->_makeIdempotentRequest(array($this->http, 'get'),
+ return $this->_makeIdempotentRequest(array($this->http, 'get'),
$uri, $this->retryAttempts);
}
/**
* DELETE the resource at the specified path.
*
- * @param string $path Path to the resource
- * @param array $params Query string parameters
+ * :param string $path: Path to the resource
+ * :param array $params: Query string parameters
*
- * @return object The object representation of the resource
+ * :return: The object representation of the resource
+ * :rtype: object
*/
- public function deleteData($path, array $params = array())
+ public function deleteData($path, $params = array())
{
$uri = self::getRequestUri($path, $params);
- return $this->_makeIdempotentRequest(array($this->http, 'delete'),
+ return $this->_makeIdempotentRequest(array($this->http, 'delete'),
$uri, $this->retryAttempts);
}
/**
* POST to the resource at the specified path.
*
- * @param string $path Path to the resource
- * @param array $params Query string parameters
+ * :param string $path: Path to the resource
+ * :param array $params: Query string parameters
*
- * @return object The object representation of the resource
+ * :return: The object representation of the resource
+ * :rtype: object
*/
- public function createData($path, array $params = array())
+ public function createData($path, $params = array())
{
$path = "$path.json";
$headers = array('Content-Type' => 'application/x-www-form-urlencoded');
$response = $this->http->post(
- $path, $headers, http_build_query($params, '', '&')
+ $path, $headers, self::buildQuery($params, '')
);
return $this->_processResponse($response);
}
+ /**
+ * Build a query string from query data
+ *
+ * :param array $queryData: An associative array of keys and values. The
+ * values can be a simple type or a list, in which case the list is
+ * converted to multiple query parameters with the same key.
+ * :param string $numericPrefix:
+ * :param string $queryStringStyle: Determine how to build the url
+ * - strict: Build a standards compliant query string without braces (can be hacked by using braces in key)
+ * - php: Build a PHP compatible query string with nested array syntax
+ * :return: The encoded query string
+ * :rtype: string
+ */
+ public static function buildQuery($queryData, $numericPrefix = '') {
+ $query = '';
+ // Loop through all of the $query_data
+ foreach ($queryData as $key => $value) {
+ // If the key is an int, add the numeric_prefix to the beginning
+ if (is_int($key)) {
+ $key = $numericPrefix . $key;
+ }
+
+ // If the value is an array, we will end up recursing
+ if (is_array($value)) {
+ // Loop through the values
+ foreach ($value as $value2) {
+ // Add an arg_separator if needed
+ if ($query !== '') {
+ $query .= '&';
+ }
+ // Recurse
+ $query .= self::buildQuery(array($key => $value2), $numericPrefix);
+ }
+ } else {
+ // Add an arg_separator if needed
+ if ($query !== '') {
+ $query .= '&';
+ }
+ // Add the key and the urlencoded value (as a string)
+ $query .= $key . '=' . urlencode((string)$value);
+ }
+ }
+ return $query;
+ }
+
/**
* Convert the JSON encoded resource into a PHP object.
*
- * @param array $response 3-tuple containing status, headers, and body
+ * :param array $response: 3-tuple containing status, headers, and body
*
- * @return object PHP object decoded from JSON
- * @throws Services_Twilio_RestException (Response in 300-500 class)
+ * :return: PHP object decoded from JSON
+ * :rtype: object
+ * :throws: A :php:class:`Services_Twilio_RestException` if the Response is
+ * in the 300-500 range of status codes.
*/
private function _processResponse($response)
{
@@ -203,18 +282,20 @@ private function _processResponse($response)
if ($decoded === null) {
throw new Services_Twilio_RestException(
$status,
- 'Could not decode response body as JSON. ' .
+ 'Could not decode response body as JSON. ' .
'This likely indicates a 500 server error'
);
}
if (200 <= $status && $status < 300) {
+ $this->last_response = $decoded;
return $decoded;
}
throw new Services_Twilio_RestException(
- (int)$decoded->status,
- $decoded->message,
+ $status,
+ isset($decoded->message) ? $decoded->message : '',
isset($decoded->code) ? $decoded->code : null,
isset($decoded->more_info) ? $decoded->more_info : null
);
}
}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Capability.php b/OpenVBX/libraries/Services/Twilio/Capability.php
index 554e2a32..9f02e452 100755
--- a/OpenVBX/libraries/Services/Twilio/Capability.php
+++ b/OpenVBX/libraries/Services/Twilio/Capability.php
@@ -68,7 +68,7 @@ public function allowClientOutgoing($appSid, array $appParams=array())
{
$this->allow('client', 'outgoing', array(
'appSid' => $appSid,
- 'appParams' => http_build_query($appParams)));
+ 'appParams' => http_build_query($appParams, '', '&')));
}
/**
@@ -80,7 +80,7 @@ public function allowEventStream(array $filters=array())
{
$this->allow('stream', 'subscribe', array(
'path' => '/2010-04-01/Events',
- 'params' => http_build_query($filters),
+ 'params' => http_build_query($filters, '', '&'),
));
}
@@ -146,7 +146,7 @@ public function toString()
{
$uri = "scope:{$this->service}:{$this->privilege}";
if (count($this->params)) {
- $uri .= "?".http_build_query($this->params);
+ $uri .= "?".http_build_query($this->params, '', '&');
}
return $uri;
}
@@ -343,4 +343,4 @@ private static function handleJsonError($errno)
: 'Unknown JSON error: ' . $errno
);
}
-}
\ No newline at end of file
+}
diff --git a/OpenVBX/libraries/Services/Twilio/HttpException.php b/OpenVBX/libraries/Services/Twilio/HttpException.php
new file mode 100644
index 00000000..b79a357d
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/HttpException.php
@@ -0,0 +1,3 @@
+ array(
+ "headers" => "",
+ "timeout" => 60,
+ "follow_location" => true,
+ "ignore_errors" => true,
+ ),
+ "ssl" => array(),
+ );
+ private $options = array();
+
+ public function __construct($uri = '', $kwargs = array()) {
+ $this->uri = $uri;
+ if (isset($kwargs['debug'])) {
+ $this->debug = true;
+ }
+ if (isset($kwargs['http_options'])) {
+ $this->options = $kwargs['http_options'] + self::$default_options;
+ } else {
+ $this->options = self::$default_options;
+ }
+ }
+
+ public function __call($name, $args) {
+ list($res, $req_headers, $req_body) = $args + array(0, array(), '');
+
+ $request_options = $this->options;
+ $url = $this->uri . $res;
+
+ if (isset($req_body) && strlen($req_body) > 0) {
+ $request_options['http']['content'] = $req_body;
+ }
+
+ foreach($req_headers as $key => $value) {
+ $request_options['http']['header'] .= sprintf("%s: %s\r\n", $key, $value);
+ }
+
+ if (isset($this->auth_header)) {
+ $request_options['http']['header'] .= $this->auth_header;
+ }
+
+ $request_options['http']['method'] = strtoupper($name);
+ $request_options['http']['ignore_errors'] = true;
+
+ if ($this->debug) {
+ error_log(var_export($request_options, true));
+ }
+ $ctx = stream_context_create($request_options);
+ $result = file_get_contents($url, false, $ctx);
+
+ if (false === $result) {
+ throw new Services_Twilio_HttpStreamException(
+ "Unable to connect to service");
+ }
+
+ $status_header = array_shift($http_response_header);
+ if (1 !== preg_match('#HTTP/\d+\.\d+ (\d+)#', $status_header, $matches)) {
+ throw new Services_Twilio_HttpStreamException(
+ "Unable to detect the status code in the HTTP result.");
+ }
+
+ $status_code = intval($matches[1]);
+ $response_headers = array();
+
+ foreach($http_response_header as $header) {
+ list($key, $val) = explode(":", $header);
+ $response_headers[trim($key)] = trim($val);
+ }
+
+ return array($status_code, $response_headers, $result);
+ }
+
+ public function authenticate($user, $pass) {
+ if (isset($user) && isset($pass)) {
+ $this->auth_header = sprintf("Authorization: Basic %s",
+ base64_encode(sprintf("%s:%s", $user, $pass)));
+ } else {
+ $this->auth_header = null;
+ }
+ }
+}
diff --git a/OpenVBX/libraries/Services/Twilio/InstanceResource.php b/OpenVBX/libraries/Services/Twilio/InstanceResource.php
index 6c1e9a1a..011d8f99 100755
--- a/OpenVBX/libraries/Services/Twilio/InstanceResource.php
+++ b/OpenVBX/libraries/Services/Twilio/InstanceResource.php
@@ -1,22 +1,27 @@
* @license http://creativecommons.org/licenses/MIT/ MIT
* @link http://pear.php.net/package/Services_Twilio
- */
-abstract class Services_Twilio_InstanceResource
- extends Services_Twilio_Resource
-{
+ */
+
+/**
+ * Abstraction of an instance resource from the Twilio API.
+ */
+abstract class Services_Twilio_InstanceResource extends Services_Twilio_Resource {
+
/**
- * @param mixed $params An array of updates, or a property name
- * @param mixed $value A value with which to update the resource
+ * Make a request to the API to update an instance resource
*
- * @return null
+ * :param mixed $params: An array of updates, or a property name
+ * :param mixed $value: A value with which to update the resource
+ *
+ * :rtype: null
+ * :throws: a :php:class:`RestException ` if
+ * the update fails.
*/
public function update($params, $value = null)
{
@@ -27,13 +32,14 @@ public function update($params, $value = null)
$this->updateAttributes($decamelizedParams);
}
- /*
- * Add all properties from an associative array (the JSON response body) as
+ /*
+ * Add all properties from an associative array (the JSON response body) as
* properties on this instance resource, except the URI
*
- * @param stdClass $params An object containing all of the parameters of
+ * :param stdClass $params: An object containing all of the parameters of
* this instance
- * @return null Purely side effecting
+ * :return: Nothing, this is purely side effecting
+ * :rtype: null
*/
public function updateAttributes($params) {
unset($params->uri);
@@ -44,15 +50,25 @@ public function updateAttributes($params) {
/**
* Get the value of a property on this resource.
- *
- * To help with lazy HTTP requests, we don't actually retrieve an object
- * from the API unless you really need it. Hence, this function may make
- * API requests if the property you're requesting isn't available on the
+ *
+ * Instead of defining all of the properties of an object directly, we rely
+ * on the API to tell us which properties an object has. This method will
+ * query the API to retrieve a property for an object, if it is not already
+ * set on the object.
+ *
+ * If the call is to a subresource, eg ``$client->account->messages``, no
+ * request is made.
+ *
+ * To help with lazy HTTP requests, we don't actually retrieve an object
+ * from the API unless you really need it. Hence, this function may make API
+ * requests even if the property you're requesting isn't available on the
* resource.
*
- * @param string $key The property name
+ * :param string $key: The property name
*
- * @return mixed Could be anything.
+ * :return mixed: Could be anything.
+ * :throws: a :php:class:`RestException ` if
+ * the update fails.
*/
public function __get($key)
{
diff --git a/OpenVBX/libraries/Services/Twilio/ListResource.php b/OpenVBX/libraries/Services/Twilio/ListResource.php
index e628b42d..4d7bc3c3 100755
--- a/OpenVBX/libraries/Services/Twilio/ListResource.php
+++ b/OpenVBX/libraries/Services/Twilio/ListResource.php
@@ -1,22 +1,26 @@
+ * @author Neuman Vong neuman@twilio.com
* @license http://creativecommons.org/licenses/MIT/ MIT
* @link http://pear.php.net/package/Services_Twilio
*/
-abstract class Services_Twilio_ListResource
- extends Services_Twilio_Resource
+
+/**
+ * Abstraction of a list resource from the Twilio API.
+ *
+ * The list resource implements the `IteratorAggregate
+ * `_ and the `Countable
+ * `_ interfaces.
+ *
+ */
+abstract class Services_Twilio_ListResource extends Services_Twilio_Resource
implements IteratorAggregate, Countable
{
public function __construct($client, $uri) {
$name = $this->getResourceName(true);
- /*
+ /*
* By default trim the 's' from the end of the list name to get the
* instance name (ex Accounts -> Account). This behavior can be
* overridden by child classes if the rule doesn't work.
@@ -24,17 +28,18 @@ public function __construct($client, $uri) {
if (!isset($this->instance_name)) {
$this->instance_name = "Services_Twilio_Rest_" . rtrim($name, 's');
}
+
parent::__construct($client, $uri);
}
/**
* Gets a resource from this list.
*
- * @param string $sid The resource SID
- * @return Services_Twilio_InstanceResource The resource
+ * :param string $sid: The resource SID
+ * :return: The resource
+ * :rtype: :php:class:`InstanceResource `
*/
- public function get($sid)
- {
+ public function get($sid) {
$instance = new $this->instance_name(
$this->client, $this->uri . "/$sid"
);
@@ -43,12 +48,14 @@ public function get($sid)
return $instance;
}
- /*
- * Construct an InstanceResource with the specified params.
+ /**
+ * Construct an :php:class:`InstanceResource
+ * ` with the specified params.
*
- * @param array params usually a JSON HTTP response from the API
- * @return Services_Twilio_InstanceResource An instance with properties
+ * :param array $params: usually a JSON HTTP response from the API
+ * :return: An instance with properties
* initialized to the values in the params array.
+ * :rtype: :php:class:`InstanceResource `
*/
public function getObjectFromJson($params, $idParam = "sid")
{
@@ -63,10 +70,10 @@ public function getObjectFromJson($params, $idParam = "sid")
/**
* Deletes a resource from this list.
*
- * @param string $sid The resource SID
- * @return null
+ * :param string $sid: The resource SID
+ * :rtype: null
*/
- public function delete($sid, array $params = array())
+ public function delete($sid, $params = array())
{
$this->client->deleteData($this->uri . '/' . $sid, $params);
}
@@ -75,11 +82,12 @@ public function delete($sid, array $params = array())
* Create a resource on the list and then return its representation as an
* InstanceResource.
*
- * @param array $params The parameters with which to create the resource
+ * :param array $params: The parameters with which to create the resource
*
- * @return Services_Twilio_InstanceResource The created resource
+ * :return: The created resource
+ * :rtype: :php:class:`InstanceResource `
*/
- protected function _create(array $params)
+ protected function _create($params)
{
$params = $this->client->createData($this->uri, $params);
/* Some methods like verified caller ID don't return sids. */
@@ -92,19 +100,20 @@ protected function _create(array $params)
}
/**
- * Returns a page of InstanceResources from this list.
+ * Returns a page of :php:class:`InstanceResources
+ * ` from this list.
*
- * @param int $page The start page
- * @param int $size Number of items per page
- * @param array $filters Optional filters
- * @param string $deep_paging_uri if provided, the $page and $size
+ * :param int $page: The start page
+ * :param int $size: Number of items per page
+ * :param array $filters: Optional filters
+ * :param string $deep_paging_uri: if provided, the $page and $size
* parameters will be ignored and this URI will be requested directly.
*
- * @return Services_Twilio_Page A page
+ * :return: A page of resources
+ * :rtype: :php:class:`Services_Twilio_Page`
*/
public function getPage(
- $page = 0, $size = 50, array $filters = array(),
- $deep_paging_uri = null
+ $page = 0, $size = 50, $filters = array(), $deep_paging_uri = null
) {
$list_name = $this->getResourceName();
if ($deep_paging_uri !== null) {
@@ -130,13 +139,15 @@ public function getPage(
}
/**
- * Get the total number of instance members. Note this will make one small
- * HTTP request to retrieve the total, every time this method is called.
+ * Get the total number of instances for this list.
*
- * If the total is not set or an Exception was thrown, returns 0
+ * This will make one HTTP request to retrieve the total, every time this
+ * method is called.
*
- * @return integer
+ * If the total is not set, or an Exception was thrown, returns 0
*
+ * :return: The total number of instance members
+ * :rtype: integer
*/
public function count() {
try {
@@ -149,37 +160,44 @@ public function count() {
/**
- * Returns an iterable list of InstanceResources
+ * Returns an iterable list of
+ * :php:class:`instance resources `.
+ *
+ * :param int $page: The start page
+ * :param int $size: Number of items per page
+ * :param array $filters: Optional filters.
+ * The filter array can accept full datetimes when StartTime or DateCreated
+ * are used. Inequalities should be within the key portion of the array and
+ * multiple filter parameters can be combined for more specific searches.
*
- * @param int $page The start page
- * @param int $size Number of items per page
- * @param array $size Optional filters
+ * .. code-block:: php
*
- * The filter array can accept full datetimes when StartTime or DateCreated
- * are used. Inequalities should be within the key portion of the array and
- * multiple filter parameters can be combined for more specific searches.
+ * array('DateCreated>' => '2011-07-05 08:00:00', 'DateCreated<' => '2011-08-01')
*
- * eg.
- * array('DateCreated>' => '2011-07-05 08:00:00', 'DateCreated<' => '2011-08-01')
- * or
- * array('StartTime<' => '2011-07-05 08:00:00')
+ * .. code-block:: php
*
- * @return Services_Twilio_AutoPagingIterator An iterator
+ * array('StartTime<' => '2011-07-05 08:00:00')
+ *
+ * :return: An iterator
+ * :rtype: :php:class:`Services_Twilio_AutoPagingIterator`
*/
public function getIterator(
- $page = 0, $size = 50, array $filters = array()
+ $page = 0, $size = 50, $filters = array()
) {
return new Services_Twilio_AutoPagingIterator(
array($this, 'getPageGenerator'), $page, $size, $filters
);
}
- /*
- * Retrieve a new page of API results, and update iterator parameters.
+ /**
+ * Retrieve a new page of API results, and update iterator parameters. This
+ * function is called by the paging iterator to retrieve a new page and
+ * shouldn't be called directly.
*/
public function getPageGenerator(
- $page, $size, array $filters = array(), $deep_paging_uri = null
+ $page, $size, $filters = array(), $deep_paging_uri = null
) {
return $this->getPage($page, $size, $filters, $deep_paging_uri);
}
}
+
diff --git a/OpenVBX/libraries/Services/Twilio/NumberType.php b/OpenVBX/libraries/Services/Twilio/NumberType.php
new file mode 100644
index 00000000..0683d996
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/NumberType.php
@@ -0,0 +1,35 @@
+instance_name = 'Services_Twilio_Rest_IncomingPhoneNumber';
+ return $camelized ? 'IncomingPhoneNumbers' : 'incoming_phone_numbers';
+ }
+
+ /**
+ * Purchase a new phone number.
+ *
+ * Example usage:
+ *
+ * .. code-block:: php
+ *
+ * $marlosBurner = '+14105551234';
+ * $client->account->incoming_phone_numbers->local->purchase($marlosBurner);
+ *
+ * :param string $phone_number: The phone number to purchase
+ * :param array $params: An optional array of parameters to pass along with
+ * the request (to configure the phone number)
+ */
+ public function purchase($phone_number, array $params = array()) {
+ $postParams = array(
+ 'PhoneNumber' => $phone_number
+ );
+ return $this->create($postParams + $params);
+ }
+
+ public function create(array $params = array()) {
+ return parent::_create($params);
+ }
+
+}
diff --git a/OpenVBX/libraries/Services/Twilio/RequestValidator.php b/OpenVBX/libraries/Services/Twilio/RequestValidator.php
index 4bf3f0cb..52a40d91 100755
--- a/OpenVBX/libraries/Services/Twilio/RequestValidator.php
+++ b/OpenVBX/libraries/Services/Twilio/RequestValidator.php
@@ -33,4 +33,4 @@ public function validate($expectedSignature, $url, $data = array())
== $expectedSignature;
}
-}
\ No newline at end of file
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Resource.php b/OpenVBX/libraries/Services/Twilio/Resource.php
index 5d80f479..5320e537 100755
--- a/OpenVBX/libraries/Services/Twilio/Resource.php
+++ b/OpenVBX/libraries/Services/Twilio/Resource.php
@@ -8,7 +8,7 @@
* @author Neuman Vong
* @license http://creativecommons.org/licenses/MIT/ MIT
* @link http://pear.php.net/package/Services_Twilio
- */
+ */
abstract class Services_Twilio_Resource {
protected $subresources;
@@ -50,14 +50,14 @@ protected function setupSubresources()
}
}
- /*
+ /*
* Get the resource name from the classname
- *
+ *
* Ex: Services_Twilio_Rest_Accounts -> Accounts
*
* @param boolean $camelized Whether to return camel case or not
*/
- public function getResourceName($camelized = false)
+ public function getResourceName($camelized = false)
{
$name = get_class($this);
$parts = explode('_', $name);
@@ -71,28 +71,35 @@ public function getResourceName($camelized = false)
public static function decamelize($word)
{
- return preg_replace(
- '/(^|[a-z])([A-Z])/e',
- 'strtolower(strlen("\\1") ? "\\1_\\2" : "\\2")',
+ $callback = create_function('$matches',
+ 'return strtolower(strlen("$matches[1]") ? "$matches[1]_$matches[2]" : "$matches[2]");');
+
+ return preg_replace_callback(
+ '/(^|[a-z])([A-Z])/',
+ $callback,
$word
);
}
/**
* Return camelized version of a word
- * Examples: sms_messages => SMSMessages, calls => Calls,
+ * Examples: sms_messages => SMSMessages, calls => Calls,
* incoming_phone_numbers => IncomingPhoneNumbers
*
* @param string $word The word to camelize
* @return string
*/
public static function camelize($word) {
- return preg_replace('/(^|_)([a-z])/e', 'strtoupper("\\2")', $word);
+ $callback = create_function('$matches', 'return strtoupper("$matches[2]");');
+
+ return preg_replace_callback('/(^|_)([a-z])/',
+ $callback,
+ $word);
}
/**
* Get the value of a property on this resource.
- *
+ *
* @param string $key The property name
* @return mixed Could be anything.
*/
@@ -104,19 +111,19 @@ public function __get($key) {
}
/**
- * Print a JSON representation of this object. Strips the HTTP client
+ * Print a JSON representation of this object. Strips the HTTP client
* before returning.
*
- * Note, this should mainly be used for debugging, and is not guaranteed
+ * Note, this should mainly be used for debugging, and is not guaranteed
* to correspond 1:1 with the JSON API output.
*
- * Note that echoing an object before an HTTP request has been made to
+ * Note that echoing an object before an HTTP request has been made to
* "fill in" its properties may return an empty object
*/
public function __toString() {
$out = array();
foreach ($this as $key => $value) {
- if ($key !== "client") {
+ if ($key !== "client" && $key !== "subresources") {
$out[$key] = (string)$value;
}
}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Account.php b/OpenVBX/libraries/Services/Twilio/Rest/Account.php
index fec0e21c..e1181b7d 100755
--- a/OpenVBX/libraries/Services/Twilio/Rest/Account.php
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Account.php
@@ -10,6 +10,8 @@ protected function init($client, $uri) {
'calls',
'conferences',
'incoming_phone_numbers',
+ 'media',
+ 'messages',
'notifications',
'outgoing_callerids',
'recordings',
@@ -20,7 +22,8 @@ protected function init($client, $uri) {
'authorized_connect_apps',
'usage_records',
'usage_triggers',
- 'queues'
+ 'queues',
+ 'sip'
);
$this->sandbox = new Services_Twilio_Rest_Sandbox(
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Accounts.php b/OpenVBX/libraries/Services/Twilio/Rest/Accounts.php
index d85db9e1..0e7ea0a5 100755
--- a/OpenVBX/libraries/Services/Twilio/Rest/Accounts.php
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Accounts.php
@@ -1,10 +1,25 @@
`_ documentation.
+ */
+class Services_Twilio_Rest_Accounts extends Services_Twilio_ListResource {
+
+ /**
+ * Create a new subaccount.
+ *
+ * :param array $params: An array of parameters describing the new
+ * subaccount. The ``$params`` array can contain the following keys:
+ *
+ * *FriendlyName*
+ * A description of this account, up to 64 characters long
+ *
+ * :returns: The new subaccount
+ * :rtype: :php:class:`Services_Twilio_Rest_Account`
+ *
+ */
+ public function create($params = array()) {
return parent::_create($params);
}
}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/AvailablePhoneNumbers.php b/OpenVBX/libraries/Services/Twilio/Rest/AvailablePhoneNumbers.php
index e774b94c..9d371411 100755
--- a/OpenVBX/libraries/Services/Twilio/Rest/AvailablePhoneNumbers.php
+++ b/OpenVBX/libraries/Services/Twilio/Rest/AvailablePhoneNumbers.php
@@ -3,8 +3,7 @@
class Services_Twilio_Rest_AvailablePhoneNumbers
extends Services_Twilio_ListResource
{
- public function getLocal($country)
- {
+ public function getLocal($country) {
$curried = new Services_Twilio_PartialApplicationHelper();
$curried->set(
'getList',
@@ -13,8 +12,7 @@ public function getLocal($country)
);
return $curried;
}
- public function getTollFree($country)
- {
+ public function getTollFree($country) {
$curried = new Services_Twilio_PartialApplicationHelper();
$curried->set(
'getList',
@@ -24,12 +22,23 @@ public function getTollFree($country)
return $curried;
}
+ public function getMobile($country)
+ {
+ $curried = new Services_Twilio_PartialApplicationHelper();
+ $curried->set(
+ 'getList',
+ array($this, 'getList'),
+ array($country, 'Mobile')
+ );
+ return $curried;
+ }
+
/**
- * Get a list of available phone numbers.
+ * Get a list of available phone numbers.
*
* @param string $country The 2-digit country code you'd like to search for
* numbers e.g. ('US', 'CA', 'GB')
- * @param string $type The type of number ('Local' or 'TollFree')
+ * @param string $type The type of number ('Local', 'TollFree', or 'Mobile')
* @return object The object representation of the resource
*/
public function getList($country, $type, array $params = array())
@@ -37,8 +46,7 @@ public function getList($country, $type, array $params = array())
return $this->client->retrieveData($this->uri . "/$country/$type", $params);
}
- public function getResourceName($camelized = false)
- {
+ public function getResourceName($camelized = false) {
// You can't page through the list of available phone numbers.
$this->instance_name = 'Services_Twilio_Rest_AvailablePhoneNumber';
return $camelized ? 'Countries' : 'countries';
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Call.php b/OpenVBX/libraries/Services/Twilio/Rest/Call.php
index f862c79b..75565684 100755
--- a/OpenVBX/libraries/Services/Twilio/Rest/Call.php
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Call.php
@@ -1,19 +1,102 @@
`_ documentation.
+ *
+ * .. php:attr:: sid
+ *
+ * A 34 character string that uniquely identifies this resource.
+ *
+ * .. php:attr:: parent_call_sid
+ *
+ * A 34 character string that uniquely identifies the call that created this leg.
+ *
+ * .. php:attr:: date_created
+ *
+ * The date that this resource was created, given as GMT in RFC 2822 format.
+ *
+ * .. php:attr:: date_updated
+ *
+ * The date that this resource was last updated, given as GMT in RFC 2822 format.
+ *
+ * .. php:attr:: account_sid
+ *
+ * The unique id of the Account responsible for creating this call.
+ *
+ * .. php:attr:: to
+ *
+ * The phone number that received this call. e.g., +16175551212 (E.164 format)
+ *
+ * .. php:attr:: from
+ *
+ * The phone number that made this call. e.g., +16175551212 (E.164 format)
+ *
+ * .. php:attr:: phone_number_sid
+ *
+ * If the call was inbound, this is the Sid of the IncomingPhoneNumber that
+ * received the call. If the call was outbound, it is the Sid of the
+ * OutgoingCallerId from which the call was placed.
+ *
+ * .. php:attr:: status
+ *
+ * A string representing the status of the call. May be `QUEUED`, `RINGING`,
+ * `IN-PROGRESS`, `COMPLETED`, `FAILED`, `BUSY` or `NO_ANSWER`.
+ *
+ * .. php:attr:: stat_time
+ *
+ * The start time of the call, given as GMT in RFC 2822 format. Empty if the call has not yet been dialed.
+ *
+ * .. php:attr:: end_time
+ *
+ * The end time of the call, given as GMT in RFC 2822 format. Empty if the call did not complete successfully.
+ *
+ * .. php:attr:: duration
+ *
+ * The length of the call in seconds. This value is empty for busy, failed, unanswered or ongoing calls.
+ *
+ * .. php:attr:: price
+ *
+ * The charge for this call in USD. Populated after the call is completed. May not be immediately available.
+ *
+ * .. php:attr:: direction
+ *
+ * A string describing the direction of the call. inbound for inbound
+ * calls, outbound-api for calls initiated via the REST API or
+ * outbound-dial for calls initiated by a verb.
+ *
+ * .. php:attr:: answered_by
+ *
+ * If this call was initiated with answering machine detection, either human or machine. Empty otherwise.
+ *
+ * .. php:attr:: forwarded_from
+ *
+ * If this call was an incoming call forwarded from another number, the
+ * forwarding phone number (depends on carrier supporting forwarding).
+ * Empty otherwise.
+ *
+ * .. php:attr:: caller_name
+ *
+ * If this call was an incoming call from a phone number with Caller ID Lookup enabled, the caller's name. Empty otherwise.
+ */
+class Services_Twilio_Rest_Call extends Services_Twilio_InstanceResource {
+
+ /**
+ * Hang up the call
+ */
+ public function hangup() {
$this->update('Status', 'completed');
}
+ /**
+ * Redirect the call to a new URL
+ *
+ * :param string $url: the new URL to retrieve call flow from.
+ */
public function route($url) {
$this->update('Url', $url);
}
- protected function init($client, $uri)
- {
+ protected function init($client, $uri) {
$this->setupSubresources(
'notifications',
'recordings'
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Credential.php b/OpenVBX/libraries/Services/Twilio/Rest/Credential.php
new file mode 100644
index 00000000..03d82652
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Credential.php
@@ -0,0 +1,30 @@
+setupSubresources(
+ 'credentials'
+ );
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/CredentialListMapping.php b/OpenVBX/libraries/Services/Twilio/Rest/CredentialListMapping.php
new file mode 100644
index 00000000..3f9c3054
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/CredentialListMapping.php
@@ -0,0 +1,37 @@
+setupSubresources(
+ 'credentials'
+ );
+ }
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/CredentialListMappings.php b/OpenVBX/libraries/Services/Twilio/Rest/CredentialListMappings.php
new file mode 100644
index 00000000..ab34f60c
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/CredentialListMappings.php
@@ -0,0 +1,24 @@
+account->sip->domains->get('SDXXX')->credential_list_mappings->create("CLXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ *
+ * :param string $credential_list_sid: the sid of the CredentialList you're adding to this domain.
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API.
+ */
+ public function create($credential_list_sid, $params = array()) {
+ return parent::_create(array(
+ 'CredentialListSid' => $credential_list_sid,
+ ) + $params);
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/CredentialLists.php b/OpenVBX/libraries/Services/Twilio/Rest/CredentialLists.php
new file mode 100644
index 00000000..e8eb1a69
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/CredentialLists.php
@@ -0,0 +1,24 @@
+account->sip->credential_lists->create("MyFriendlyName");
+ *
+ * :param string $friendly_name: the friendly name of this credential list
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API.
+ */
+ public function create($friendly_name, $params = array()) {
+ return parent::_create(array(
+ 'FriendlyName' => $friendly_name,
+ ) + $params);
+ }
+
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Credentials.php b/OpenVBX/libraries/Services/Twilio/Rest/Credentials.php
new file mode 100644
index 00000000..129a44db
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Credentials.php
@@ -0,0 +1,28 @@
+account->sip->credential_lists->get('CLXXX')->credentials->create(
+ * "AwesomeUsername", "SuperSecretPassword",
+ * );
+ *
+ * :param string $username: the username for the new Credential object
+ * :param string $password: the password for the new Credential object
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API.
+ */
+ public function create($username, $password, $params = array()) {
+ return parent::_create(array(
+ 'Username' => $username,
+ 'Password' => $password,
+ ) + $params);
+ }
+
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Domain.php b/OpenVBX/libraries/Services/Twilio/Rest/Domain.php
new file mode 100644
index 00000000..7d5a5c26
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Domain.php
@@ -0,0 +1,70 @@
+setupSubresources(
+ 'ip_access_control_list_mappings',
+ 'credential_list_mappings'
+ );
+ }
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Domains.php b/OpenVBX/libraries/Services/Twilio/Rest/Domains.php
new file mode 100644
index 00000000..041c080c
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Domains.php
@@ -0,0 +1,28 @@
+account->sip->domains->create(
+ * "MyFriendlyName", "MyDomainName"
+ * );
+ *
+ * :param string $friendly_name: the friendly name of this domain
+ * :param string $domain_name: the domain name for this domain
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API.
+ */
+ public function create($friendly_name, $domain_name, $params = array()) {
+ return parent::_create(array(
+ 'FriendlyName' => $friendly_name,
+ 'DomainName' => $domain_name,
+ ) + $params);
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumber.php b/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumber.php
index 9cc65526..ab72eafe 100755
--- a/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumber.php
+++ b/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumber.php
@@ -1,5 +1,90 @@
`_
+ * documentation.
+ *
+ * .. php:attr:: sid
+ *
+ * A 34 character string that uniquely idetifies this resource.
+ *
+ * .. php:attr:: date_created
+ *
+ * The date that this resource was created, given as GMT RFC 2822 format.
+ *
+ * .. php:attr:: date_updated
+ *
+ * The date that this resource was last updated, given as GMT RFC 2822 format.
+ *
+ * .. php:attr:: friendly_name
+ *
+ * A human readable descriptive text for this resource, up to 64
+ * characters long. By default, the FriendlyName is a nicely formatted
+ * version of the phone number.
+ *
+ * .. php:attr:: account_sid
+ *
+ * The unique id of the Account responsible for this phone number.
+ *
+ * .. php:attr:: phone_number
+ *
+ * The incoming phone number. e.g., +16175551212 (E.164 format)
+ *
+ * .. php:attr:: api_version
+ *
+ * Calls to this phone number will start a new TwiML session with this
+ * API version.
+ *
+ * .. php:attr:: voice_caller_id_lookup
+ *
+ * Look up the caller's caller-ID name from the CNAM database (additional charges apply). Either true or false.
+ *
+ * .. php:attr:: voice_url
+ *
+ * The URL Twilio will request when this phone number receives a call.
+ *
+ * .. php:attr:: voice_method
+ *
+ * The HTTP method Twilio will use when requesting the above Url. Either GET or POST.
+ *
+ * .. php:attr:: voice_fallback_url
+ *
+ * The URL that Twilio will request if an error occurs retrieving or executing the TwiML requested by Url.
+ *
+ * .. php:attr:: voice_fallback_method
+ *
+ * The HTTP method Twilio will use when requesting the VoiceFallbackUrl. Either GET or POST.
+ *
+ * .. php:attr:: status_callback
+ *
+ * The URL that Twilio will request to pass status parameters (such as call ended) to your application.
+ *
+ * .. php:attr:: status_callback_method
+ *
+ * The HTTP method Twilio will use to make requests to the StatusCallback URL. Either GET or POST.
+ *
+ * .. php:attr:: sms_url
+ *
+ * The URL Twilio will request when receiving an incoming SMS message to this number.
+ *
+ * .. php:attr:: sms_method
+ *
+ * The HTTP method Twilio will use when making requests to the SmsUrl. Either GET or POST.
+ *
+ * .. php:attr:: sms_fallback_url
+ *
+ * The URL that Twilio will request if an error occurs retrieving or executing the TwiML from SmsUrl.
+ *
+ * .. php:attr:: sms_fallback_method
+ *
+ * The HTTP method Twilio will use when requesting the above URL. Either GET or POST.
+ *
+ * .. php:attr:: uri
+ *
+ * The URI for this resource, relative to https://api.twilio.com.
+ */
class Services_Twilio_Rest_IncomingPhoneNumber
extends Services_Twilio_InstanceResource
{
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumbers.php b/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumbers.php
index 15cafa22..48ce4cab 100755
--- a/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumbers.php
+++ b/OpenVBX/libraries/Services/Twilio/Rest/IncomingPhoneNumbers.php
@@ -1,22 +1,44 @@
`_
+ * documentation at twilio.com.
+ */
+class Services_Twilio_Rest_IncomingPhoneNumbers extends Services_Twilio_ListResource {
+ function init($client, $uri) {
+ $this->setupSubresources(
+ 'local',
+ 'toll_free',
+ 'mobile'
+ );
+ }
+
function create(array $params = array()) {
return parent::_create($params);
}
+ function getList($type, array $params = array())
+ {
+ return $this->client->retrieveData($this->uri . "/$type", $params);
+ }
+
/**
* Return a phone number instance from its E.164 representation. If more
* than one number matches the search string, returns the first one.
*
- * @param string $number The number in E.164 format, eg "+684105551234"
- * @return Services_Twilio_Rest_IncomingPhoneNumber|null The number object,
- * or null
- *
- * @throws Services_Twilio_RestException if the number is invalid, not
- * provided in E.164 format or for any other API exception.
+ * Example usage:
+ *
+ * .. code-block:: php
+ *
+ * $number = $client->account->incoming_phone_numbers->getNumber('+14105551234');
+ * echo $number->sid;
+ *
+ * :param string $number: The number in E.164 format, eg "+684105551234"
+ * :return: A :php:class:`Services_Twilio_Rest_IncomingPhoneNumber` object, or null
+ * :raises: a A :php:class:`Services_Twilio_RestException` if the number is
+ * invalid, not provided in E.164 format or for any other API exception.
*/
public function getNumber($number) {
$page = $this->getPage(0, 1, array(
@@ -29,3 +51,9 @@ public function getNumber($number) {
return $items[0];
}
}
+
+class Services_Twilio_Rest_Local extends Services_Twilio_NumberType { }
+
+class Services_Twilio_Rest_Mobile extends Services_Twilio_NumberType { }
+
+class Services_Twilio_Rest_TollFree extends Services_Twilio_NumberType { }
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlList.php b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlList.php
new file mode 100644
index 00000000..5ba83f3e
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlList.php
@@ -0,0 +1,40 @@
+setupSubresources(
+ 'ip_addresses'
+ );
+ }
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlListMapping.php b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlListMapping.php
new file mode 100644
index 00000000..ce5bc5a9
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlListMapping.php
@@ -0,0 +1,37 @@
+setupSubresources(
+ 'ip_addresses'
+ );
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlListMappings.php b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlListMappings.php
new file mode 100644
index 00000000..f58e1b95
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlListMappings.php
@@ -0,0 +1,25 @@
+account->sip->domains->get('SDXXX')->ip_access_control_list_mappings->create("ALXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
+ *
+ * :param string $ip_access_control_list_sid: the sid of the IpAccessControList
+ * you're adding to this domain.
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API.
+ */
+ public function create($ip_access_control_list_sid, $params = array()) {
+ return parent::_create(array(
+ 'IpAccessControlListSid' => $ip_access_control_list_sid,
+ ) + $params);
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlLists.php b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlLists.php
new file mode 100644
index 00000000..88b9d14f
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/IpAccessControlLists.php
@@ -0,0 +1,27 @@
+account->sip->ip_access_control_lists->create("MyFriendlyName");
+ *
+ * :param string $friendly_name: the friendly name of this ip access control list
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API.
+ * :return: the created list
+ * :rtype: :class:`Services_Twilio_Rest_IpAccessControlList`
+ *
+ */
+ public function create($friendly_name, $params = array()) {
+ return parent::_create(array(
+ 'FriendlyName' => $friendly_name,
+ ) + $params);
+ }
+
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/IpAddress.php b/OpenVBX/libraries/Services/Twilio/Rest/IpAddress.php
new file mode 100644
index 00000000..38b716e6
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/IpAddress.php
@@ -0,0 +1,34 @@
+instance_name = "Services_Twilio_Rest_IpAddress";
+ parent::__construct($client, $uri);
+ }
+
+ /**
+ * Creates a new IpAddress instance
+ *
+ * Example usage:
+ *
+ * .. code-block:: php
+ *
+ * $client->account->sip->ip_access_control_lists->get('ALXXX')->ip_addresses->create(
+ * "FriendlyName", "127.0.0.1"
+ * );
+ *
+ * :param string $friendly_name: the friendly name for the new IpAddress object
+ * :param string $ip_address: the ip address for the new IpAddress object
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API.
+ */
+ public function create($friendly_name, $ip_address, $params = array()) {
+ return parent::_create(array(
+ 'FriendlyName' => $friendly_name,
+ 'IpAddress' => $ip_address,
+ ) + $params);
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Media.php b/OpenVBX/libraries/Services/Twilio/Rest/Media.php
new file mode 100644
index 00000000..0d8a19f3
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Media.php
@@ -0,0 +1,31 @@
+` objects.
+ * For the definitive reference, see the `Twilio Media List Documentation
+ * `_.
+ */
+class Services_Twilio_Rest_Media extends Services_Twilio_ListResource {
+
+
+ // This is overridden because the list key in the Twilio response
+ // is "media_list", not "media".
+ public function getResourceName($camelized = false)
+ {
+ if ($camelized) {
+ return "MediaList";
+ } else {
+ return "media_list";
+ }
+ }
+
+ // We manually set the instance name here so that the parent
+ // constructor doesn't attempt to figure out it. It would do it
+ // incorrectly because we override getResourceName above.
+ public function __construct($client, $uri) {
+ $this->instance_name = "Services_Twilio_Rest_MediaInstance";
+ parent::__construct($client, $uri);
+ }
+
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/MediaInstance.php b/OpenVBX/libraries/Services/Twilio/Rest/MediaInstance.php
new file mode 100644
index 00000000..1a152b2e
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/MediaInstance.php
@@ -0,0 +1,37 @@
+`_.
+ *
+ * .. php:attr:: sid
+ *
+ * A 34 character string that identifies this object
+ *
+ * .. php:attr:: account_sid
+ *
+ * A 34 character string representing the account that sent the message
+ *
+ * .. php:attr:: parent_sid
+ *
+ * The sid of the message that created this media.
+ *
+ * .. php:attr:: date_created
+ *
+ * The date the message was created
+ *
+ * .. php:attr:: date_updated
+ *
+ * The date the message was updated
+ *
+ * .. php:attr:: content_type
+ *
+ * The content-type of the media.
+ */
+class Services_Twilio_Rest_MediaInstance extends Services_Twilio_InstanceResource {
+ public function __construct($client, $uri) {
+ $uri = str_replace('MediaInstance', 'Media', $uri);
+ parent::__construct($client, $uri);
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Message.php b/OpenVBX/libraries/Services/Twilio/Rest/Message.php
new file mode 100644
index 00000000..afc6cf5b
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Message.php
@@ -0,0 +1,53 @@
+setupSubresources(
+ 'media'
+ );
+ }
+}
+
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Messages.php b/OpenVBX/libraries/Services/Twilio/Rest/Messages.php
new file mode 100644
index 00000000..355fce03
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Messages.php
@@ -0,0 +1,73 @@
+account->messages->create(array(
+ * "Body" => "foo",
+ * "From" => "+14105551234",
+ * "To" => "+14105556789",
+ * ));
+ *
+ * :param array $params: a single array of parameters which is serialized and
+ * sent directly to the Twilio API. You may find it easier to use the
+ * sendMessage helper instead of this function.
+ *
+ */
+ public function create($params = array()) {
+ return parent::_create($params);
+ }
+
+ /**
+ * Send a message
+ *
+ * .. code-block:: php
+ *
+ * $client = new Services_Twilio('AC123', '123');
+ * $message = $client->account->messages->sendMessage(
+ * '+14105551234', // From a Twilio number in your account
+ * '+14105556789', // Text any number
+ * 'Come at the king, you best not miss.' // Message body (if any)
+ * array('https://demo.twilio.com/owl.png'), // An array of MediaUrls
+ * );
+ *
+ * :param string $from: the from number for the message, this must be a
+ * number you purchased from Twilio
+ * :param string $to: the message recipient's phone number
+ * :param $mediaUrls: the URLs of images to send in this MMS
+ * :type $mediaUrls: null (don't include media), a single URL, or an array
+ * of URLs to send as media with this message
+ * :param string $body: the text to include along with this MMS
+ * :param array $params: Any additional params (callback, etc) you'd like to
+ * send with this request, these are serialized and sent as POST
+ * parameters
+ *
+ * :return: The created :class:`Services_Twilio_Rest_Message`
+ * :raises: :class:`Services_Twilio_RestException`
+ * An exception if the parameters are invalid (for example, the from
+ * number is not a Twilio number registered to your account, or is
+ * unable to send MMS)
+ */
+ public function sendMessage($from, $to, $body = null, $mediaUrls = null,
+ $params = array()
+ ) {
+ $postParams = array(
+ 'From' => $from,
+ 'To' => $to,
+ );
+ // When the request is made, this will get serialized into MediaUrl=a&MediaUrl=b
+ if (!is_null($mediaUrls)) {
+ $postParams['MediaUrl'] = $mediaUrls;
+ }
+ if (!is_null($body)) {
+ $postParams['Body'] = $body;
+ }
+ return self::create($postParams + $params);
+ }
+}
diff --git a/OpenVBX/libraries/Services/Twilio/Rest/Sip.php b/OpenVBX/libraries/Services/Twilio/Rest/Sip.php
new file mode 100644
index 00000000..8c4bdb5d
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/Rest/Sip.php
@@ -0,0 +1,19 @@
+setupSubresources(
+ 'domains',
+ 'ip_access_control_lists',
+ 'credential_lists'
+ );
+ }
+
+ public function getResourceName($camelized = false) {
+ return "SIP";
+ }
+}
diff --git a/OpenVBX/libraries/Services/Twilio/RestException.php b/OpenVBX/libraries/Services/Twilio/RestException.php
index c7e77a3c..c7de16ce 100755
--- a/OpenVBX/libraries/Services/Twilio/RestException.php
+++ b/OpenVBX/libraries/Services/Twilio/RestException.php
@@ -1,25 +1,44 @@
status = $status;
$this->info = $info;
parent::__construct($message, $code);
}
- public function getStatus()
- {
+ /**
+ * Get the HTTP status code
+ */
+ public function getStatus() {
return $this->status;
}
- public function getInfo()
- {
+ /**
+ * Get a link to more information
+ */
+ public function getInfo() {
return $this->info;
}
}
diff --git a/OpenVBX/libraries/Services/Twilio/SIPListResource.php b/OpenVBX/libraries/Services/Twilio/SIPListResource.php
new file mode 100644
index 00000000..1e63b67f
--- /dev/null
+++ b/OpenVBX/libraries/Services/Twilio/SIPListResource.php
@@ -0,0 +1,14 @@
+ array(
+ * CURLOPT_USERAGENT => self::USER_AGENT,
+ * CURLOPT_HTTPHEADER => array('Accept-Charset: utf-8'),
+ * CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem',
+ * ))
+ * );
+ */
class Services_Twilio_TinyHttp {
var $user, $pass, $scheme, $host, $port, $debug, $curlopts;
@@ -83,7 +107,7 @@ public function __call($name, $args) {
fclose($buf);
}
return array($status, $headers, $body);
- } else {
+ } else {
throw new Services_Twilio_TinyHttpException(curl_error($curl));
}
} else throw new Services_Twilio_TinyHttpException(curl_error($curl));
diff --git a/OpenVBX/libraries/Services/Twilio/Twiml.php b/OpenVBX/libraries/Services/Twilio/Twiml.php
index 41e73053..93c30eb7 100755
--- a/OpenVBX/libraries/Services/Twilio/Twiml.php
+++ b/OpenVBX/libraries/Services/Twilio/Twiml.php
@@ -115,7 +115,7 @@ public function __call($verb, array $args)
}
$child->addAttribute($name, $value);
}
- return new self($child);
+ return new static($child);
}
/**
diff --git a/OpenVBX/models/vbx_accounts.php b/OpenVBX/models/vbx_accounts.php
index 167256dc..b9d937fa 100644
--- a/OpenVBX/models/vbx_accounts.php
+++ b/OpenVBX/models/vbx_accounts.php
@@ -23,7 +23,7 @@
class VBX_AccountsException extends Exception {}
-class VBX_Accounts extends Model
+class VBX_Accounts extends CI_Model
{
public function __construct()
{
@@ -50,4 +50,4 @@ function getAccountType()
return $account_type;
}
-}
\ No newline at end of file
+}
diff --git a/OpenVBX/models/vbx_call.php b/OpenVBX/models/vbx_call.php
index 4fca18c5..00998193 100644
--- a/OpenVBX/models/vbx_call.php
+++ b/OpenVBX/models/vbx_call.php
@@ -26,14 +26,14 @@ class VBX_CallException extends Exception {}
/*
* Call Class
*/
-class VBX_Call extends Model {
+class VBX_Call extends CI_Model {
public $total = 0;
const CACHE_TIME_SEC = 180;
public function __construct()
{
- parent::Model();
+ parent::__construct();
}
/**
diff --git a/OpenVBX/models/vbx_incoming_numbers.php b/OpenVBX/models/vbx_incoming_numbers.php
index 14de41da..fce9922a 100644
--- a/OpenVBX/models/vbx_incoming_numbers.php
+++ b/OpenVBX/models/vbx_incoming_numbers.php
@@ -23,7 +23,7 @@
class VBX_IncomingNumberException extends Exception {}
-class VBX_Incoming_numbers extends Model
+class VBX_Incoming_numbers extends CI_Model
{
public function __construct()
{
diff --git a/OpenVBX/models/vbx_message.php b/OpenVBX/models/vbx_message.php
index cbf0c545..9639e379 100644
--- a/OpenVBX/models/vbx_message.php
+++ b/OpenVBX/models/vbx_message.php
@@ -24,7 +24,7 @@ class VBX_MessageException extends Exception {}
/*
* Message Class
*/
-class VBX_Message extends Model {
+class VBX_Message extends CI_Model {
public $auto_populate_has_one = TRUE;
public $has_one = array('group', 'user');
diff --git a/OpenVBX/models/vbx_settings.php b/OpenVBX/models/vbx_settings.php
index 8be12eb4..4dec2036 100644
--- a/OpenVBX/models/vbx_settings.php
+++ b/OpenVBX/models/vbx_settings.php
@@ -21,7 +21,7 @@
class VBX_SettingsException extends Exception {}
-class VBX_Settings extends Model
+class VBX_Settings extends CI_Model
{
protected $settings_table = 'settings';
protected $tenants_table = 'tenants';
diff --git a/OpenVBX/models/vbx_sms_message.php b/OpenVBX/models/vbx_sms_message.php
index e7742ece..3bf88e2d 100644
--- a/OpenVBX/models/vbx_sms_message.php
+++ b/OpenVBX/models/vbx_sms_message.php
@@ -25,7 +25,7 @@ class VBX_Sms_messageException extends Exception {}
/*
* SMS Message Class
*/
-class VBX_Sms_message extends Model {
+class VBX_Sms_message extends CI_Model {
public $total = 0;
@@ -35,7 +35,7 @@ class VBX_Sms_message extends Model {
function __construct()
{
- parent::Model();
+ parent::__construct();
$ci = &get_instance();
$this->cache_key = $ci->twilio_sid . '_sms';
}
diff --git a/OpenVBX/models/vbx_theme.php b/OpenVBX/models/vbx_theme.php
index 4c63b26a..eb478d40 100644
--- a/OpenVBX/models/vbx_theme.php
+++ b/OpenVBX/models/vbx_theme.php
@@ -21,7 +21,7 @@
class VBX_ThemeException extends Exception {}
-class VBX_Theme extends Model
+class VBX_Theme extends CI_Model
{
public function __construct()
{
@@ -54,4 +54,4 @@ public function get_iphone_json($name)
$name = preg_replace('/[^0-9a-zA-Z-_]/', '', $name);
return read_file('assets/themes/'.$name.'/iphone.json');
}
-}
\ No newline at end of file
+}
diff --git a/index.php b/index.php
index 5cf6fdbc..87cd043e 100644
--- a/index.php
+++ b/index.php
@@ -90,7 +90,7 @@ function shutdown()
| NO TRAILING SLASH!
|
*/
-$application_folder = dirname(__FILE__) . '/OpenVBX';
+$application_folder = 'OpenVBX';
/*
|===============================================================
@@ -136,9 +136,11 @@ function shutdown()
|
*/
define('EXT', '.'.pathinfo(__FILE__, PATHINFO_EXTENSION));
-define('FCPATH', __FILE__);
+define('FCPATH', str_replace(SELF, '', __FILE__));
define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
define('BASEPATH', $system_folder.'/');
+// Name of the "system folder"
+define('SYSDIR', trim(strrchr(trim(BASEPATH, '/'), '/'), '/'));
if (is_dir($application_folder))
{
@@ -162,7 +164,7 @@ function shutdown()
| And away we go...
|
*/
-require_once BASEPATH.'codeigniter/CodeIgniter'.EXT;
+require_once BASEPATH.'core/CodeIgniter.php';
/* End of file index.php */
/* Location: ./index.php */
diff --git a/system/codeigniter/Base4.php b/system/codeigniter/Base4.php
deleted file mode 100644
index 91a43502..00000000
--- a/system/codeigniter/Base4.php
+++ /dev/null
@@ -1,69 +0,0 @@
-load->library('email') to instantiate
- * classes that can then be used within controllers as $this->email->send()
- *
- * PHP 4 also has trouble referencing the CI super object within application
- * constructors since objects do not exist until the class is fully
- * instantiated. Basically PHP 4 sucks...
- *
- * Since PHP 5 doesn't suffer from this problem so we load one of
- * two files based on the version of PHP being run.
- *
- * @package CodeIgniter
- * @subpackage codeigniter
- * @category front-controller
- * @author ExpressionEngine Dev Team
- * @link http://codeigniter.com/user_guide/
- */
- class CI_Base extends CI_Loader {
-
- function CI_Base()
- {
- // This allows syntax like $this->load->foo() to work
- parent::CI_Loader();
- $this->load =& $this;
-
- // This allows resources used within controller constructors to work
- global $OBJ;
- $OBJ = $this->load; // Do NOT use a reference.
- }
-}
-
-function &get_instance()
-{
- global $CI, $OBJ;
-
- if (is_object($CI))
- {
- return $CI;
- }
-
- return $OBJ->load;
-}
-
-
-/* End of file Base4.php */
-/* Location: ./system/codeigniter/Base4.php */
\ No newline at end of file
diff --git a/system/codeigniter/Base5.php b/system/codeigniter/Base5.php
deleted file mode 100644
index a2cca72c..00000000
--- a/system/codeigniter/Base5.php
+++ /dev/null
@@ -1,56 +0,0 @@
-mark('total_execution_time_start');
-$BM->mark('loading_time_base_classes_start');
-
-/*
- * ------------------------------------------------------
- * Instantiate the hooks class
- * ------------------------------------------------------
- */
-
-$EXT =& load_class('Hooks');
-
-/*
- * ------------------------------------------------------
- * Is there a "pre_system" hook?
- * ------------------------------------------------------
- */
-$EXT->_call_hook('pre_system');
-
-/*
- * ------------------------------------------------------
- * Instantiate the base classes
- * ------------------------------------------------------
- */
-
-$CFG =& load_class('Config');
-$URI =& load_class('URI');
-$RTR =& load_class('Router');
-$OUT =& load_class('Output');
-
-/*
- * ------------------------------------------------------
- * Is there a valid cache file? If so, we're done...
- * ------------------------------------------------------
- */
-
-if ($EXT->_call_hook('cache_override') === FALSE)
-{
- if ($OUT->_display_cache($CFG, $URI) == TRUE)
- {
- exit;
- }
-}
-
-/*
- * ------------------------------------------------------
- * Load the remaining base classes
- * ------------------------------------------------------
- */
-
-$IN =& load_class('Input');
-$LANG =& load_class('Language');
-
-/*
- * ------------------------------------------------------
- * Load the app controller and local controller
- * ------------------------------------------------------
- *
- * Note: Due to the poor object handling in PHP 4 we'll
- * conditionally load different versions of the base
- * class. Retaining PHP 4 compatibility requires a bit of a hack.
- *
- * Note: The Loader class needs to be included first
- *
- */
-if ( ! is_php('5.0.0'))
-{
- load_class('Loader', FALSE);
- require(BASEPATH.'codeigniter/Base4'.EXT);
-}
-else
-{
- require(BASEPATH.'codeigniter/Base5'.EXT);
-}
-
-// Load the base controller class
-load_class('Controller', FALSE);
-
-// Load the local application controller
-// Note: The Router class automatically validates the controller path. If this include fails it
-// means that the default controller in the Routes.php file is not resolving to something valid.
-if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT))
-{
- show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
-}
-
-include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().EXT);
-
-// Set a mark point for benchmarking
-$BM->mark('loading_time_base_classes_end');
-
-
-/*
- * ------------------------------------------------------
- * Security check
- * ------------------------------------------------------
- *
- * None of the functions in the app controller or the
- * loader class can be called via the URI, nor can
- * controller functions that begin with an underscore
- */
-$class = $RTR->fetch_class();
-$method = $RTR->fetch_method();
-
-if ( ! class_exists($class)
- OR $method == 'controller'
- OR strncmp($method, '_', 1) == 0
- OR in_array(strtolower($method), array_map('strtolower', get_class_methods('Controller')))
- )
-{
- show_404("{$class}/{$method}");
-}
-
-/*
- * ------------------------------------------------------
- * Is there a "pre_controller" hook?
- * ------------------------------------------------------
- */
-$EXT->_call_hook('pre_controller');
-
-/*
- * ------------------------------------------------------
- * Instantiate the controller and call requested method
- * ------------------------------------------------------
- */
-
-// Mark a start point so we can benchmark the controller
-$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
-
-$CI = new $class();
-
-// Is this a scaffolding request?
-if ($RTR->scaffolding_request === TRUE)
-{
- if ($EXT->_call_hook('scaffolding_override') === FALSE)
- {
- $CI->_ci_scaffolding();
- }
-}
-else
-{
- /*
- * ------------------------------------------------------
- * Is there a "post_controller_constructor" hook?
- * ------------------------------------------------------
- */
- $EXT->_call_hook('post_controller_constructor');
-
- // Is there a "remap" function?
- if (method_exists($CI, '_remap'))
- {
- $CI->_remap($method);
- }
- else
- {
- // is_callable() returns TRUE on some versions of PHP 5 for private and protected
- // methods, so we'll use this workaround for consistent behavior
- if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
- {
- show_404("{$class}/{$method}");
- }
-
- // Call the requested method.
- // Any URI segments present (besides the class/function) will be passed to the method for convenience
- call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
- }
-}
-
-// Mark a benchmark end point
-$BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
-
-/*
- * ------------------------------------------------------
- * Is there a "post_controller" hook?
- * ------------------------------------------------------
- */
-$EXT->_call_hook('post_controller');
-
-/*
- * ------------------------------------------------------
- * Send the final rendered output to the browser
- * ------------------------------------------------------
- */
-
-if ($EXT->_call_hook('display_override') === FALSE)
-{
- $OUT->_display();
-}
-
-/*
- * ------------------------------------------------------
- * Is there a "post_system" hook?
- * ------------------------------------------------------
- */
-$EXT->_call_hook('post_system');
-
-/*
- * ------------------------------------------------------
- * Close the DB connection if one exists
- * ------------------------------------------------------
- */
-if (class_exists('CI_DB') AND isset($CI->db))
-{
- $CI->db->close();
-}
-
-
-/* End of file CodeIgniter.php */
-/* Location: ./system/codeigniter/CodeIgniter.php */
\ No newline at end of file
diff --git a/system/codeigniter/Common.php b/system/codeigniter/Common.php
deleted file mode 100644
index eb9dce64..00000000
--- a/system/codeigniter/Common.php
+++ /dev/null
@@ -1,421 +0,0 @@
- 5
-* we'll set a static variable.
-*
-* @access public
-* @param string
-* @return bool
-*/
-function is_php($version = '5.0.0')
-{
- static $_is_php;
- $version = (string)$version;
-
- if ( ! isset($_is_php[$version]))
- {
- $_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0) ? FALSE : TRUE;
- }
-
- return $_is_php[$version];
-}
-
-// ------------------------------------------------------------------------
-
-/**
- * Tests for file writability
- *
- * is_writable() returns TRUE on Windows servers when you really can't write to
- * the file, based on the read-only attribute. is_writable() is also unreliable
- * on Unix servers if safe_mode is on.
- *
- * @access private
- * @return void
- */
-function is_really_writable($file)
-{
- // If we're on a Unix server with safe_mode off we call is_writable
- if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
- {
- return is_writable($file);
- }
-
- // For windows servers and safe_mode "on" installations we'll actually
- // write a file then read it. Bah...
- if (is_dir($file))
- {
- $file = rtrim($file, '/').'/'.md5(rand(1,100));
-
- if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
- {
- return FALSE;
- }
-
- fclose($fp);
- @chmod($file, DIR_WRITE_MODE);
- @unlink($file);
- return TRUE;
- }
- elseif (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
- {
- return FALSE;
- }
-
- fclose($fp);
- return TRUE;
-}
-
-// ------------------------------------------------------------------------
-
-/**
-* Class registry
-*
-* This function acts as a singleton. If the requested class does not
-* exist it is instantiated and set to a static variable. If it has
-* previously been instantiated the variable is returned.
-*
-* @access public
-* @param string the class name being requested
-* @param bool optional flag that lets classes get loaded but not instantiated
-* @return object
-*/
-function &load_class($class, $instantiate = TRUE)
-{
- static $objects = array();
-
- // Does the class exist? If so, we're done...
- if (isset($objects[$class]))
- {
- return $objects[$class];
- }
-
- // If the requested class does not exist in the application/libraries
- // folder we'll load the native class from the system/libraries folder.
- if (file_exists(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT))
- {
- require(BASEPATH.'libraries/'.$class.EXT);
- require(APPPATH.'libraries/'.config_item('subclass_prefix').$class.EXT);
- $is_subclass = TRUE;
- }
- else
- {
- if (file_exists(APPPATH.'libraries/'.$class.EXT))
- {
- require(APPPATH.'libraries/'.$class.EXT);
- $is_subclass = FALSE;
- }
- else
- {
- require(BASEPATH.'libraries/'.$class.EXT);
- $is_subclass = FALSE;
- }
- }
-
- if ($instantiate == FALSE)
- {
- $objects[$class] = TRUE;
- return $objects[$class];
- }
-
- if ($is_subclass == TRUE)
- {
- $name = config_item('subclass_prefix').$class;
-
- $objects[$class] =& instantiate_class(new $name());
- return $objects[$class];
- }
-
- $name = ($class != 'Controller') ? 'CI_'.$class : $class;
-
- $objects[$class] =& instantiate_class(new $name());
- return $objects[$class];
-}
-
-/**
- * Instantiate Class
- *
- * Returns a new class object by reference, used by load_class() and the DB class.
- * Required to retain PHP 4 compatibility and also not make PHP 5.3 cry.
- *
- * Use: $obj =& instantiate_class(new Foo());
- *
- * @access public
- * @param object
- * @return object
- */
-function &instantiate_class(&$class_object)
-{
- return $class_object;
-}
-
-/**
-* Loads the main config.php file
-*
-* @access private
-* @return array
-*/
-function &get_config()
-{
- static $main_conf;
-
- if ( ! isset($main_conf))
- {
- if ( ! file_exists(APPPATH.'config/config'.EXT))
- {
- exit('The configuration file config'.EXT.' does not exist.');
- }
-
- require(APPPATH.'config/config'.EXT);
-
- if ( ! isset($config) OR ! is_array($config))
- {
- exit('Your config file does not appear to be formatted correctly.');
- }
-
- $main_conf[0] =& $config;
- }
- return $main_conf[0];
-}
-
-/**
-* Gets a config item
-*
-* @access public
-* @return mixed
-*/
-function config_item($item)
-{
- static $config_item = array();
-
- if ( ! isset($config_item[$item]))
- {
- $config =& get_config();
-
- if ( ! isset($config[$item]))
- {
- return FALSE;
- }
- $config_item[$item] = $config[$item];
- }
-
- return $config_item[$item];
-}
-
-
-/**
-* Error Handler
-*
-* This function lets us invoke the exception class and
-* display errors using the standard error template located
-* in application/errors/errors.php
-* This function will send the error page directly to the
-* browser and exit.
-*
-* @access public
-* @return void
-*/
-function show_error($message, $status_code = 500)
-{
- $error =& load_class('Exceptions');
- echo $error->show_error('An Error Was Encountered', $message, 'error_general', $status_code);
- exit;
-}
-
-
-/**
-* 404 Page Handler
-*
-* This function is similar to the show_error() function above
-* However, instead of the standard error template it displays
-* 404 errors.
-*
-* @access public
-* @return void
-*/
-function show_404($page = '')
-{
- $error =& load_class('Exceptions');
- $error->show_404($page);
- exit;
-}
-
-
-/**
-* Error Logging Interface
-*
-* We use this as a simple mechanism to access the logging
-* class and send messages to be logged.
-*
-* @access public
-* @return void
-*/
-function log_message($level = 'error', $message, $php_error = FALSE)
-{
- static $LOG;
-
- $config =& get_config();
- if ($config['log_threshold'] == 0)
- {
- return;
- }
-
- $LOG =& load_class('Log');
- $LOG->write_log($level, $message, $php_error);
-}
-
-
-/**
- * Set HTTP Status Header
- *
- * @access public
- * @param int the status code
- * @param string
- * @return void
- */
-function set_status_header($code = 200, $text = '')
-{
- $stati = array(
- 200 => 'OK',
- 201 => 'Created',
- 202 => 'Accepted',
- 203 => 'Non-Authoritative Information',
- 204 => 'No Content',
- 205 => 'Reset Content',
- 206 => 'Partial Content',
-
- 300 => 'Multiple Choices',
- 301 => 'Moved Permanently',
- 302 => 'Found',
- 304 => 'Not Modified',
- 305 => 'Use Proxy',
- 307 => 'Temporary Redirect',
-
- 400 => 'Bad Request',
- 401 => 'Unauthorized',
- 403 => 'Forbidden',
- 404 => 'Not Found',
- 405 => 'Method Not Allowed',
- 406 => 'Not Acceptable',
- 407 => 'Proxy Authentication Required',
- 408 => 'Request Timeout',
- 409 => 'Conflict',
- 410 => 'Gone',
- 411 => 'Length Required',
- 412 => 'Precondition Failed',
- 413 => 'Request Entity Too Large',
- 414 => 'Request-URI Too Long',
- 415 => 'Unsupported Media Type',
- 416 => 'Requested Range Not Satisfiable',
- 417 => 'Expectation Failed',
-
- 500 => 'Internal Server Error',
- 501 => 'Not Implemented',
- 502 => 'Bad Gateway',
- 503 => 'Service Unavailable',
- 504 => 'Gateway Timeout',
- 505 => 'HTTP Version Not Supported'
- );
-
- if ($code == '' OR ! is_numeric($code))
- {
- show_error('Status codes must be numeric', 500);
- }
-
- if (isset($stati[$code]) AND $text == '')
- {
- $text = $stati[$code];
- }
-
- if ($text == '')
- {
- show_error('No status text available. Please check your status code number or supply your own message text.', 500);
- }
-
- $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
-
- if (substr(php_sapi_name(), 0, 3) == 'cgi')
- {
- header("Status: {$code} {$text}", TRUE);
- }
- elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
- {
- header($server_protocol." {$code} {$text}", TRUE, $code);
- }
- else
- {
- header("HTTP/1.1 {$code} {$text}", TRUE, $code);
- }
-}
-
-
-/**
-* Exception Handler
-*
-* This is the custom exception handler that is declaired at the top
-* of Codeigniter.php. The main reason we use this is permit
-* PHP errors to be logged in our own log files since we may
-* not have access to server logs. Since this function
-* effectively intercepts PHP errors, however, we also need
-* to display errors based on the current error_reporting level.
-* We do that with the use of a PHP error template.
-*
-* @access private
-* @return void
-*/
-function _exception_handler($severity, $message, $filepath, $line)
-{
- // We don't bother with "strict" notices since they will fill up
- // the log file with information that isn't normally very
- // helpful. For example, if you are running PHP 5 and you
- // use version 4 style class functions (without prefixes
- // like "public", "private", etc.) you'll get notices telling
- // you that these have been deprecated.
-
- if ($severity == E_STRICT)
- {
- return;
- }
-
- $error =& load_class('Exceptions');
-
- // Should we display the error?
- // We'll get the current error_reporting level and add its bits
- // with the severity bits to find out.
-
- if (($severity & error_reporting()) == $severity)
- {
- $error->show_php_error($severity, $message, $filepath, $line);
- }
-
- // Should we log the error? No? We're done...
- $config =& get_config();
- if ($config['log_threshold'] == 0)
- {
- return;
- }
-
- $error->log_exception($severity, $message, $filepath, $line);
-}
-
-
-
-/* End of file Common.php */
-/* Location: ./system/codeigniter/Common.php */
\ No newline at end of file
diff --git a/system/codeigniter/Compat.php b/system/codeigniter/Compat.php
deleted file mode 100644
index 958ab4c0..00000000
--- a/system/codeigniter/Compat.php
+++ /dev/null
@@ -1,93 +0,0 @@
-marker[$point2] = microtime();
}
-
+
list($sm, $ss) = explode(' ', $this->marker[$point1]);
list($em, $es) = explode(' ', $this->marker[$point2]);
return number_format(($em + $es) - ($sm + $ss), $decimals);
}
-
+
// --------------------------------------------------------------------
/**
@@ -110,4 +115,4 @@ function memory_usage()
// END CI_Benchmark class
/* End of file Benchmark.php */
-/* Location: ./system/libraries/Benchmark.php */
\ No newline at end of file
+/* Location: ./system/core/Benchmark.php */
\ No newline at end of file
diff --git a/system/core/CodeIgniter.php b/system/core/CodeIgniter.php
new file mode 100755
index 00000000..e0819c80
--- /dev/null
+++ b/system/core/CodeIgniter.php
@@ -0,0 +1,402 @@
+ $assign_to_config['subclass_prefix']));
+ }
+
+/*
+ * ------------------------------------------------------
+ * Set a liberal script execution time limit
+ * ------------------------------------------------------
+ */
+ if (function_exists("set_time_limit") == TRUE AND @ini_get("safe_mode") == 0)
+ {
+ @set_time_limit(300);
+ }
+
+/*
+ * ------------------------------------------------------
+ * Start the timer... tick tock tick tock...
+ * ------------------------------------------------------
+ */
+ $BM =& load_class('Benchmark', 'core');
+ $BM->mark('total_execution_time_start');
+ $BM->mark('loading_time:_base_classes_start');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the hooks class
+ * ------------------------------------------------------
+ */
+ $EXT =& load_class('Hooks', 'core');
+
+/*
+ * ------------------------------------------------------
+ * Is there a "pre_system" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('pre_system');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the config class
+ * ------------------------------------------------------
+ */
+ $CFG =& load_class('Config', 'core');
+
+ // Do we have any manually set config items in the index.php file?
+ if (isset($assign_to_config))
+ {
+ $CFG->_assign_to_config($assign_to_config);
+ }
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the UTF-8 class
+ * ------------------------------------------------------
+ *
+ * Note: Order here is rather important as the UTF-8
+ * class needs to be used very early on, but it cannot
+ * properly determine if UTf-8 can be supported until
+ * after the Config class is instantiated.
+ *
+ */
+
+ $UNI =& load_class('Utf8', 'core');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the URI class
+ * ------------------------------------------------------
+ */
+ $URI =& load_class('URI', 'core');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the routing class and set the routing
+ * ------------------------------------------------------
+ */
+ $RTR =& load_class('Router', 'core');
+ $RTR->_set_routing();
+
+ // Set any routing overrides that may exist in the main index file
+ if (isset($routing))
+ {
+ $RTR->_set_overrides($routing);
+ }
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the output class
+ * ------------------------------------------------------
+ */
+ $OUT =& load_class('Output', 'core');
+
+/*
+ * ------------------------------------------------------
+ * Is there a valid cache file? If so, we're done...
+ * ------------------------------------------------------
+ */
+ if ($EXT->_call_hook('cache_override') === FALSE)
+ {
+ if ($OUT->_display_cache($CFG, $URI) == TRUE)
+ {
+ exit;
+ }
+ }
+
+/*
+ * -----------------------------------------------------
+ * Load the security class for xss and csrf support
+ * -----------------------------------------------------
+ */
+ $SEC =& load_class('Security', 'core');
+
+/*
+ * ------------------------------------------------------
+ * Load the Input class and sanitize globals
+ * ------------------------------------------------------
+ */
+ $IN =& load_class('Input', 'core');
+
+/*
+ * ------------------------------------------------------
+ * Load the Language class
+ * ------------------------------------------------------
+ */
+ $LANG =& load_class('Lang', 'core');
+
+/*
+ * ------------------------------------------------------
+ * Load the app controller and local controller
+ * ------------------------------------------------------
+ *
+ */
+ // Load the base controller class
+ require BASEPATH.'core/Controller.php';
+
+ function &get_instance()
+ {
+ return CI_Controller::get_instance();
+ }
+
+
+ if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
+ {
+ require APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
+ }
+
+ // Load the local application controller
+ // Note: The Router class automatically validates the controller path using the router->_validate_request().
+ // If this include fails it means that the default controller in the Routes.php file is not resolving to something valid.
+ if ( ! file_exists(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php'))
+ {
+ show_error('Unable to load your default controller. Please make sure the controller specified in your Routes.php file is valid.');
+ }
+
+ include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');
+
+ // Set a mark point for benchmarking
+ $BM->mark('loading_time:_base_classes_end');
+
+/*
+ * ------------------------------------------------------
+ * Security check
+ * ------------------------------------------------------
+ *
+ * None of the functions in the app controller or the
+ * loader class can be called via the URI, nor can
+ * controller functions that begin with an underscore
+ */
+ $class = $RTR->fetch_class();
+ $method = $RTR->fetch_method();
+
+ if ( ! class_exists($class)
+ OR strncmp($method, '_', 1) == 0
+ OR in_array(strtolower($method), array_map('strtolower', get_class_methods('CI_Controller')))
+ )
+ {
+ if ( ! empty($RTR->routes['404_override']))
+ {
+ $x = explode('/', $RTR->routes['404_override']);
+ $class = $x[0];
+ $method = (isset($x[1]) ? $x[1] : 'index');
+ if ( ! class_exists($class))
+ {
+ if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
+ {
+ show_404("{$class}/{$method}");
+ }
+
+ include_once(APPPATH.'controllers/'.$class.'.php');
+ }
+ }
+ else
+ {
+ show_404("{$class}/{$method}");
+ }
+ }
+
+/*
+ * ------------------------------------------------------
+ * Is there a "pre_controller" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('pre_controller');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the requested controller
+ * ------------------------------------------------------
+ */
+ // Mark a start point so we can benchmark the controller
+ $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_start');
+
+ $CI = new $class();
+
+/*
+ * ------------------------------------------------------
+ * Is there a "post_controller_constructor" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('post_controller_constructor');
+
+/*
+ * ------------------------------------------------------
+ * Call the requested method
+ * ------------------------------------------------------
+ */
+ // Is there a "remap" function? If so, we call it instead
+ if (method_exists($CI, '_remap'))
+ {
+ $CI->_remap($method, array_slice($URI->rsegments, 2));
+ }
+ else
+ {
+ // is_callable() returns TRUE on some versions of PHP 5 for private and protected
+ // methods, so we'll use this workaround for consistent behavior
+ if ( ! in_array(strtolower($method), array_map('strtolower', get_class_methods($CI))))
+ {
+ // Check and see if we are using a 404 override and use it.
+ if ( ! empty($RTR->routes['404_override']))
+ {
+ $x = explode('/', $RTR->routes['404_override']);
+ $class = $x[0];
+ $method = (isset($x[1]) ? $x[1] : 'index');
+ if ( ! class_exists($class))
+ {
+ if ( ! file_exists(APPPATH.'controllers/'.$class.'.php'))
+ {
+ show_404("{$class}/{$method}");
+ }
+
+ include_once(APPPATH.'controllers/'.$class.'.php');
+ unset($CI);
+ $CI = new $class();
+ }
+ }
+ else
+ {
+ show_404("{$class}/{$method}");
+ }
+ }
+
+ // Call the requested method.
+ // Any URI segments present (besides the class/function) will be passed to the method for convenience
+ call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));
+ }
+
+
+ // Mark a benchmark end point
+ $BM->mark('controller_execution_time_( '.$class.' / '.$method.' )_end');
+
+/*
+ * ------------------------------------------------------
+ * Is there a "post_controller" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('post_controller');
+
+/*
+ * ------------------------------------------------------
+ * Send the final rendered output to the browser
+ * ------------------------------------------------------
+ */
+ if ($EXT->_call_hook('display_override') === FALSE)
+ {
+ $OUT->_display();
+ }
+
+/*
+ * ------------------------------------------------------
+ * Is there a "post_system" hook?
+ * ------------------------------------------------------
+ */
+ $EXT->_call_hook('post_system');
+
+/*
+ * ------------------------------------------------------
+ * Close the DB connection if one exists
+ * ------------------------------------------------------
+ */
+ if (class_exists('CI_DB') AND isset($CI->db))
+ {
+ $CI->db->close();
+ }
+
+
+/* End of file CodeIgniter.php */
+/* Location: ./system/core/CodeIgniter.php */
\ No newline at end of file
diff --git a/system/core/Common.php b/system/core/Common.php
new file mode 100644
index 00000000..07534c51
--- /dev/null
+++ b/system/core/Common.php
@@ -0,0 +1,564 @@
+ 5
+* we'll set a static variable.
+*
+* @access public
+* @param string
+* @return bool TRUE if the current version is $version or higher
+*/
+if ( ! function_exists('is_php'))
+{
+ function is_php($version = '5.0.0')
+ {
+ static $_is_php;
+ $version = (string)$version;
+
+ if ( ! isset($_is_php[$version]))
+ {
+ $_is_php[$version] = (version_compare(PHP_VERSION, $version) < 0) ? FALSE : TRUE;
+ }
+
+ return $_is_php[$version];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Tests for file writability
+ *
+ * is_writable() returns TRUE on Windows servers when you really can't write to
+ * the file, based on the read-only attribute. is_writable() is also unreliable
+ * on Unix servers if safe_mode is on.
+ *
+ * @access private
+ * @return void
+ */
+if ( ! function_exists('is_really_writable'))
+{
+ function is_really_writable($file)
+ {
+ // If we're on a Unix server with safe_mode off we call is_writable
+ if (DIRECTORY_SEPARATOR == '/' AND @ini_get("safe_mode") == FALSE)
+ {
+ return is_writable($file);
+ }
+
+ // For windows servers and safe_mode "on" installations we'll actually
+ // write a file then read it. Bah...
+ if (is_dir($file))
+ {
+ $file = rtrim($file, '/').'/'.md5(mt_rand(1,100).mt_rand(1,100));
+
+ if (($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ fclose($fp);
+ @chmod($file, DIR_WRITE_MODE);
+ @unlink($file);
+ return TRUE;
+ }
+ elseif ( ! is_file($file) OR ($fp = @fopen($file, FOPEN_WRITE_CREATE)) === FALSE)
+ {
+ return FALSE;
+ }
+
+ fclose($fp);
+ return TRUE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* Class registry
+*
+* This function acts as a singleton. If the requested class does not
+* exist it is instantiated and set to a static variable. If it has
+* previously been instantiated the variable is returned.
+*
+* @access public
+* @param string the class name being requested
+* @param string the directory where the class should be found
+* @param string the class name prefix
+* @return object
+*/
+if ( ! function_exists('load_class'))
+{
+ function &load_class($class, $directory = 'libraries', $prefix = 'CI_')
+ {
+ static $_classes = array();
+
+ // Does the class exist? If so, we're done...
+ if (isset($_classes[$class]))
+ {
+ return $_classes[$class];
+ }
+
+ $name = FALSE;
+
+ // Look for the class first in the local application/libraries folder
+ // then in the native system/libraries folder
+ foreach (array(APPPATH, BASEPATH) as $path)
+ {
+ if (file_exists($path.$directory.'/'.$class.'.php'))
+ {
+ $name = $prefix.$class;
+
+ if (class_exists($name) === FALSE)
+ {
+ require($path.$directory.'/'.$class.'.php');
+ }
+
+ break;
+ }
+ }
+
+ // Is the request a class extension? If so we load it too
+ if (file_exists(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php'))
+ {
+ $name = config_item('subclass_prefix').$class;
+
+ if (class_exists($name) === FALSE)
+ {
+ require(APPPATH.$directory.'/'.config_item('subclass_prefix').$class.'.php');
+ }
+ }
+
+ // Did we find the class?
+ if ($name === FALSE)
+ {
+ // Note: We use exit() rather then show_error() in order to avoid a
+ // self-referencing loop with the Excptions class
+ exit('Unable to locate the specified class: '.$class.'.php');
+ }
+
+ // Keep track of what we just loaded
+ is_loaded($class);
+
+ $_classes[$class] = new $name();
+ return $_classes[$class];
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+* Keeps track of which libraries have been loaded. This function is
+* called by the load_class() function above
+*
+* @access public
+* @return array
+*/
+if ( ! function_exists('is_loaded'))
+{
+ function &is_loaded($class = '')
+ {
+ static $_is_loaded = array();
+
+ if ($class != '')
+ {
+ $_is_loaded[strtolower($class)] = $class;
+ }
+
+ return $_is_loaded;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* Loads the main config.php file
+*
+* This function lets us grab the config file even if the Config class
+* hasn't been instantiated yet
+*
+* @access private
+* @return array
+*/
+if ( ! function_exists('get_config'))
+{
+ function &get_config($replace = array())
+ {
+ static $_config;
+
+ if (isset($_config))
+ {
+ return $_config[0];
+ }
+
+ // Is the config file in the environment folder?
+ if ( ! defined('ENVIRONMENT') OR ! file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
+ {
+ $file_path = APPPATH.'config/config.php';
+ }
+
+ // Fetch the config file
+ if ( ! file_exists($file_path))
+ {
+ exit('The configuration file does not exist.');
+ }
+
+ require($file_path);
+
+ // Does the $config array exist in the file?
+ if ( ! isset($config) OR ! is_array($config))
+ {
+ exit('Your config file does not appear to be formatted correctly.');
+ }
+
+ // Are any values being dynamically replaced?
+ if (count($replace) > 0)
+ {
+ foreach ($replace as $key => $val)
+ {
+ if (isset($config[$key]))
+ {
+ $config[$key] = $val;
+ }
+ }
+ }
+
+ return $_config[0] =& $config;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* Returns the specified config item
+*
+* @access public
+* @return mixed
+*/
+if ( ! function_exists('config_item'))
+{
+ function config_item($item)
+ {
+ static $_config_item = array();
+
+ if ( ! isset($_config_item[$item]))
+ {
+ $config =& get_config();
+
+ if ( ! isset($config[$item]))
+ {
+ return FALSE;
+ }
+ $_config_item[$item] = $config[$item];
+ }
+
+ return $_config_item[$item];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* Error Handler
+*
+* This function lets us invoke the exception class and
+* display errors using the standard error template located
+* in application/errors/errors.php
+* This function will send the error page directly to the
+* browser and exit.
+*
+* @access public
+* @return void
+*/
+if ( ! function_exists('show_error'))
+{
+ function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
+ {
+ $_error =& load_class('Exceptions', 'core');
+ echo $_error->show_error($heading, $message, 'error_general', $status_code);
+ exit;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* 404 Page Handler
+*
+* This function is similar to the show_error() function above
+* However, instead of the standard error template it displays
+* 404 errors.
+*
+* @access public
+* @return void
+*/
+if ( ! function_exists('show_404'))
+{
+ function show_404($page = '', $log_error = TRUE)
+ {
+ $_error =& load_class('Exceptions', 'core');
+ $_error->show_404($page, $log_error);
+ exit;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* Error Logging Interface
+*
+* We use this as a simple mechanism to access the logging
+* class and send messages to be logged.
+*
+* @access public
+* @return void
+*/
+if ( ! function_exists('log_message'))
+{
+ function log_message($level = 'error', $message, $php_error = FALSE)
+ {
+ static $_log;
+
+ if (config_item('log_threshold') == 0)
+ {
+ return;
+ }
+
+ $_log =& load_class('Log');
+ $_log->write_log($level, $message, $php_error);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+ * Set HTTP Status Header
+ *
+ * @access public
+ * @param int the status code
+ * @param string
+ * @return void
+ */
+if ( ! function_exists('set_status_header'))
+{
+ function set_status_header($code = 200, $text = '')
+ {
+ $stati = array(
+ 200 => 'OK',
+ 201 => 'Created',
+ 202 => 'Accepted',
+ 203 => 'Non-Authoritative Information',
+ 204 => 'No Content',
+ 205 => 'Reset Content',
+ 206 => 'Partial Content',
+
+ 300 => 'Multiple Choices',
+ 301 => 'Moved Permanently',
+ 302 => 'Found',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 403 => 'Forbidden',
+ 404 => 'Not Found',
+ 405 => 'Method Not Allowed',
+ 406 => 'Not Acceptable',
+ 407 => 'Proxy Authentication Required',
+ 408 => 'Request Timeout',
+ 409 => 'Conflict',
+ 410 => 'Gone',
+ 411 => 'Length Required',
+ 412 => 'Precondition Failed',
+ 413 => 'Request Entity Too Large',
+ 414 => 'Request-URI Too Long',
+ 415 => 'Unsupported Media Type',
+ 416 => 'Requested Range Not Satisfiable',
+ 417 => 'Expectation Failed',
+
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported'
+ );
+
+ if ($code == '' OR ! is_numeric($code))
+ {
+ show_error('Status codes must be numeric', 500);
+ }
+
+ if (isset($stati[$code]) AND $text == '')
+ {
+ $text = $stati[$code];
+ }
+
+ if ($text == '')
+ {
+ show_error('No status text available. Please check your status code number or supply your own message text.', 500);
+ }
+
+ $server_protocol = (isset($_SERVER['SERVER_PROTOCOL'])) ? $_SERVER['SERVER_PROTOCOL'] : FALSE;
+
+ if (substr(php_sapi_name(), 0, 3) == 'cgi')
+ {
+ header("Status: {$code} {$text}", TRUE);
+ }
+ elseif ($server_protocol == 'HTTP/1.1' OR $server_protocol == 'HTTP/1.0')
+ {
+ header($server_protocol." {$code} {$text}", TRUE, $code);
+ }
+ else
+ {
+ header("HTTP/1.1 {$code} {$text}", TRUE, $code);
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+* Exception Handler
+*
+* This is the custom exception handler that is declaired at the top
+* of Codeigniter.php. The main reason we use this is to permit
+* PHP errors to be logged in our own log files since the user may
+* not have access to server logs. Since this function
+* effectively intercepts PHP errors, however, we also need
+* to display errors based on the current error_reporting level.
+* We do that with the use of a PHP error template.
+*
+* @access private
+* @return void
+*/
+if ( ! function_exists('_exception_handler'))
+{
+ function _exception_handler($severity, $message, $filepath, $line)
+ {
+ // We don't bother with "strict" notices since they tend to fill up
+ // the log file with excess information that isn't normally very helpful.
+ // For example, if you are running PHP 5 and you use version 4 style
+ // class functions (without prefixes like "public", "private", etc.)
+ // you'll get notices telling you that these have been deprecated.
+ if ($severity == E_STRICT)
+ {
+ return;
+ }
+
+ $_error =& load_class('Exceptions', 'core');
+
+ // Should we display the error? We'll get the current error_reporting
+ // level and add its bits with the severity bits to find out.
+ if (($severity & error_reporting()) == $severity)
+ {
+ $_error->show_php_error($severity, $message, $filepath, $line);
+ }
+
+ // Should we log the error? No? We're done...
+ if (config_item('log_threshold') == 0)
+ {
+ return;
+ }
+
+ $_error->log_exception($severity, $message, $filepath, $line);
+ }
+}
+
+// --------------------------------------------------------------------
+
+/**
+ * Remove Invisible Characters
+ *
+ * This prevents sandwiching null characters
+ * between ascii characters, like Java\0script.
+ *
+ * @access public
+ * @param string
+ * @return string
+ */
+if ( ! function_exists('remove_invisible_characters'))
+{
+ function remove_invisible_characters($str, $url_encoded = TRUE)
+ {
+ $non_displayables = array();
+
+ // every control character except newline (dec 10)
+ // carriage return (dec 13), and horizontal tab (dec 09)
+
+ if ($url_encoded)
+ {
+ $non_displayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15
+ $non_displayables[] = '/%1[0-9a-f]/'; // url encoded 16-31
+ }
+
+ $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127
+
+ do
+ {
+ $str = preg_replace($non_displayables, '', $str, -1, $count);
+ }
+ while ($count);
+
+ return $str;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+/**
+* Returns HTML escaped variable
+*
+* @access public
+* @param mixed
+* @return mixed
+*/
+if ( ! function_exists('html_escape'))
+{
+ function html_escape($var)
+ {
+ if (is_array($var))
+ {
+ return array_map('html_escape', $var);
+ }
+ else
+ {
+ return htmlspecialchars($var, ENT_QUOTES, config_item('charset'));
+ }
+ }
+}
+
+/* End of file Common.php */
+/* Location: ./system/core/Common.php */
\ No newline at end of file
diff --git a/system/core/Config.php b/system/core/Config.php
new file mode 100755
index 00000000..5dffbf3f
--- /dev/null
+++ b/system/core/Config.php
@@ -0,0 +1,379 @@
+config =& get_config();
+ log_message('debug', "Config Class Initialized");
+
+ // Set the base_url automatically if none was provided
+ if ($this->config['base_url'] == '')
+ {
+ if (isset($_SERVER['HTTP_HOST']))
+ {
+ $base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
+ $base_url .= '://'. $_SERVER['HTTP_HOST'];
+ $base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']);
+ }
+
+ else
+ {
+ $base_url = 'http://localhost/';
+ }
+
+ $this->set_item('base_url', $base_url);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Load Config File
+ *
+ * @access public
+ * @param string the config file name
+ * @param boolean if configuration values should be loaded into their own section
+ * @param boolean true if errors should just return false, false if an error message should be displayed
+ * @return boolean if the file was loaded correctly
+ */
+ function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
+ {
+ $file = ($file == '') ? 'config' : str_replace('.php', '', $file);
+ $found = FALSE;
+ $loaded = FALSE;
+
+ $check_locations = defined('ENVIRONMENT')
+ ? array(ENVIRONMENT.'/'.$file, $file)
+ : array($file);
+
+ foreach ($this->_config_paths as $path)
+ {
+ foreach ($check_locations as $location)
+ {
+ $file_path = $path.'config/'.$location.'.php';
+
+ if (in_array($file_path, $this->is_loaded, TRUE))
+ {
+ $loaded = TRUE;
+ continue 2;
+ }
+
+ if (file_exists($file_path))
+ {
+ $found = TRUE;
+ break;
+ }
+ }
+
+ if ($found === FALSE)
+ {
+ continue;
+ }
+
+ include($file_path);
+
+ if ( ! isset($config) OR ! is_array($config))
+ {
+ if ($fail_gracefully === TRUE)
+ {
+ return FALSE;
+ }
+ show_error('Your '.$file_path.' file does not appear to contain a valid configuration array.');
+ }
+
+ if ($use_sections === TRUE)
+ {
+ if (isset($this->config[$file]))
+ {
+ $this->config[$file] = array_merge($this->config[$file], $config);
+ }
+ else
+ {
+ $this->config[$file] = $config;
+ }
+ }
+ else
+ {
+ $this->config = array_merge($this->config, $config);
+ }
+
+ $this->is_loaded[] = $file_path;
+ unset($config);
+
+ $loaded = TRUE;
+ log_message('debug', 'Config file loaded: '.$file_path);
+ break;
+ }
+
+ if ($loaded === FALSE)
+ {
+ if ($fail_gracefully === TRUE)
+ {
+ return FALSE;
+ }
+ show_error('The configuration file '.$file.'.php does not exist.');
+ }
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch a config file item
+ *
+ *
+ * @access public
+ * @param string the config item name
+ * @param string the index name
+ * @param bool
+ * @return string
+ */
+ function item($item, $index = '')
+ {
+ if ($index == '')
+ {
+ if ( ! isset($this->config[$item]))
+ {
+ return FALSE;
+ }
+
+ $pref = $this->config[$item];
+ }
+ else
+ {
+ if ( ! isset($this->config[$index]))
+ {
+ return FALSE;
+ }
+
+ if ( ! isset($this->config[$index][$item]))
+ {
+ return FALSE;
+ }
+
+ $pref = $this->config[$index][$item];
+ }
+
+ return $pref;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch a config file item - adds slash after item (if item is not empty)
+ *
+ * @access public
+ * @param string the config item name
+ * @param bool
+ * @return string
+ */
+ function slash_item($item)
+ {
+ if ( ! isset($this->config[$item]))
+ {
+ return FALSE;
+ }
+ if( trim($this->config[$item]) == '')
+ {
+ return '';
+ }
+
+ return rtrim($this->config[$item], '/').'/';
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Site URL
+ * Returns base_url . index_page [. uri_string]
+ *
+ * @access public
+ * @param string the URI string
+ * @return string
+ */
+ function site_url($uri = '')
+ {
+ if ($uri == '')
+ {
+ return $this->slash_item('base_url').$this->item('index_page');
+ }
+
+ if ($this->item('enable_query_strings') == FALSE)
+ {
+ $suffix = ($this->item('url_suffix') == FALSE) ? '' : $this->item('url_suffix');
+ return $this->slash_item('base_url').$this->slash_item('index_page').$this->_uri_string($uri).$suffix;
+ }
+ else
+ {
+ return $this->slash_item('base_url').$this->item('index_page').'?'.$this->_uri_string($uri);
+ }
+ }
+
+ // -------------------------------------------------------------
+
+ /**
+ * Base URL
+ * Returns base_url [. uri_string]
+ *
+ * @access public
+ * @param string $uri
+ * @return string
+ */
+ function base_url($uri = '')
+ {
+ return $this->slash_item('base_url').ltrim($this->_uri_string($uri), '/');
+ }
+
+ // -------------------------------------------------------------
+
+ /**
+ * Build URI string for use in Config::site_url() and Config::base_url()
+ *
+ * @access protected
+ * @param $uri
+ * @return string
+ */
+ protected function _uri_string($uri)
+ {
+ if ($this->item('enable_query_strings') == FALSE)
+ {
+ if (is_array($uri))
+ {
+ $uri = implode('/', $uri);
+ }
+ $uri = trim($uri, '/');
+ }
+ else
+ {
+ if (is_array($uri))
+ {
+ $i = 0;
+ $str = '';
+ foreach ($uri as $key => $val)
+ {
+ $prefix = ($i == 0) ? '' : '&';
+ $str .= $prefix.$key.'='.$val;
+ $i++;
+ }
+ $uri = $str;
+ }
+ }
+ return $uri;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * System URL
+ *
+ * @access public
+ * @return string
+ */
+ function system_url()
+ {
+ $x = explode("/", preg_replace("|/*(.+?)/*$|", "\\1", BASEPATH));
+ return $this->slash_item('base_url').end($x).'/';
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set a config file item
+ *
+ * @access public
+ * @param string the config item key
+ * @param string the config item value
+ * @return void
+ */
+ function set_item($item, $value)
+ {
+ $this->config[$item] = $value;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Assign to Config
+ *
+ * This function is called by the front controller (CodeIgniter.php)
+ * after the Config class is instantiated. It permits config items
+ * to be assigned or overriden by variables contained in the index.php file
+ *
+ * @access private
+ * @param array
+ * @return void
+ */
+ function _assign_to_config($items = array())
+ {
+ if (is_array($items))
+ {
+ foreach ($items as $key => $val)
+ {
+ $this->set_item($key, $val);
+ }
+ }
+ }
+}
+
+// END CI_Config class
+
+/* End of file Config.php */
+/* Location: ./system/core/Config.php */
diff --git a/system/core/Controller.php b/system/core/Controller.php
new file mode 100644
index 00000000..fddb81e1
--- /dev/null
+++ b/system/core/Controller.php
@@ -0,0 +1,64 @@
+ $class)
+ {
+ $this->$var =& load_class($class);
+ }
+
+ $this->load =& load_class('Loader', 'core');
+
+ $this->load->initialize();
+
+ log_message('debug', "Controller Class Initialized");
+ }
+
+ public static function &get_instance()
+ {
+ return self::$instance;
+ }
+}
+// END Controller class
+
+/* End of file Controller.php */
+/* Location: ./system/core/Controller.php */
\ No newline at end of file
diff --git a/system/libraries/Exceptions.php b/system/core/Exceptions.php
old mode 100644
new mode 100755
similarity index 82%
rename from system/libraries/Exceptions.php
rename to system/core/Exceptions.php
index 9c655a17..869739a5
--- a/system/libraries/Exceptions.php
+++ b/system/core/Exceptions.php
@@ -2,11 +2,11 @@
/**
* CodeIgniter
*
- * An open source application development framework for PHP 4.3.2 or newer
+ * An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
- * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
@@ -30,8 +30,21 @@ class CI_Exceptions {
var $message;
var $filename;
var $line;
+
+ /**
+ * Nesting level of the output buffering mechanism
+ *
+ * @var int
+ * @access public
+ */
var $ob_level;
+ /**
+ * List if available error levels
+ *
+ * @var array
+ * @access public
+ */
var $levels = array(
E_ERROR => 'Error',
E_WARNING => 'Warning',
@@ -50,14 +63,13 @@ class CI_Exceptions {
/**
* Constructor
- *
- */
- function CI_Exceptions()
+ */
+ public function __construct()
{
$this->ob_level = ob_get_level();
// Note: Do not log messages from this constructor.
}
-
+
// --------------------------------------------------------------------
/**
@@ -73,9 +85,9 @@ function CI_Exceptions()
* @return string
*/
function log_exception($severity, $message, $filepath, $line)
- {
+ {
$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
-
+
log_message('error', 'Severity: '.$severity.' --> '.$message. ' '.$filepath.' '.$line, TRUE);
}
@@ -85,19 +97,25 @@ function log_exception($severity, $message, $filepath, $line)
* 404 Page Not Found Handler
*
* @access private
- * @param string
+ * @param string the page
+ * @param bool log error yes/no
* @return string
*/
- function show_404($page = '')
- {
+ function show_404($page = '', $log_error = TRUE)
+ {
$heading = "404 Page Not Found";
$message = "The page you requested was not found.";
- log_message('error', '404 Page Not Found --> '.$page);
+ // By default we log this, but allow a dev to skip it
+ if ($log_error)
+ {
+ log_message('error', '404 Page Not Found --> '.$page);
+ }
+
echo $this->show_error($heading, $message, 'error_404', 404);
exit;
}
-
+
// --------------------------------------------------------------------
/**
@@ -111,20 +129,21 @@ function show_404($page = '')
* @param string the heading
* @param string the message
* @param string the template name
+ * @param int the status code
* @return string
*/
function show_error($heading, $message, $template = 'error_general', $status_code = 500)
{
set_status_header($status_code);
-
+
$message = ''.implode('
', ( ! is_array($message)) ? array($message) : $message).'
';
if (ob_get_level() > $this->ob_level + 1)
{
- ob_end_flush();
+ ob_end_flush();
}
ob_start();
- include(APPPATH.'errors/'.$template.EXT);
+ include(APPPATH.'errors/'.$template.'.php');
$buffer = ob_get_contents();
ob_end_clean();
return $buffer;
@@ -143,24 +162,24 @@ function show_error($heading, $message, $template = 'error_general', $status_cod
* @return string
*/
function show_php_error($severity, $message, $filepath, $line)
- {
+ {
$severity = ( ! isset($this->levels[$severity])) ? $severity : $this->levels[$severity];
-
+
$filepath = str_replace("\\", "/", $filepath);
-
+
// For safety reasons we do not show the full file path
if (FALSE !== strpos($filepath, '/'))
{
$x = explode('/', $filepath);
$filepath = $x[count($x)-2].'/'.end($x);
}
-
+
if (ob_get_level() > $this->ob_level + 1)
{
- ob_end_flush();
+ ob_end_flush();
}
ob_start();
- include(APPPATH.'errors/error_php'.EXT);
+ include(APPPATH.'errors/error_php.php');
$buffer = ob_get_contents();
ob_end_clean();
echo $buffer;
@@ -171,4 +190,4 @@ function show_php_error($severity, $message, $filepath, $line)
// END Exceptions Class
/* End of file Exceptions.php */
-/* Location: ./system/libraries/Exceptions.php */
\ No newline at end of file
+/* Location: ./system/core/Exceptions.php */
\ No newline at end of file
diff --git a/system/libraries/Hooks.php b/system/core/Hooks.php
old mode 100644
new mode 100755
similarity index 82%
rename from system/libraries/Hooks.php
rename to system/core/Hooks.php
index 0b5d4680..33f1c034
--- a/system/libraries/Hooks.php
+++ b/system/core/Hooks.php
@@ -2,11 +2,11 @@
/**
* CodeIgniter
*
- * An open source application development framework for PHP 4.3.2 or newer
+ * An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
- * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
@@ -18,8 +18,7 @@
/**
* CodeIgniter Hooks Class
*
- * Provides a mechanism to extend the base system without hacking. Most of
- * this class is borrowed from Paul's Extension class in ExpressionEngine.
+ * Provides a mechanism to extend the base system without hacking.
*
* @package CodeIgniter
* @subpackage Libraries
@@ -29,20 +28,35 @@
*/
class CI_Hooks {
- var $enabled = FALSE;
- var $hooks = array();
+ /**
+ * Determines wether hooks are enabled
+ *
+ * @var bool
+ */
+ var $enabled = FALSE;
+ /**
+ * List of all hooks set in config/hooks.php
+ *
+ * @var array
+ */
+ var $hooks = array();
+ /**
+ * Determines wether hook is in progress, used to prevent infinte loops
+ *
+ * @var bool
+ */
var $in_progress = FALSE;
/**
* Constructor
*
*/
- function CI_Hooks()
+ function __construct()
{
$this->_initialize();
log_message('debug', "Hooks Class Initialized");
}
-
+
// --------------------------------------------------------------------
/**
@@ -50,10 +64,10 @@ function CI_Hooks()
*
* @access private
* @return void
- */
- function _initialize()
- {
- $CFG =& load_class('Config');
+ */
+ function _initialize()
+ {
+ $CFG =& load_class('Config', 'core');
// If hooks are not enabled in the config file
// there is nothing else to do
@@ -66,7 +80,15 @@ function _initialize()
// Grab the "hooks" definition file.
// If there are no hooks, we're done.
- @include(APPPATH.'config/hooks'.EXT);
+ if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
+ {
+ include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
+ }
+ elseif (is_file(APPPATH.'config/hooks.php'))
+ {
+ include(APPPATH.'config/hooks.php');
+ }
+
if ( ! isset($hook) OR ! is_array($hook))
{
@@ -75,8 +97,8 @@ function _initialize()
$this->hooks =& $hook;
$this->enabled = TRUE;
- }
-
+ }
+
// --------------------------------------------------------------------
/**
@@ -223,4 +245,4 @@ function _run_hook($data)
// END CI_Hooks class
/* End of file Hooks.php */
-/* Location: ./system/libraries/Hooks.php */
\ No newline at end of file
+/* Location: ./system/core/Hooks.php */
\ No newline at end of file
diff --git a/system/core/Input.php b/system/core/Input.php
new file mode 100755
index 00000000..0c1f2b08
--- /dev/null
+++ b/system/core/Input.php
@@ -0,0 +1,849 @@
+_allow_get_array = (config_item('allow_get_array') === TRUE);
+ $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
+ $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
+
+ global $SEC;
+ $this->security =& $SEC;
+
+ // Do we need the UTF-8 class?
+ if (UTF8_ENABLED === TRUE)
+ {
+ global $UNI;
+ $this->uni =& $UNI;
+ }
+
+ // Sanitize global arrays
+ $this->_sanitize_globals();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch from array
+ *
+ * This is a helper function to retrieve values from global arrays
+ *
+ * @access private
+ * @param array
+ * @param string
+ * @param bool
+ * @return string
+ */
+ function _fetch_from_array(&$array, $index = '', $xss_clean = FALSE)
+ {
+ if ( ! isset($array[$index]))
+ {
+ return FALSE;
+ }
+
+ if ($xss_clean === TRUE)
+ {
+ return $this->security->xss_clean($array[$index]);
+ }
+
+ return $array[$index];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the GET array
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return string
+ */
+ function get($index = NULL, $xss_clean = FALSE)
+ {
+ // Check if a field has been provided
+ if ($index === NULL AND ! empty($_GET))
+ {
+ $get = array();
+
+ // loop through the full _GET array
+ foreach (array_keys($_GET) as $key)
+ {
+ $get[$key] = $this->_fetch_from_array($_GET, $key, $xss_clean);
+ }
+ return $get;
+ }
+
+ return $this->_fetch_from_array($_GET, $index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the POST array
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return string
+ */
+ function post($index = NULL, $xss_clean = FALSE)
+ {
+ // Check if a field has been provided
+ if ($index === NULL AND ! empty($_POST))
+ {
+ $post = array();
+
+ // Loop through the full _POST array and return it
+ foreach (array_keys($_POST) as $key)
+ {
+ $post[$key] = $this->_fetch_from_array($_POST, $key, $xss_clean);
+ }
+ return $post;
+ }
+
+ return $this->_fetch_from_array($_POST, $index, $xss_clean);
+ }
+
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from either the GET array or the POST
+ *
+ * @access public
+ * @param string The index key
+ * @param bool XSS cleaning
+ * @return string
+ */
+ function get_post($index = '', $xss_clean = FALSE)
+ {
+ if ( ! isset($_POST[$index]) )
+ {
+ return $this->get($index, $xss_clean);
+ }
+ else
+ {
+ return $this->post($index, $xss_clean);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the COOKIE array
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return string
+ */
+ function cookie($index = '', $xss_clean = FALSE)
+ {
+ return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * 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
+ * @param bool true makes the cookie secure
+ * @return void
+ */
+ function set_cookie($name = '', $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = FALSE)
+ {
+ if (is_array($name))
+ {
+ // always leave 'name' in last place, as the loop will break otherwise, due to $$item
+ foreach (array('value', 'expire', 'domain', 'path', 'prefix', 'secure', 'name') as $item)
+ {
+ if (isset($name[$item]))
+ {
+ $$item = $name[$item];
+ }
+ }
+ }
+
+ if ($prefix == '' AND config_item('cookie_prefix') != '')
+ {
+ $prefix = config_item('cookie_prefix');
+ }
+ if ($domain == '' AND config_item('cookie_domain') != '')
+ {
+ $domain = config_item('cookie_domain');
+ }
+ if ($path == '/' AND config_item('cookie_path') != '/')
+ {
+ $path = config_item('cookie_path');
+ }
+ if ($secure == FALSE AND config_item('cookie_secure') != FALSE)
+ {
+ $secure = config_item('cookie_secure');
+ }
+
+ if ( ! is_numeric($expire))
+ {
+ $expire = time() - 86500;
+ }
+ else
+ {
+ $expire = ($expire > 0) ? time() + $expire : 0;
+ }
+
+ setcookie($prefix.$name, $value, $expire, $path, $domain, $secure);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the SERVER array
+ *
+ * @access public
+ * @param string
+ * @param bool
+ * @return string
+ */
+ function server($index = '', $xss_clean = FALSE)
+ {
+ return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch the IP Address
+ *
+ * @return string
+ */
+ public function ip_address()
+ {
+ if ($this->ip_address !== FALSE)
+ {
+ return $this->ip_address;
+ }
+
+ $proxy_ips = config_item('proxy_ips');
+ if ( ! empty($proxy_ips))
+ {
+ $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
+ foreach (array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'HTTP_X_CLIENT_IP', 'HTTP_X_CLUSTER_CLIENT_IP') as $header)
+ {
+ if (($spoof = $this->server($header)) !== FALSE)
+ {
+ // Some proxies typically list the whole chain of IP
+ // addresses through which the client has reached us.
+ // e.g. client_ip, proxy_ip1, proxy_ip2, etc.
+ if (strpos($spoof, ',') !== FALSE)
+ {
+ $spoof = explode(',', $spoof, 2);
+ $spoof = $spoof[0];
+ }
+
+ if ( ! $this->valid_ip($spoof))
+ {
+ $spoof = FALSE;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ $this->ip_address = ($spoof !== FALSE && in_array($_SERVER['REMOTE_ADDR'], $proxy_ips, TRUE))
+ ? $spoof : $_SERVER['REMOTE_ADDR'];
+ }
+ else
+ {
+ $this->ip_address = $_SERVER['REMOTE_ADDR'];
+ }
+
+ if ( ! $this->valid_ip($this->ip_address))
+ {
+ $this->ip_address = '0.0.0.0';
+ }
+
+ return $this->ip_address;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Validate IP Address
+ *
+ * @access public
+ * @param string
+ * @param string ipv4 or ipv6
+ * @return bool
+ */
+ public function valid_ip($ip, $which = '')
+ {
+ $which = strtolower($which);
+
+ // First check if filter_var is available
+ if (is_callable('filter_var'))
+ {
+ switch ($which) {
+ case 'ipv4':
+ $flag = FILTER_FLAG_IPV4;
+ break;
+ case 'ipv6':
+ $flag = FILTER_FLAG_IPV6;
+ break;
+ default:
+ $flag = '';
+ break;
+ }
+
+ return (bool) filter_var($ip, FILTER_VALIDATE_IP, $flag);
+ }
+
+ if ($which !== 'ipv6' && $which !== 'ipv4')
+ {
+ if (strpos($ip, ':') !== FALSE)
+ {
+ $which = 'ipv6';
+ }
+ elseif (strpos($ip, '.') !== FALSE)
+ {
+ $which = 'ipv4';
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+
+ $func = '_valid_'.$which;
+ return $this->$func($ip);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Validate IPv4 Address
+ *
+ * Updated version suggested by Geert De Deckere
+ *
+ * @access protected
+ * @param string
+ * @return bool
+ */
+ protected function _valid_ipv4($ip)
+ {
+ $ip_segments = explode('.', $ip);
+
+ // Always 4 segments needed
+ if (count($ip_segments) !== 4)
+ {
+ return FALSE;
+ }
+ // IP can not start with 0
+ if ($ip_segments[0][0] == '0')
+ {
+ return FALSE;
+ }
+
+ // Check each segment
+ foreach ($ip_segments as $segment)
+ {
+ // IP segments must be digits and can not be
+ // longer than 3 digits or greater then 255
+ if ($segment == '' OR preg_match("/[^0-9]/", $segment) OR $segment > 255 OR strlen($segment) > 3)
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Validate IPv6 Address
+ *
+ * @access protected
+ * @param string
+ * @return bool
+ */
+ protected function _valid_ipv6($str)
+ {
+ // 8 groups, separated by :
+ // 0-ffff per group
+ // one set of consecutive 0 groups can be collapsed to ::
+
+ $groups = 8;
+ $collapsed = FALSE;
+
+ $chunks = array_filter(
+ preg_split('/(:{1,2})/', $str, NULL, PREG_SPLIT_DELIM_CAPTURE)
+ );
+
+ // Rule out easy nonsense
+ if (current($chunks) == ':' OR end($chunks) == ':')
+ {
+ return FALSE;
+ }
+
+ // PHP supports IPv4-mapped IPv6 addresses, so we'll expect those as well
+ if (strpos(end($chunks), '.') !== FALSE)
+ {
+ $ipv4 = array_pop($chunks);
+
+ if ( ! $this->_valid_ipv4($ipv4))
+ {
+ return FALSE;
+ }
+
+ $groups--;
+ }
+
+ while ($seg = array_pop($chunks))
+ {
+ if ($seg[0] == ':')
+ {
+ if (--$groups == 0)
+ {
+ return FALSE; // too many groups
+ }
+
+ if (strlen($seg) > 2)
+ {
+ return FALSE; // long separator
+ }
+
+ if ($seg == '::')
+ {
+ if ($collapsed)
+ {
+ return FALSE; // multiple collapsed
+ }
+
+ $collapsed = TRUE;
+ }
+ }
+ elseif (preg_match("/[^0-9a-f]/i", $seg) OR strlen($seg) > 4)
+ {
+ return FALSE; // invalid segment
+ }
+ }
+
+ return $collapsed OR $groups == 1;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * User Agent
+ *
+ * @access public
+ * @return string
+ */
+ function user_agent()
+ {
+ if ($this->user_agent !== FALSE)
+ {
+ return $this->user_agent;
+ }
+
+ $this->user_agent = ( ! isset($_SERVER['HTTP_USER_AGENT'])) ? FALSE : $_SERVER['HTTP_USER_AGENT'];
+
+ return $this->user_agent;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sanitize Globals
+ *
+ * This function does the following:
+ *
+ * Unsets $_GET data (if query strings are not enabled)
+ *
+ * Unsets all globals if register_globals is enabled
+ *
+ * Standardizes newline characters to \n
+ *
+ * @access private
+ * @return void
+ */
+ function _sanitize_globals()
+ {
+ // It would be "wrong" to unset any of these GLOBALS.
+ $protected = array('_SERVER', '_GET', '_POST', '_FILES', '_REQUEST',
+ '_SESSION', '_ENV', 'GLOBALS', 'HTTP_RAW_POST_DATA',
+ 'system_folder', 'application_folder', 'BM', 'EXT',
+ 'CFG', 'URI', 'RTR', 'OUT', 'IN');
+
+ // Unset globals for securiy.
+ // This is effectively the same as register_globals = off
+ foreach (array($_GET, $_POST, $_COOKIE) as $global)
+ {
+ if ( ! is_array($global))
+ {
+ if ( ! in_array($global, $protected))
+ {
+ global $$global;
+ $$global = NULL;
+ }
+ }
+ else
+ {
+ foreach ($global as $key => $val)
+ {
+ if ( ! in_array($key, $protected))
+ {
+ global $$key;
+ $$key = NULL;
+ }
+ }
+ }
+ }
+
+ // Is $_GET data allowed? If not we'll set the $_GET to an empty array
+ if ($this->_allow_get_array == FALSE)
+ {
+ $_GET = array();
+ }
+ else
+ {
+ if (is_array($_GET) AND count($_GET) > 0)
+ {
+ foreach ($_GET as $key => $val)
+ {
+ $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ }
+ }
+ }
+
+ // Clean $_POST Data
+ if (is_array($_POST) AND count($_POST) > 0)
+ {
+ foreach ($_POST as $key => $val)
+ {
+ $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ }
+ }
+
+ // Clean $_COOKIE Data
+ if (is_array($_COOKIE) AND count($_COOKIE) > 0)
+ {
+ // Also get rid of specially treated cookies that might be set by a server
+ // or silly application, that are of no use to a CI application anyway
+ // but that when present will trip our 'Disallowed Key Characters' alarm
+ // http://www.ietf.org/rfc/rfc2109.txt
+ // note that the key names below are single quoted strings, and are not PHP variables
+ unset($_COOKIE['$Version']);
+ unset($_COOKIE['$Path']);
+ unset($_COOKIE['$Domain']);
+
+ foreach ($_COOKIE as $key => $val)
+ {
+ $_COOKIE[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ }
+ }
+
+ // Sanitize PHP_SELF
+ $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
+
+
+ // CSRF Protection check on HTTP requests
+ if ($this->_enable_csrf == TRUE && ! $this->is_cli_request())
+ {
+ $this->security->csrf_verify();
+ }
+
+ log_message('debug', "Global POST and COOKIE data sanitized");
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Clean Input Data
+ *
+ * This is a helper function. It escapes data and
+ * standardizes newline characters to \n
+ *
+ * @access private
+ * @param string
+ * @return string
+ */
+ function _clean_input_data($str)
+ {
+ if (is_array($str))
+ {
+ $new_array = array();
+ foreach ($str as $key => $val)
+ {
+ $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ }
+ return $new_array;
+ }
+
+ /* We strip slashes if magic quotes is on to keep things consistent
+
+ NOTE: In PHP 5.4 get_magic_quotes_gpc() will always return 0 and
+ it will probably not exist in future versions at all.
+ */
+ if ( ! is_php('5.4') && get_magic_quotes_gpc())
+ {
+ $str = stripslashes($str);
+ }
+
+ // Clean UTF-8 if supported
+ if (UTF8_ENABLED === TRUE)
+ {
+ $str = $this->uni->clean_string($str);
+ }
+
+ // Remove control characters
+ $str = remove_invisible_characters($str);
+
+ // Should we filter the input data?
+ if ($this->_enable_xss === TRUE)
+ {
+ $str = $this->security->xss_clean($str);
+ }
+
+ // Standardize newlines if needed
+ if ($this->_standardize_newlines == TRUE)
+ {
+ if (strpos($str, "\r") !== FALSE)
+ {
+ $str = str_replace(array("\r\n", "\r", "\r\n\n"), PHP_EOL, $str);
+ }
+ }
+
+ return $str;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Clean Keys
+ *
+ * This is a helper function. To prevent malicious users
+ * from trying to exploit keys we make sure that keys are
+ * only named with alpha-numeric text and a few other items.
+ *
+ * @access private
+ * @param string
+ * @return string
+ */
+ function _clean_input_keys($str)
+ {
+ if ( ! preg_match("/^[a-z0-9:_\/-]+$/i", $str))
+ {
+ exit('Disallowed Key Characters.');
+ }
+
+ // Clean UTF-8 if supported
+ if (UTF8_ENABLED === TRUE)
+ {
+ $str = $this->uni->clean_string($str);
+ }
+
+ return $str;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Request Headers
+ *
+ * In Apache, you can simply call apache_request_headers(), however for
+ * people running other webservers the function is undefined.
+ *
+ * @param bool XSS cleaning
+ *
+ * @return array
+ */
+ public function request_headers($xss_clean = FALSE)
+ {
+ // Look at Apache go!
+ if (function_exists('apache_request_headers'))
+ {
+ $headers = apache_request_headers();
+ }
+ else
+ {
+ $headers['Content-Type'] = (isset($_SERVER['CONTENT_TYPE'])) ? $_SERVER['CONTENT_TYPE'] : @getenv('CONTENT_TYPE');
+
+ foreach ($_SERVER as $key => $val)
+ {
+ if (strncmp($key, 'HTTP_', 5) === 0)
+ {
+ $headers[substr($key, 5)] = $this->_fetch_from_array($_SERVER, $key, $xss_clean);
+ }
+ }
+ }
+
+ // take SOME_HEADER and turn it into Some-Header
+ foreach ($headers as $key => $val)
+ {
+ $key = str_replace('_', ' ', strtolower($key));
+ $key = str_replace(' ', '-', ucwords($key));
+
+ $this->headers[$key] = $val;
+ }
+
+ return $this->headers;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Request Header
+ *
+ * Returns the value of a single member of the headers class member
+ *
+ * @param string array key for $this->headers
+ * @param boolean XSS Clean or not
+ * @return mixed FALSE on failure, string on success
+ */
+ public function get_request_header($index, $xss_clean = FALSE)
+ {
+ if (empty($this->headers))
+ {
+ $this->request_headers();
+ }
+
+ if ( ! isset($this->headers[$index]))
+ {
+ return FALSE;
+ }
+
+ if ($xss_clean === TRUE)
+ {
+ return $this->security->xss_clean($this->headers[$index]);
+ }
+
+ return $this->headers[$index];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Is ajax Request?
+ *
+ * Test to see if a request contains the HTTP_X_REQUESTED_WITH header
+ *
+ * @return boolean
+ */
+ public function is_ajax_request()
+ {
+ return ($this->server('HTTP_X_REQUESTED_WITH') === 'XMLHttpRequest');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Is cli Request?
+ *
+ * Test to see if a request was made from the command line
+ *
+ * @return bool
+ */
+ public function is_cli_request()
+ {
+ return (php_sapi_name() === 'cli' OR defined('STDIN'));
+ }
+
+}
+
+/* End of file Input.php */
+/* Location: ./system/core/Input.php */
\ No newline at end of file
diff --git a/system/libraries/Language.php b/system/core/Lang.php
old mode 100644
new mode 100755
similarity index 55%
rename from system/libraries/Language.php
rename to system/core/Lang.php
index b679c891..5ac67183
--- a/system/libraries/Language.php
+++ b/system/core/Lang.php
@@ -2,11 +2,11 @@
/**
* CodeIgniter
*
- * An open source application development framework for PHP 4.3.2 or newer
+ * An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
- * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
@@ -24,9 +24,19 @@
* @author ExpressionEngine Dev Team
* @link http://codeigniter.com/user_guide/libraries/language.html
*/
-class CI_Language {
+class CI_Lang {
+ /**
+ * List of translations
+ *
+ * @var array
+ */
var $language = array();
+ /**
+ * List of loaded language files
+ *
+ * @var array
+ */
var $is_loaded = array();
/**
@@ -34,7 +44,7 @@ class CI_Language {
*
* @access public
*/
- function CI_Language()
+ function __construct()
{
log_message('debug', "Language Class Initialized");
}
@@ -47,41 +57,61 @@ function CI_Language()
* @access public
* @param mixed the name of the language file to be loaded. Can be an array
* @param string the language (english, etc.)
+ * @param bool return loaded array of translations
+ * @param bool add suffix to $langfile
+ * @param string alternative path to look for language file
* @return mixed
*/
- function load($langfile = '', $idiom = '', $return = FALSE)
+ function load($langfile = '', $idiom = '', $return = FALSE, $add_suffix = TRUE, $alt_path = '')
{
- $langfile = str_replace(EXT, '', str_replace('_lang.', '', $langfile)).'_lang'.EXT;
+ $langfile = str_replace('.php', '', $langfile);
+
+ if ($add_suffix == TRUE)
+ {
+ $langfile = str_replace('_lang.', '', $langfile).'_lang';
+ }
+
+ $langfile .= '.php';
if (in_array($langfile, $this->is_loaded, TRUE))
{
return;
}
+ $config =& get_config();
+
if ($idiom == '')
{
- $CI =& get_instance();
- $deft_lang = $CI->config->item('language');
+ $deft_lang = ( ! isset($config['language'])) ? 'english' : $config['language'];
$idiom = ($deft_lang == '') ? 'english' : $deft_lang;
}
// Determine where the language file is and load it
- if (file_exists(APPPATH.'language/'.$idiom.'/'.$langfile))
+ if ($alt_path != '' && file_exists($alt_path.'language/'.$idiom.'/'.$langfile))
{
- include(APPPATH.'language/'.$idiom.'/'.$langfile);
+ include($alt_path.'language/'.$idiom.'/'.$langfile);
}
else
{
- if (file_exists(BASEPATH.'language/'.$idiom.'/'.$langfile))
+ $found = FALSE;
+
+ foreach (get_instance()->load->get_package_paths(TRUE) as $package_path)
{
- include(BASEPATH.'language/'.$idiom.'/'.$langfile);
+ if (file_exists($package_path.'language/'.$idiom.'/'.$langfile))
+ {
+ include($package_path.'language/'.$idiom.'/'.$langfile);
+ $found = TRUE;
+ break;
+ }
}
- else
+
+ if ($found !== TRUE)
{
show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
}
}
+
if ( ! isset($lang))
{
log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
@@ -107,17 +137,24 @@ function load($langfile = '', $idiom = '', $return = FALSE)
* Fetch a single line of text from the language array
*
* @access public
- * @param string $line the language line
+ * @param string $line the language line
* @return string
*/
function line($line = '')
{
- $line = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
- return $line;
+ $value = ($line == '' OR ! isset($this->language[$line])) ? FALSE : $this->language[$line];
+
+ // Because killer robots like unicorns!
+ if ($value === FALSE)
+ {
+ log_message('error', 'Could not find the language line "'.$line.'"');
+ }
+
+ return $value;
}
}
// END Language Class
-/* End of file Language.php */
-/* Location: ./system/libraries/Language.php */
\ No newline at end of file
+/* End of file Lang.php */
+/* Location: ./system/core/Lang.php */
diff --git a/system/libraries/Loader.php b/system/core/Loader.php
similarity index 53%
rename from system/libraries/Loader.php
rename to system/core/Loader.php
index 781c83c6..6b7ee0c2 100644
--- a/system/libraries/Loader.php
+++ b/system/core/Loader.php
@@ -2,11 +2,11 @@
/**
* CodeIgniter
*
- * An open source application development framework for PHP 4.3.2 or newer
+ * An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
- * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
@@ -29,96 +29,212 @@
class CI_Loader {
// All these are set automatically. Don't mess with them.
- var $_ci_ob_level;
- var $_ci_view_path = '';
- var $_ci_is_php5 = FALSE;
- var $_ci_is_instance = FALSE; // Whether we should use $this or $CI =& get_instance()
- var $_ci_cached_vars = array();
- var $_ci_classes = array();
- var $_ci_loaded_files = array();
- var $_ci_models = array();
- var $_ci_helpers = array();
- var $_ci_plugins = array();
- var $_ci_varmap = array('unit_test' => 'unit', 'user_agent' => 'agent');
-
+ /**
+ * Nesting level of the output buffering mechanism
+ *
+ * @var int
+ * @access protected
+ */
+ protected $_ci_ob_level;
+ /**
+ * List of paths to load views from
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_view_paths = array();
+ /**
+ * List of paths to load libraries from
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_library_paths = array();
+ /**
+ * List of paths to load models from
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_model_paths = array();
+ /**
+ * List of paths to load helpers from
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_helper_paths = array();
+ /**
+ * List of loaded base classes
+ * Set by the controller class
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_base_classes = array(); // Set by the controller class
+ /**
+ * List of cached variables
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_cached_vars = array();
+ /**
+ * List of loaded classes
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_classes = array();
+ /**
+ * List of loaded files
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_loaded_files = array();
+ /**
+ * List of loaded models
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_models = array();
+ /**
+ * List of loaded helpers
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_helpers = array();
+ /**
+ * List of class name mappings
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_ci_varmap = array('unit_test' => 'unit',
+ 'user_agent' => 'agent');
/**
* Constructor
*
* Sets the path to the view files and gets the initial output buffering level
- *
- * @access public
*/
- function CI_Loader()
- {
- $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;
- $this->_ci_view_path = APPPATH.'views/';
+ public function __construct()
+ {
$this->_ci_ob_level = ob_get_level();
-
+ $this->_ci_library_paths = array(APPPATH, BASEPATH);
+ $this->_ci_helper_paths = array(APPPATH, BASEPATH);
+ $this->_ci_model_paths = array(APPPATH);
+ $this->_ci_view_paths = array(APPPATH.'views/' => TRUE);
+
log_message('debug', "Loader Class Initialized");
}
-
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initialize the Loader
+ *
+ * This method is called once in CI_Controller.
+ *
+ * @param array
+ * @return object
+ */
+ public function initialize()
+ {
+ $this->_ci_classes = array();
+ $this->_ci_loaded_files = array();
+ $this->_ci_models = array();
+ $this->_base_classes =& is_loaded();
+
+ $this->_ci_autoloader();
+
+ return $this;
+ }
+
// --------------------------------------------------------------------
-
+
+ /**
+ * Is Loaded
+ *
+ * A utility function to test if a class is in the self::$_ci_classes array.
+ * This function returns the object name if the class tested for is loaded,
+ * and returns FALSE if it isn't.
+ *
+ * It is mainly used in the form_helper -> _get_validation_object()
+ *
+ * @param string class being checked for
+ * @return mixed class object name on the CI SuperObject or FALSE
+ */
+ public function is_loaded($class)
+ {
+ if (isset($this->_ci_classes[$class]))
+ {
+ return $this->_ci_classes[$class];
+ }
+
+ return FALSE;
+ }
+
+ // --------------------------------------------------------------------
+
/**
* Class Loader
*
* This function lets users load and instantiate classes.
* It is designed to be called from a user's app controllers.
*
- * @access public
* @param string the name of the class
* @param mixed the optional parameters
* @param string an optional object name
* @return void
- */
- function library($library = '', $params = NULL, $object_name = NULL)
+ */
+ public function library($library = '', $params = NULL, $object_name = NULL)
{
- if ($library == '')
- {
- return FALSE;
- }
-
- if ( ! is_null($params) AND ! is_array($params))
- {
- $params = NULL;
- }
-
if (is_array($library))
{
foreach ($library as $class)
{
- $this->_ci_load_class($class, $params, $object_name);
+ $this->library($class, $params);
}
+
+ return;
}
- else
+
+ if ($library == '' OR isset($this->_base_classes[$library]))
{
- $this->_ci_load_class($library, $params, $object_name);
+ return FALSE;
}
-
- $this->_ci_assign_to_models();
+
+ if ( ! is_null($params) && ! is_array($params))
+ {
+ $params = NULL;
+ }
+
+ $this->_ci_load_class($library, $params, $object_name);
}
// --------------------------------------------------------------------
-
+
/**
* Model Loader
*
* This function lets users load and instantiate models.
*
- * @access public
* @param string the name of the class
* @param string name for the model
* @param bool database connection
* @return void
- */
- function model($model, $name = '', $db_conn = FALSE)
- {
+ */
+ public function model($model, $name = '', $db_conn = FALSE)
+ {
if (is_array($model))
{
- foreach($model as $babe)
+ foreach ($model as $babe)
{
- $this->model($babe);
+ $this->model($babe);
}
return;
}
@@ -127,164 +243,161 @@ function model($model, $name = '', $db_conn = FALSE)
{
return;
}
-
+
+ $path = '';
+
// Is the model in a sub-folder? If so, parse out the filename and path.
- if (strpos($model, '/') === FALSE)
- {
- $path = '';
- }
- else
+ if (($last_slash = strrpos($model, '/')) !== FALSE)
{
- $x = explode('/', $model);
- $model = end($x);
- unset($x[count($x)-1]);
- $path = implode('/', $x).'/';
+ // The path is in front of the last slash
+ $path = substr($model, 0, $last_slash + 1);
+
+ // And the model name behind it
+ $model = substr($model, $last_slash + 1);
}
-
+
if ($name == '')
{
$name = $model;
}
-
+
if (in_array($name, $this->_ci_models, TRUE))
{
return;
}
-
+
$CI =& get_instance();
if (isset($CI->$name))
{
show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
}
-
+
$model = strtolower($model);
-
- if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
- {
- show_error('Unable to locate the model you have specified: '.$model);
- }
-
- if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
- {
- if ($db_conn === TRUE)
- $db_conn = '';
-
- $CI->load->database($db_conn, FALSE, TRUE);
- }
-
- if ( ! class_exists('Model'))
+
+ foreach ($this->_ci_model_paths as $mod_path)
{
- load_class('Model', FALSE);
- }
+ if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
+ {
+ continue;
+ }
- require_once(APPPATH.'models/'.$path.$model.EXT);
+ if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
+ {
+ if ($db_conn === TRUE)
+ {
+ $db_conn = '';
+ }
- $model = ucfirst($model);
-
- $CI->$name = new $model();
- $CI->$name->_assign_libraries();
-
- $this->_ci_models[] = $name;
+ $CI->load->database($db_conn, FALSE, TRUE);
+ }
+
+ if ( ! class_exists('CI_Model'))
+ {
+ load_class('Model', 'core');
+ }
+
+ require_once($mod_path.'models/'.$path.$model.'.php');
+
+ $model = ucfirst($model);
+
+ $CI->$name = new $model();
+
+ $this->_ci_models[] = $name;
+ return;
+ }
+
+ // couldn't find the model
+ show_error('Unable to locate the model you have specified: '.$model);
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Database Loader
*
- * @access public
* @param string the DB credentials
* @param bool whether to return the DB object
* @param bool whether to enable active record (this allows us to override the config setting)
* @return object
- */
- function database($params = '', $return = FALSE, $active_record = FALSE)
+ */
+ public function database($params = '', $return = FALSE, $active_record = NULL)
{
// Grab the super object
$CI =& get_instance();
-
+
// Do we even need to load the database class?
- if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))
+ if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db))
{
return FALSE;
- }
-
- require_once(BASEPATH.'database/DB'.EXT);
+ }
+
+ require_once(BASEPATH.'database/DB.php');
if ($return === TRUE)
{
return DB($params, $active_record);
}
-
- // Initialize the db variable. Needed to prevent
+
+ // Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = '';
-
+
// Load the DB class
- $CI->db =& DB($params, $active_record);
-
- // Assign the DB object to any existing models
- $this->_ci_assign_to_models();
+ $CI->db =& DB($params, $active_record);
}
-
+
// --------------------------------------------------------------------
/**
* Load the Utilities Class
*
- * @access public
- * @return string
- */
- function dbutil()
+ * @return string
+ */
+ public function dbutil()
{
if ( ! class_exists('CI_DB'))
{
$this->database();
}
-
+
$CI =& get_instance();
// for backwards compatibility, load dbforge so we can extend dbutils off it
// this use is deprecated and strongly discouraged
$CI->load->dbforge();
-
- require_once(BASEPATH.'database/DB_utility'.EXT);
- require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT);
- $class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
- $CI->dbutil =& instantiate_class(new $class());
+ require_once(BASEPATH.'database/DB_utility.php');
+ require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility.php');
+ $class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
- $CI->load->_ci_assign_to_models();
+ $CI->dbutil = new $class();
}
-
+
// --------------------------------------------------------------------
/**
* Load the Database Forge Class
*
- * @access public
- * @return string
- */
- function dbforge()
+ * @return string
+ */
+ public function dbforge()
{
if ( ! class_exists('CI_DB'))
{
$this->database();
}
-
+
$CI =& get_instance();
-
- require_once(BASEPATH.'database/DB_forge'.EXT);
- require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT);
+
+ require_once(BASEPATH.'database/DB_forge.php');
+ require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php');
$class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
$CI->dbforge = new $class();
-
- $CI->load->_ci_assign_to_models();
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Load View
*
@@ -296,55 +409,53 @@ function dbforge()
* some cases it's advantageous to be able to return data so that
* a developer can process it in some way.
*
- * @access public
* @param string
* @param array
* @param bool
* @return void
*/
- function view($view, $vars = array(), $return = FALSE)
+ public function view($view, $vars = array(), $return = FALSE)
{
return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Load File
*
* This is a generic file loader
*
- * @access public
* @param string
* @param bool
* @return string
*/
- function file($path, $return = FALSE)
+ public function file($path, $return = FALSE)
{
return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Set Variables
*
* Once variables are set they become available within
* the controller class and its "view" files.
*
- * @access public
* @param array
+ * @param string
* @return void
*/
- function vars($vars = array(), $val = '')
+ public function vars($vars = array(), $val = '')
{
if ($val != '' AND is_string($vars))
{
$vars = array($vars => $val);
}
-
+
$vars = $this->_ci_object_to_array($vars);
-
+
if (is_array($vars) AND count($vars) > 0)
{
foreach ($vars as $key => $val)
@@ -353,236 +464,270 @@ function vars($vars = array(), $val = '')
}
}
}
-
+
// --------------------------------------------------------------------
-
+
+ /**
+ * Get Variable
+ *
+ * Check if a variable is set and retrieve it.
+ *
+ * @param array
+ * @return void
+ */
+ public function get_var($key)
+ {
+ return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL;
+ }
+
+ // --------------------------------------------------------------------
+
/**
* Load Helper
*
* This function loads the specified helper file.
*
- * @access public
* @param mixed
* @return void
*/
- function helper($helpers = array())
+ public function helper($helpers = array())
{
- if ( ! is_array($helpers))
+ foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper)
{
- $helpers = array($helpers);
- }
-
- foreach ($helpers as $helper)
- {
- $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');
-
if (isset($this->_ci_helpers[$helper]))
{
continue;
}
-
- $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT;
- // Is this a helper extension request?
+ $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.'.php';
+
+ // Is this a helper extension request?
if (file_exists($ext_helper))
{
- $base_helper = BASEPATH.'helpers/'.$helper.EXT;
-
+ $base_helper = BASEPATH.'helpers/'.$helper.'.php';
+
if ( ! file_exists($base_helper))
{
- show_error('Unable to load the requested file: helpers/'.$helper.EXT);
+ show_error('Unable to load the requested file: helpers/'.$helper.'.php');
}
-
+
include_once($ext_helper);
include_once($base_helper);
+
+ $this->_ci_helpers[$helper] = TRUE;
+ log_message('debug', 'Helper loaded: '.$helper);
+ continue;
}
- elseif (file_exists(APPPATH.'helpers/'.$helper.EXT))
- {
- include_once(APPPATH.'helpers/'.$helper.EXT);
- }
- else
- {
- if (file_exists(BASEPATH.'helpers/'.$helper.EXT))
- {
- include_once(BASEPATH.'helpers/'.$helper.EXT);
- }
- else
+
+ // Try to load the helper
+ foreach ($this->_ci_helper_paths as $path)
+ {
+ if (file_exists($path.'helpers/'.$helper.'.php'))
{
- show_error('Unable to load the requested file: helpers/'.$helper.EXT);
+ include_once($path.'helpers/'.$helper.'.php');
+
+ $this->_ci_helpers[$helper] = TRUE;
+ log_message('debug', 'Helper loaded: '.$helper);
+ break;
}
}
- $this->_ci_helpers[$helper] = TRUE;
- log_message('debug', 'Helper loaded: '.$helper);
- }
+ // unable to load the helper
+ if ( ! isset($this->_ci_helpers[$helper]))
+ {
+ show_error('Unable to load the requested file: helpers/'.$helper.'.php');
+ }
+ }
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Load Helpers
*
* This is simply an alias to the above function in case the
* user has written the plural form of this function.
*
- * @access public
* @param array
* @return void
*/
- function helpers($helpers = array())
+ public function helpers($helpers = array())
{
$this->helper($helpers);
}
-
+
// --------------------------------------------------------------------
-
+
/**
- * Load Plugin
- *
- * This function loads the specified plugin.
+ * Loads a language file
*
- * @access public
* @param array
+ * @param string
* @return void
*/
- function plugin($plugins = array())
+ public function language($file = array(), $lang = '')
{
- if ( ! is_array($plugins))
+ $CI =& get_instance();
+
+ if ( ! is_array($file))
{
- $plugins = array($plugins);
+ $file = array($file);
}
-
- foreach ($plugins as $plugin)
- {
- $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');
-
- if (isset($this->_ci_plugins[$plugin]))
- {
- continue;
- }
- if (file_exists(APPPATH.'plugins/'.$plugin.EXT))
- {
- include_once(APPPATH.'plugins/'.$plugin.EXT);
- }
- else
- {
- if (file_exists(BASEPATH.'plugins/'.$plugin.EXT))
- {
- include_once(BASEPATH.'plugins/'.$plugin.EXT);
- }
- else
- {
- show_error('Unable to load the requested file: plugins/'.$plugin.EXT);
- }
- }
-
- $this->_ci_plugins[$plugin] = TRUE;
- log_message('debug', 'Plugin loaded: '.$plugin);
- }
+ foreach ($file as $langfile)
+ {
+ $CI->lang->load($langfile, $lang);
+ }
}
// --------------------------------------------------------------------
-
+
/**
- * Load Plugins
- *
- * This is simply an alias to the above function in case the
- * user has written the plural form of this function.
+ * Loads a config file
*
- * @access public
- * @param array
+ * @param string
+ * @param bool
+ * @param bool
* @return void
*/
- function plugins($plugins = array())
+ public function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
{
- $this->plugin($plugins);
+ $CI =& get_instance();
+ $CI->config->load($file, $use_sections, $fail_gracefully);
}
-
+
// --------------------------------------------------------------------
-
+
/**
- * Loads a language file
+ * Driver
*
- * @access public
- * @param array
- * @param string
+ * Loads a driver library
+ *
+ * @param string the name of the class
+ * @param mixed the optional parameters
+ * @param string an optional object name
* @return void
*/
- function language($file = array(), $lang = '')
+ public function driver($library = '', $params = NULL, $object_name = NULL)
{
- $CI =& get_instance();
+ if ( ! class_exists('CI_Driver_Library'))
+ {
+ // we aren't instantiating an object here, that'll be done by the Library itself
+ require BASEPATH.'libraries/Driver.php';
+ }
- if ( ! is_array($file))
+ if ($library == '')
{
- $file = array($file);
+ return FALSE;
}
- foreach ($file as $langfile)
- {
- $CI->lang->load($langfile, $lang);
+ // We can save the loader some time since Drivers will *always* be in a subfolder,
+ // and typically identically named to the library
+ if ( ! strpos($library, '/'))
+ {
+ $library = ucfirst($library).'/'.$library;
}
+
+ return $this->library($library, $params, $object_name);
}
+ // --------------------------------------------------------------------
+
/**
- * Loads language files for scaffolding
+ * Add Package Path
+ *
+ * Prepends a parent path to the library, model, helper, and config path arrays
*
- * @access public
* @param string
- * @return arra
+ * @param boolean
+ * @return void
*/
- function scaffold_language($file = '', $lang = '', $return = FALSE)
+ public function add_package_path($path, $view_cascade=TRUE)
{
- $CI =& get_instance();
- return $CI->lang->load($file, $lang, $return);
+ $path = rtrim($path, '/').'/';
+
+ array_unshift($this->_ci_library_paths, $path);
+ array_unshift($this->_ci_model_paths, $path);
+ array_unshift($this->_ci_helper_paths, $path);
+
+ $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;
+
+ // Add config file path
+ $config =& $this->_ci_get_component('config');
+ array_unshift($config->_config_paths, $path);
}
-
+
// --------------------------------------------------------------------
-
+
/**
- * Loads a config file
+ * Get Package Paths
+ *
+ * Return a list of all package paths, by default it will ignore BASEPATH.
*
- * @access public
* @param string
* @return void
*/
- function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
- {
- $CI =& get_instance();
- $CI->config->load($file, $use_sections, $fail_gracefully);
+ public function get_package_paths($include_base = FALSE)
+ {
+ return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths;
}
// --------------------------------------------------------------------
-
+
/**
- * Scaffolding Loader
+ * Remove Package Path
*
- * This initializing function works a bit different than the
- * others. It doesn't load the class. Instead, it simply
- * sets a flag indicating that scaffolding is allowed to be
- * used. The actual scaffolding function below is
- * called by the front controller based on whether the
- * second segment of the URL matches the "secret" scaffolding
- * word stored in the application/config/routes.php
+ * Remove a path from the library, model, and helper path arrays if it exists
+ * If no path is provided, the most recently added path is removed.
*
- * @access public
- * @param string
- * @return void
- */
- function scaffolding($table = '')
- {
- if ($table === FALSE)
+ * @param type
+ * @param bool
+ * @return type
+ */
+ public function remove_package_path($path = '', $remove_config_path = TRUE)
+ {
+ $config =& $this->_ci_get_component('config');
+
+ if ($path == '')
{
- show_error('You must include the name of the table you would like to access when you initialize scaffolding');
+ $void = array_shift($this->_ci_library_paths);
+ $void = array_shift($this->_ci_model_paths);
+ $void = array_shift($this->_ci_helper_paths);
+ $void = array_shift($this->_ci_view_paths);
+ $void = array_shift($config->_config_paths);
}
-
- $CI =& get_instance();
- $CI->_ci_scaffolding = TRUE;
- $CI->_ci_scaff_table = $table;
+ else
+ {
+ $path = rtrim($path, '/').'/';
+ foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var)
+ {
+ if (($key = array_search($path, $this->{$var})) !== FALSE)
+ {
+ unset($this->{$var}[$key]);
+ }
+ }
+
+ if (isset($this->_ci_view_paths[$path.'views/']))
+ {
+ unset($this->_ci_view_paths[$path.'views/']);
+ }
+
+ if (($key = array_search($path, $config->_config_paths)) !== FALSE)
+ {
+ unset($config->_config_paths[$key]);
+ }
+ }
+
+ // make sure the application default paths are still in the array
+ $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH)));
+ $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH)));
+ $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));
+ $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));
+ $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));
}
// --------------------------------------------------------------------
-
+
/**
* Loader
*
@@ -590,11 +735,10 @@ function scaffolding($table = '')
* Variables are prefixed with _ci_ to avoid symbol collision with
* variables made available to view files
*
- * @access private
* @param array
* @return void
*/
- function _ci_load($_ci_data)
+ protected function _ci_load($_ci_data)
{
// Set the default data variables
foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
@@ -602,37 +746,49 @@ function _ci_load($_ci_data)
$$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
}
+ $file_exists = FALSE;
+
// Set the path to the requested file
- if ($_ci_path == '')
+ if ($_ci_path != '')
{
- $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
- $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;
- $_ci_path = $this->_ci_view_path.$_ci_file;
+ $_ci_x = explode('/', $_ci_path);
+ $_ci_file = end($_ci_x);
}
else
{
- $_ci_x = explode('/', $_ci_path);
- $_ci_file = end($_ci_x);
+ $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
+ $_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view;
+
+ foreach ($this->_ci_view_paths as $view_file => $cascade)
+ {
+ if (file_exists($view_file.$_ci_file))
+ {
+ $_ci_path = $view_file.$_ci_file;
+ $file_exists = TRUE;
+ break;
+ }
+
+ if ( ! $cascade)
+ {
+ break;
+ }
+ }
}
-
- if ( ! file_exists($_ci_path))
+
+ if ( ! $file_exists && ! file_exists($_ci_path))
{
show_error('Unable to load the requested file: '.$_ci_file);
}
-
+
// This allows anything loaded using $this->load (views, files, etc.)
// to become accessible from within the Controller and Model functions.
- // Only needed when running PHP 5
-
- if ($this->_ci_is_instance())
+
+ $_ci_CI =& get_instance();
+ foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
{
- $_ci_CI =& get_instance();
- foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
+ if ( ! isset($this->$_ci_key))
{
- if ( ! isset($this->$_ci_key))
- {
- $this->$_ci_key =& $_ci_CI->$_ci_key;
- }
+ $this->$_ci_key =& $_ci_CI->$_ci_key;
}
}
@@ -643,13 +799,13 @@ function _ci_load($_ci_data)
* function or via the second parameter of this function. We'll merge
* the two types and cache them so that views that are embedded within
* other views can have access to these variables.
- */
+ */
if (is_array($_ci_vars))
{
$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
}
extract($this->_ci_cached_vars);
-
+
/*
* Buffer the output
*
@@ -663,11 +819,11 @@ function _ci_load($_ci_data)
* the browser and then stop the timer it won't be accurate.
*/
ob_start();
-
+
// If the PHP installation does not support short tags we'll
// do a little string replacement, changing the short tags
// to standard PHP echo statements.
-
+
if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
{
echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('=', ' $this->_ci_ob_level + 1)
{
ob_end_flush();
}
else
{
- // PHP 4 requires that we use a global
- global $OUT;
- $OUT->append_output(ob_get_contents());
+ $_ci_CI->output->append_output(ob_get_contents());
@ob_end_clean();
}
}
@@ -717,47 +871,40 @@ function _ci_load($_ci_data)
*
* This function loads the requested class.
*
- * @access private
- * @param string the item that is being loaded
+ * @param string the item that is being loaded
* @param mixed any additional parameters
* @param string an optional object name
- * @return void
+ * @return void
*/
- function _ci_load_class($class, $params = NULL, $object_name = NULL)
- {
- // Get the class name, and while we're at it trim any slashes.
- // The directory path can be included as part of the class name,
+ protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
+ {
+ // Get the class name, and while we're at it trim any slashes.
+ // The directory path can be included as part of the class name,
// but we don't want a leading slash
- $class = str_replace(EXT, '', trim($class, '/'));
-
+ $class = str_replace('.php', '', trim($class, '/'));
+
// Was the path included with the class name?
// We look for a slash to determine this
$subdir = '';
- if (strpos($class, '/') !== FALSE)
+ if (($last_slash = strrpos($class, '/')) !== FALSE)
{
- // explode the path so we can separate the filename from the path
- $x = explode('/', $class);
-
- // Reset the $class variable now that we know the actual filename
- $class = end($x);
-
- // Kill the filename from the array
- unset($x[count($x)-1]);
-
- // Glue the path back together, sans filename
- $subdir = implode($x, '/').'/';
+ // Extract the path
+ $subdir = substr($class, 0, $last_slash + 1);
+
+ // Get the filename from the path
+ $class = substr($class, $last_slash + 1);
}
// We'll test for both lowercase and capitalized versions of the file name
foreach (array(ucfirst($class), strtolower($class)) as $class)
{
- $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT;
+ $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';
- // Is this a class extension request?
+ // Is this a class extension request?
if (file_exists($subclass))
{
- $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT;
-
+ $baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php';
+
if ( ! file_exists($baseclass))
{
log_message('error', "Unable to load the requested class: ".$class);
@@ -775,35 +922,34 @@ function _ci_load_class($class, $params = NULL, $object_name = NULL)
$CI =& get_instance();
if ( ! isset($CI->$object_name))
{
- return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
+ return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
}
-
+
$is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
}
-
- include_once($baseclass);
+
+ include_once($baseclass);
include_once($subclass);
$this->_ci_loaded_files[] = $subclass;
-
- return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
+
+ return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
}
-
+
// Lets search for the requested library file and load it.
- $is_duplicate = FALSE;
- for ($i = 1; $i < 3; $i++)
+ $is_duplicate = FALSE;
+ foreach ($this->_ci_library_paths as $path)
{
- $path = ($i % 2) ? APPPATH : BASEPATH;
- $filepath = $path.'libraries/'.$subdir.$class.EXT;
-
+ $filepath = $path.'libraries/'.$subdir.$class.'.php';
+
// Does the file exist? No? Bummer...
if ( ! file_exists($filepath))
{
continue;
}
-
+
// Safety: Was the class already loaded by a previous call?
if (in_array($filepath, $this->_ci_loaded_files))
{
@@ -818,16 +964,17 @@ function _ci_load_class($class, $params = NULL, $object_name = NULL)
return $this->_ci_init_class($class, '', $params, $object_name);
}
}
-
+
$is_duplicate = TRUE;
log_message('debug', $class." class already loaded. Second attempt ignored.");
return;
}
-
+
include_once($filepath);
$this->_ci_loaded_files[] = $filepath;
return $this->_ci_init_class($class, '', $params, $object_name);
}
+
} // END FOREACH
// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
@@ -836,7 +983,7 @@ function _ci_load_class($class, $params = NULL, $object_name = NULL)
$path = strtolower($class).'/'.$class;
return $this->_ci_load_class($path, $params);
}
-
+
// If we got this far we were unable to find the requested class.
// We do not issue errors if the load call failed due to a duplicate request
if ($is_duplicate == FALSE)
@@ -845,42 +992,66 @@ function _ci_load_class($class, $params = NULL, $object_name = NULL)
show_error("Unable to load the requested class: ".$class);
}
}
-
+
// --------------------------------------------------------------------
/**
* Instantiates a class
*
- * @access private
* @param string
* @param string
+ * @param bool
* @param string an optional object name
* @return null
*/
- function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
- {
- // Is there an associated config file for this class?
+ protected function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
+ {
+ // Is there an associated config file for this class? Note: these should always be lowercase
if ($config === NULL)
{
- // We test for both uppercase and lowercase, for servers that
- // are case-sensitive with regard to file names
- if (file_exists(APPPATH.'config/'.strtolower($class).EXT))
- {
- include_once(APPPATH.'config/'.strtolower($class).EXT);
- }
- elseif (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT))
+ // Fetch the config paths containing any package paths
+ $config_component = $this->_ci_get_component('config');
+
+ if (is_array($config_component->_config_paths))
{
- include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT);
+ // Break on the first found file, thus package files
+ // are not overridden by default paths
+ foreach ($config_component->_config_paths as $path)
+ {
+ // We test for both uppercase and lowercase, for servers that
+ // are case-sensitive with regard to file names. Check for environment
+ // first, global next
+ if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
+ {
+ include($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
+ break;
+ }
+ elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
+ {
+ include($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
+ break;
+ }
+ elseif (file_exists($path .'config/'.strtolower($class).'.php'))
+ {
+ include($path .'config/'.strtolower($class).'.php');
+ break;
+ }
+ elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).'.php'))
+ {
+ include($path .'config/'.ucfirst(strtolower($class)).'.php');
+ break;
+ }
+ }
}
}
-
+
if ($prefix == '')
- {
- if (class_exists('CI_'.$class))
+ {
+ if (class_exists('CI_'.$class))
{
$name = 'CI_'.$class;
}
- elseif (class_exists(config_item('subclass_prefix').$class))
+ elseif (class_exists(config_item('subclass_prefix').$class))
{
$name = config_item('subclass_prefix').$class;
}
@@ -893,18 +1064,18 @@ function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NU
{
$name = $prefix.$class;
}
-
+
// Is the class name valid?
if ( ! class_exists($name))
{
log_message('error', "Non-existent class: ".$name);
show_error("Non-existent class: ".$class);
}
-
+
// Set the variable name we will assign the class to
// Was a custom class name supplied? If so we'll use it
$class = strtolower($class);
-
+
if (is_null($object_name))
{
$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
@@ -914,68 +1085,83 @@ function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NU
$classvar = $object_name;
}
- // Save the class name and object name
+ // Save the class name and object name
$this->_ci_classes[$class] = $classvar;
- // Instantiate the class
+ // Instantiate the class
$CI =& get_instance();
if ($config !== NULL)
{
$CI->$classvar = new $name($config);
}
else
- {
+ {
$CI->$classvar = new $name;
- }
- }
-
+ }
+ }
+
// --------------------------------------------------------------------
-
+
/**
* Autoloader
*
* The config/autoload.php file contains an array that permits sub-systems,
- * libraries, plugins, and helpers to be loaded automatically.
+ * libraries, and helpers to be loaded automatically.
*
- * @access private
* @param array
* @return void
*/
- function _ci_autoloader()
- {
- include_once(APPPATH.'config/autoload'.EXT);
-
+ private function _ci_autoloader()
+ {
+ if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
+ {
+ include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
+ }
+ else
+ {
+ include(APPPATH.'config/autoload.php');
+ }
+
if ( ! isset($autoload))
{
return FALSE;
}
-
+
+ // Autoload packages
+ if (isset($autoload['packages']))
+ {
+ foreach ($autoload['packages'] as $package_path)
+ {
+ $this->add_package_path($package_path);
+ }
+ }
+
// Load any custom config file
if (count($autoload['config']) > 0)
- {
+ {
$CI =& get_instance();
foreach ($autoload['config'] as $key => $val)
{
$CI->config->load($val);
}
- }
+ }
- // Autoload plugins, helpers and languages
- foreach (array('helper', 'plugin', 'language') as $type)
- {
+ // Autoload helpers and languages
+ foreach (array('helper', 'language') as $type)
+ {
if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
{
$this->$type($autoload[$type]);
- }
+ }
}
// A little tweak to remain backward compatible
// The $autoload['core'] item was deprecated
- if ( ! isset($autoload['libraries']))
+ if ( ! isset($autoload['libraries']) AND isset($autoload['core']))
{
$autoload['libraries'] = $autoload['core'];
}
-
+
// Load libraries
if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
{
@@ -986,100 +1172,77 @@ function _ci_autoloader()
$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
}
- // Load scaffolding
- if (in_array('scaffolding', $autoload['libraries']))
- {
- $this->scaffolding();
- $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding'));
- }
-
// Load all other libraries
foreach ($autoload['libraries'] as $item)
{
$this->library($item);
}
- }
+ }
// Autoload models
if (isset($autoload['model']))
{
$this->model($autoload['model']);
}
-
}
-
+
// --------------------------------------------------------------------
/**
- * Assign to Models
+ * Object to Array
*
- * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
- * will be available to models, if any exist.
+ * Takes an object as input and converts the class variables to array key/vals
*
- * @access private
* @param object
* @return array
*/
- function _ci_assign_to_models()
+ protected function _ci_object_to_array($object)
{
- if (count($this->_ci_models) == 0)
- {
- return;
- }
-
- if ($this->_ci_is_instance())
- {
- $CI =& get_instance();
- foreach ($this->_ci_models as $model)
- {
- $CI->$model->_assign_libraries();
- }
- }
- else
- {
- foreach ($this->_ci_models as $model)
- {
- $this->$model->_assign_libraries();
- }
- }
- }
+ return (is_object($object)) ? get_object_vars($object) : $object;
+ }
// --------------------------------------------------------------------
/**
- * Object to Array
+ * Get a reference to a specific library or model
*
- * Takes an object as input and converts the class variables to array key/vals
- *
- * @access private
- * @param object
- * @return array
+ * @param string
+ * @return bool
*/
- function _ci_object_to_array($object)
+ protected function &_ci_get_component($component)
{
- return (is_object($object)) ? get_object_vars($object) : $object;
+ $CI =& get_instance();
+ return $CI->$component;
}
// --------------------------------------------------------------------
/**
- * Determines whether we should use the CI instance or $this
+ * Prep filename
*
- * @access private
- * @return bool
+ * This function preps the name of various items to make loading them more reliable.
+ *
+ * @param mixed
+ * @param string
+ * @return array
*/
- function _ci_is_instance()
+ protected function _ci_prep_filename($filename, $extension)
{
- if ($this->_ci_is_php5 == TRUE)
+ if ( ! is_array($filename))
{
- return TRUE;
+ return array(strtolower(str_replace('.php', '', str_replace($extension, '', $filename)).$extension));
}
-
- global $CI;
- return (is_object($CI)) ? TRUE : FALSE;
- }
+ else
+ {
+ foreach ($filename as $key => $val)
+ {
+ $filename[$key] = strtolower(str_replace('.php', '', str_replace($extension, '', $val)).$extension);
+ }
+ return $filename;
+ }
+ }
}
/* End of file Loader.php */
-/* Location: ./system/libraries/Loader.php */
\ No newline at end of file
+/* Location: ./system/core/Loader.php */
\ No newline at end of file
diff --git a/system/core/Model.php b/system/core/Model.php
new file mode 100755
index 00000000..e15ffbeb
--- /dev/null
+++ b/system/core/Model.php
@@ -0,0 +1,57 @@
+$key;
+ }
+}
+// END Model Class
+
+/* End of file Model.php */
+/* Location: ./system/core/Model.php */
\ No newline at end of file
diff --git a/system/libraries/Output.php b/system/core/Output.php
old mode 100644
new mode 100755
similarity index 61%
rename from system/libraries/Output.php
rename to system/core/Output.php
index f661a083..ccecafd2
--- a/system/libraries/Output.php
+++ b/system/core/Output.php
@@ -2,11 +2,11 @@
/**
* CodeIgniter
*
- * An open source application development framework for PHP 4.3.2 or newer
+ * An open source application development framework for PHP 5.1.6 or newer
*
* @package CodeIgniter
* @author ExpressionEngine Dev Team
- * @copyright Copyright (c) 2008 - 2009, EllisLab, Inc.
+ * @copyright Copyright (c) 2008 - 2011, EllisLab, Inc.
* @license http://codeigniter.com/user_guide/license.html
* @link http://codeigniter.com
* @since Version 1.0
@@ -28,19 +28,89 @@
*/
class CI_Output {
- var $final_output;
- var $cache_expiration = 0;
- var $headers = array();
- var $enable_profiler = FALSE;
-
+ /**
+ * Current output string
+ *
+ * @var string
+ * @access protected
+ */
+ protected $final_output;
+ /**
+ * Cache expiration time
+ *
+ * @var int
+ * @access protected
+ */
+ protected $cache_expiration = 0;
+ /**
+ * List of server headers
+ *
+ * @var array
+ * @access protected
+ */
+ protected $headers = array();
+ /**
+ * List of mime types
+ *
+ * @var array
+ * @access protected
+ */
+ protected $mime_types = array();
+ /**
+ * Determines wether profiler is enabled
+ *
+ * @var book
+ * @access protected
+ */
+ protected $enable_profiler = FALSE;
+ /**
+ * Determines if output compression is enabled
+ *
+ * @var bool
+ * @access protected
+ */
+ protected $_zlib_oc = FALSE;
+ /**
+ * List of profiler sections
+ *
+ * @var array
+ * @access protected
+ */
+ protected $_profiler_sections = array();
+ /**
+ * Whether or not to parse variables like {elapsed_time} and {memory_usage}
+ *
+ * @var bool
+ * @access protected
+ */
+ protected $parse_exec_vars = TRUE;
- function CI_Output()
+ /**
+ * Constructor
+ *
+ */
+ function __construct()
{
+ $this->_zlib_oc = @ini_get('zlib.output_compression');
+
+ // Get mime types for later
+ if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
+ {
+ include APPPATH.'config/'.ENVIRONMENT.'/mimes.php';
+ }
+ else
+ {
+ include APPPATH.'config/mimes.php';
+ }
+
+
+ $this->mime_types = $mimes;
+
log_message('debug', "Output Class Initialized");
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Get Output
*
@@ -48,14 +118,14 @@ function CI_Output()
*
* @access public
* @return string
- */
+ */
function get_output()
{
return $this->final_output;
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Set Output
*
@@ -64,10 +134,12 @@ function get_output()
* @access public
* @param string
* @return void
- */
+ */
function set_output($output)
{
$this->final_output = $output;
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -80,7 +152,7 @@ function set_output($output)
* @access public
* @param string
* @return void
- */
+ */
function append_output($output)
{
if ($this->final_output == '')
@@ -91,6 +163,8 @@ function append_output($output)
{
$this->final_output .= $output;
}
+
+ return $this;
}
// --------------------------------------------------------------------
@@ -105,59 +179,133 @@ function append_output($output)
*
* @access public
* @param string
+ * @param bool
* @return void
- */
+ */
function set_header($header, $replace = TRUE)
{
+ // If zlib.output_compression is enabled it will compress the output,
+ // but it will not modify the content-length header to compensate for
+ // the reduction, causing the browser to hang waiting for more data.
+ // We'll just skip content-length in those cases.
+
+ if ($this->_zlib_oc && strncasecmp($header, 'content-length', 14) == 0)
+ {
+ return;
+ }
+
$this->headers[] = array($header, $replace);
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Content Type Header
+ *
+ * @access public
+ * @param string extension of the file we're outputting
+ * @return void
+ */
+ function set_content_type($mime_type)
+ {
+ if (strpos($mime_type, '/') === FALSE)
+ {
+ $extension = ltrim($mime_type, '.');
+
+ // Is this extension supported?
+ if (isset($this->mime_types[$extension]))
+ {
+ $mime_type =& $this->mime_types[$extension];
+
+ if (is_array($mime_type))
+ {
+ $mime_type = current($mime_type);
+ }
+ }
+ }
+
+ $header = 'Content-Type: '.$mime_type;
+
+ $this->headers[] = array($header, TRUE);
+
+ return $this;
}
// --------------------------------------------------------------------
-
+
/**
* Set HTTP Status Header
* moved to Common procedural functions in 1.7.2
- *
+ *
* @access public
- * @param int the status code
- * @param string
+ * @param int the status code
+ * @param string
* @return void
- */
- function set_status_header($code = '200', $text = '')
+ */
+ function set_status_header($code = 200, $text = '')
{
set_status_header($code, $text);
+
+ return $this;
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Enable/disable Profiler
*
* @access public
* @param bool
* @return void
- */
+ */
function enable_profiler($val = TRUE)
{
$this->enable_profiler = (is_bool($val)) ? $val : TRUE;
+
+ return $this;
}
-
+
// --------------------------------------------------------------------
-
+
+ /**
+ * Set Profiler Sections
+ *
+ * Allows override of default / config settings for Profiler section display
+ *
+ * @access public
+ * @param array
+ * @return void
+ */
+ function set_profiler_sections($sections)
+ {
+ foreach ($sections as $section => $enable)
+ {
+ $this->_profiler_sections[$section] = ($enable !== FALSE) ? TRUE : FALSE;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
/**
* Set Cache
*
* @access public
* @param integer
* @return void
- */
+ */
function cache($time)
{
$this->cache_expiration = ( ! is_numeric($time)) ? 0 : $time;
+
+ return $this;
}
-
+
// --------------------------------------------------------------------
-
+
/**
* Display Output
*
@@ -170,17 +318,24 @@ function cache($time)
* benchmark timer so the page rendering speed and memory usage can be shown.
*
* @access public
+ * @param string
* @return mixed
- */
+ */
function _display($output = '')
- {
+ {
// Note: We use globals because we can't use $CI =& get_instance()
// since this function is sometimes called by the caching mechanism,
// which happens before the CI super object is available.
global $BM, $CFG;
-
+
+ // Grab the super object if we can.
+ if (class_exists('CI_Controller'))
+ {
+ $CI =& get_instance();
+ }
+
// --------------------------------------------------------------------
-
+
// Set the output data
if ($output == '')
{
@@ -188,28 +343,34 @@ function _display($output = '')
}
// --------------------------------------------------------------------
-
- // Do we need to write a cache file?
- if ($this->cache_expiration > 0)
+
+ // Do we need to write a cache file? Only if the controller does not have its
+ // own _output() method and we are not dealing with a cache file, which we
+ // can determine by the existence of the $CI object above
+ if ($this->cache_expiration > 0 && isset($CI) && ! method_exists($CI, '_output'))
{
$this->_write_cache($output);
}
-
+
// --------------------------------------------------------------------
// Parse out the elapsed time and memory usage,
// then swap the pseudo-variables with the data
- $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
- $output = str_replace('{elapsed_time}', $elapsed, $output);
-
- $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
- $output = str_replace('{memory_usage}', $memory, $output);
+ $elapsed = $BM->elapsed_time('total_execution_time_start', 'total_execution_time_end');
+
+ if ($this->parse_exec_vars === TRUE)
+ {
+ $memory = ( ! function_exists('memory_get_usage')) ? '0' : round(memory_get_usage()/1024/1024, 2).'MB';
+
+ $output = str_replace('{elapsed_time}', $elapsed, $output);
+ $output = str_replace('{memory_usage}', $memory, $output);
+ }
// --------------------------------------------------------------------
-
+
// Is compression requested?
- if ($CFG->item('compress_output') === TRUE)
+ if ($CFG->item('compress_output') === TRUE && $this->_zlib_oc == FALSE)
{
if (extension_loaded('zlib'))
{
@@ -221,7 +382,7 @@ function _display($output = '')
}
// --------------------------------------------------------------------
-
+
// Are there any server headers to send?
if (count($this->headers) > 0)
{
@@ -229,32 +390,34 @@ function _display($output = '')
{
@header($header[0], $header[1]);
}
- }
+ }
// --------------------------------------------------------------------
-
- // Does the get_instance() function exist?
+
+ // Does the $CI object exist?
// If not we know we are dealing with a cache file so we'll
// simply echo out the data and exit.
- if ( ! function_exists('get_instance'))
+ if ( ! isset($CI))
{
echo $output;
log_message('debug', "Final output sent to browser");
log_message('debug', "Total execution time: ".$elapsed);
return TRUE;
}
-
+
// --------------------------------------------------------------------
- // Grab the super object. We'll need it in a moment...
- $CI =& get_instance();
-
// Do we need to generate profile data?
// If so, load the Profile class and run it.
if ($this->enable_profiler == TRUE)
{
- $CI->load->library('profiler');
-
+ $CI->load->library('profiler');
+
+ if ( ! empty($this->_profiler_sections))
+ {
+ $CI->profiler->set_sections($this->_profiler_sections);
+ }
+
// If the output data contains closing