diff --git a/www-api/.editorconfig b/www-api/.editorconfig
new file mode 100644
index 00000000..39f48d95
--- /dev/null
+++ b/www-api/.editorconfig
@@ -0,0 +1,15 @@
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+# Matches multiple files with brace expansion notation
+# Set default charset
+[*]
+charset = utf-8
+
+# Tab indentation (no size specified)
+indent_style = tab
diff --git a/www-api/.gitignore b/www-api/.gitignore
new file mode 100644
index 00000000..323f0646
--- /dev/null
+++ b/www-api/.gitignore
@@ -0,0 +1,32 @@
+.DS_Store
+
+application/cache/*
+!application/cache/index.html
+
+application/logs/*
+!application/logs/index.html
+
+!application/*/.htaccess
+
+composer.lock
+tests/mocks/database/ci_test.sqlite
+
+user_guide_src/build/*
+user_guide_src/cilexer/build/*
+user_guide_src/cilexer/dist/*
+user_guide_src/cilexer/pycilexer.egg-info/*
+/vendor/
+
+# IDE Files
+#-------------------------
+/nbproject/
+.idea/*
+
+## Sublime Text cache files
+*.tmlanguage.cache
+*.tmPreferences.cache
+*.stTheme.cache
+*.sublime-workspace
+*.sublime-project
+/tests/tests/
+/tests/results/
diff --git a/www-api/apache_log/error.log b/www-api/apache_log/error.log
new file mode 100644
index 00000000..e15daaa1
--- /dev/null
+++ b/www-api/apache_log/error.log
@@ -0,0 +1,15 @@
+[Fri Nov 18 01:23:31.724975 2022] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.54 (Debian) PHP/7.4.33 configured -- resuming normal operations
+[Fri Nov 18 01:23:31.725362 2022] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
+[Fri Nov 18 01:28:30.448983 2022] [mpm_prefork:notice] [pid 1] AH00170: caught SIGWINCH, shutting down gracefully
+[Fri Nov 18 01:28:38.846502 2022] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.54 (Debian) PHP/7.4.33 configured -- resuming normal operations
+[Fri Nov 18 01:28:38.846765 2022] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
+[Fri Nov 18 01:43:30.493559 2022] [mpm_prefork:notice] [pid 1] AH00170: caught SIGWINCH, shutting down gracefully
+[Fri Nov 18 01:43:33.322175 2022] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.54 (Debian) PHP/7.4.33 configured -- resuming normal operations
+[Fri Nov 18 01:43:33.322469 2022] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
+[Fri Nov 18 01:43:48.896358 2022] [autoindex:error] [pid 18] [client 172.24.0.1:47222] AH01276: Cannot serve directory /var/www/html/public/svs/: No matching DirectoryIndex (index.php,index.html) found, and server-generated directory index forbidden by Options directive
+[Fri Nov 18 01:46:42.750129 2022] [mpm_prefork:notice] [pid 1] AH00170: caught SIGWINCH, shutting down gracefully
+[Fri Nov 18 01:46:45.512615 2022] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.54 (Debian) PHP/7.4.33 configured -- resuming normal operations
+[Fri Nov 18 01:46:45.512925 2022] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
+[Sat Nov 19 22:40:16.634065 2022] [mpm_prefork:notice] [pid 1] AH00170: caught SIGWINCH, shutting down gracefully
+[Sat Nov 19 23:00:20.141921 2022] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.54 (Debian) PHP/7.4.33 configured -- resuming normal operations
+[Sat Nov 19 23:00:20.142224 2022] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
diff --git a/www-api/apache_log/other_vhosts_access.log b/www-api/apache_log/other_vhosts_access.log
new file mode 100644
index 00000000..cedbcd55
--- /dev/null
+++ b/www-api/apache_log/other_vhosts_access.log
@@ -0,0 +1,18 @@
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:30:56 +0000] "GET / HTTP/1.1" 200 6388 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:30:57 +0000] "GET /favicon.ico HTTP/1.1" 200 5731 "http://localhost:9083/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:30:59 +0000] "GET / HTTP/1.1" 200 6387 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:31:48 +0000] "-" 408 0 "-" "-"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:43:48 +0000] "GET /svs/ HTTP/1.1" 403 416 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:43:54 +0000] "GET /svs/users/ HTTP/1.1" 301 507 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:43:54 +0000] "GET /svs/users HTTP/1.1" 404 2165 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:43:58 +0000] "GET /svs/users HTTP/1.1" 404 2165 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:44:33 +0000] "GET /svs/user/ HTTP/1.1" 400 3599 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:45:25 +0000] "-" 408 0 "-" "-"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:47:52 +0000] "GET /svs/user/ HTTP/1.1" 400 519 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:01:47:52 +0000] "GET /favicon.ico HTTP/1.1" 304 250 "http://localhost:9083/svs/user/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:02:27:41 +0000] "GET / HTTP/1.1" 200 6388 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:02:27:42 +0000] "GET /favicon.ico HTTP/1.1" 200 5731 "http://10.0.0.202:9083/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.24.0.1 - - [18/Nov/2022:02:28:34 +0000] "-" 408 0 "-" "-"
+wrenchboard-api:80 172.25.0.1 - - [19/Nov/2022:23:01:00 +0000] "GET / HTTP/1.1" 200 6388 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.25.0.1 - - [19/Nov/2022:23:01:01 +0000] "GET /favicon.ico HTTP/1.1" 200 5731 "http://localhost:9083/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36"
+wrenchboard-api:80 172.25.0.1 - - [19/Nov/2022:23:01:52 +0000] "-" 408 0 "-" "-"
diff --git a/www-api/application/.htaccess b/www-api/application/.htaccess
new file mode 100644
index 00000000..6c63ed4c
--- /dev/null
+++ b/www-api/application/.htaccess
@@ -0,0 +1,6 @@
+
+ Require all denied
+
+
+ Deny from all
+
\ No newline at end of file
diff --git a/www-api/application/cache/index.html b/www-api/application/cache/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/cache/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/config/autoload.php b/www-api/application/config/autoload.php
new file mode 100644
index 00000000..7cdc9013
--- /dev/null
+++ b/www-api/application/config/autoload.php
@@ -0,0 +1,135 @@
+ 'ua');
+*/
+$autoload['libraries'] = array();
+
+/*
+| -------------------------------------------------------------------
+| Auto-load Drivers
+| -------------------------------------------------------------------
+| These classes are located in system/libraries/ or in your
+| application/libraries/ directory, but are also placed inside their
+| own subdirectory and they extend the CI_Driver_Library class. They
+| offer multiple interchangeable driver options.
+|
+| Prototype:
+|
+| $autoload['drivers'] = array('cache');
+|
+| You can also supply an alternative property name to be assigned in
+| the controller:
+|
+| $autoload['drivers'] = array('cache' => 'cch');
+|
+*/
+$autoload['drivers'] = array();
+
+/*
+| -------------------------------------------------------------------
+| Auto-load Helper Files
+| -------------------------------------------------------------------
+| Prototype:
+|
+| $autoload['helper'] = array('url', 'file');
+*/
+$autoload['helper'] = array();
+
+/*
+| -------------------------------------------------------------------
+| Auto-load Config files
+| -------------------------------------------------------------------
+| Prototype:
+|
+| $autoload['config'] = array('config1', 'config2');
+|
+| NOTE: This item is intended for use ONLY if you have created custom
+| config files. Otherwise, leave it blank.
+|
+*/
+$autoload['config'] = array();
+
+/*
+| -------------------------------------------------------------------
+| Auto-load Language files
+| -------------------------------------------------------------------
+| Prototype:
+|
+| $autoload['language'] = array('lang1', 'lang2');
+|
+| NOTE: Do not include the "_lang" part of your file. For example
+| "codeigniter_lang.php" would be referenced as array('codeigniter');
+|
+*/
+$autoload['language'] = array();
+
+/*
+| -------------------------------------------------------------------
+| Auto-load Models
+| -------------------------------------------------------------------
+| Prototype:
+|
+| $autoload['model'] = array('first_model', 'second_model');
+|
+| You can also supply an alternative model name to be assigned
+| in the controller:
+|
+| $autoload['model'] = array('first_model' => 'first');
+*/
+$autoload['model'] = array();
diff --git a/www-api/application/config/config.php b/www-api/application/config/config.php
new file mode 100644
index 00000000..35ace5cc
--- /dev/null
+++ b/www-api/application/config/config.php
@@ -0,0 +1,532 @@
+]+$/i
+|
+| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
+|
+*/
+$config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-';
+
+/*
+|--------------------------------------------------------------------------
+| Enable Query Strings
+|--------------------------------------------------------------------------
+|
+| By default CodeIgniter uses search-engine friendly segment based URLs:
+| example.com/who/what/where/
+|
+| You can optionally enable standard query string based URLs:
+| example.com?who=me&what=something&where=here
+|
+| Options are: TRUE or FALSE (boolean)
+|
+| The other items let you set the query string 'words' that will
+| invoke your controllers and its functions:
+| example.com/index.php?c=controller&m=function
+|
+| Please note that some of the helpers won't work as expected when
+| this feature is enabled, since CodeIgniter is designed primarily to
+| use segment based URLs.
+|
+*/
+$config['enable_query_strings'] = FALSE;
+$config['controller_trigger'] = 'c';
+$config['function_trigger'] = 'm';
+$config['directory_trigger'] = 'd';
+
+/*
+|--------------------------------------------------------------------------
+| Allow $_GET array
+|--------------------------------------------------------------------------
+|
+| By default CodeIgniter enables access to the $_GET array. If for some
+| reason you would like to disable it, set 'allow_get_array' to FALSE.
+|
+| WARNING: This feature is DEPRECATED and currently available only
+| for backwards compatibility purposes!
+|
+*/
+$config['allow_get_array'] = TRUE;
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Threshold
+|--------------------------------------------------------------------------
+|
+| You can enable error logging by setting a threshold over zero. The
+| threshold determines what gets logged. Threshold options are:
+|
+| 0 = Disables logging, Error logging TURNED OFF
+| 1 = Error Messages (including PHP errors)
+| 2 = Debug Messages
+| 3 = Informational Messages
+| 4 = All Messages
+|
+| You can also pass an array with threshold levels to show individual error types
+|
+| array(2) = Debug Messages, without Error Messages
+|
+| For a live site you'll usually only enable Errors (1) to be logged otherwise
+| your log files will fill up very fast.
+|
+*/
+$config['log_threshold'] = 0;
+
+/*
+|--------------------------------------------------------------------------
+| Error Logging Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/logs/ directory. Use a full server path with trailing slash.
+|
+*/
+$config['log_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Log File Extension
+|--------------------------------------------------------------------------
+|
+| The default filename extension for log files. The default 'php' allows for
+| protecting the log files via basic scripting, when they are to be stored
+| under a publicly accessible directory.
+|
+| Note: Leaving it blank will default to 'php'.
+|
+*/
+$config['log_file_extension'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Log File Permissions
+|--------------------------------------------------------------------------
+|
+| The file system permissions to be applied on newly created log files.
+|
+| IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal
+| integer notation (i.e. 0700, 0644, etc.)
+*/
+$config['log_file_permissions'] = 0644;
+
+/*
+|--------------------------------------------------------------------------
+| Date Format for Logs
+|--------------------------------------------------------------------------
+|
+| Each item that is logged has an associated date. You can use PHP date
+| codes to set your own date formatting
+|
+*/
+$config['log_date_format'] = 'Y-m-d H:i:s';
+
+/*
+|--------------------------------------------------------------------------
+| Error Views Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/views/errors/ directory. Use a full server path with trailing slash.
+|
+*/
+$config['error_views_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Cache Directory Path
+|--------------------------------------------------------------------------
+|
+| Leave this BLANK unless you would like to set something other than the default
+| application/cache/ directory. Use a full server path with trailing slash.
+|
+*/
+$config['cache_path'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Cache Include Query String
+|--------------------------------------------------------------------------
+|
+| Whether to take the URL query string into consideration when generating
+| output cache files. Valid options are:
+|
+| FALSE = Disabled
+| TRUE = Enabled, take all query parameters into account.
+| Please be aware that this may result in numerous cache
+| files generated for the same page over and over again.
+| array('q') = Enabled, but only take into account the specified list
+| of query parameters.
+|
+*/
+$config['cache_query_string'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Encryption Key
+|--------------------------------------------------------------------------
+|
+| If you use the Encryption class, you must set an encryption key.
+| See the user guide for more info.
+|
+| https://codeigniter.com/userguide3/libraries/encryption.html
+|
+*/
+$config['encryption_key'] = '';
+
+/*
+|--------------------------------------------------------------------------
+| Session Variables
+|--------------------------------------------------------------------------
+|
+| 'sess_driver'
+|
+| The storage driver to use: files, database, redis, memcached
+|
+| 'sess_cookie_name'
+|
+| The session cookie name, must contain only [0-9a-z_-] characters
+|
+| 'sess_samesite'
+|
+| Session cookie SameSite attribute: Lax (default), Strict or None
+|
+| 'sess_expiration'
+|
+| The number of SECONDS you want the session to last.
+| Setting to 0 (zero) means expire when the browser is closed.
+|
+| 'sess_save_path'
+|
+| The location to save sessions to, driver dependent.
+|
+| For the 'files' driver, it's a path to a writable directory.
+| WARNING: Only absolute paths are supported!
+|
+| For the 'database' driver, it's a table name.
+| Please read up the manual for the format with other session drivers.
+|
+| IMPORTANT: You are REQUIRED to set a valid save path!
+|
+| 'sess_match_ip'
+|
+| Whether to match the user's IP address when reading the session data.
+|
+| WARNING: If you're using the database driver, don't forget to update
+| your session table's PRIMARY KEY when changing this setting.
+|
+| 'sess_time_to_update'
+|
+| How many seconds between CI regenerating the session ID.
+|
+| 'sess_regenerate_destroy'
+|
+| Whether to destroy session data associated with the old session ID
+| when auto-regenerating the session ID. When set to FALSE, the data
+| will be later deleted by the garbage collector.
+|
+| Other session cookie settings are shared with the rest of the application,
+| except for 'cookie_prefix' and 'cookie_httponly', which are ignored here.
+|
+*/
+$config['sess_driver'] = 'files';
+$config['sess_cookie_name'] = 'ci_session';
+$config['sess_samesite'] = 'Lax';
+$config['sess_expiration'] = 7200;
+$config['sess_save_path'] = NULL;
+$config['sess_match_ip'] = FALSE;
+$config['sess_time_to_update'] = 300;
+$config['sess_regenerate_destroy'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Cookie Related Variables
+|--------------------------------------------------------------------------
+|
+| 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions
+| 'cookie_domain' = Set to .your-domain.com for site-wide cookies
+| 'cookie_path' = Typically will be a forward slash
+| 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists.
+| 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript)
+| 'cookie_samesite' = Cookie's samesite attribute (Lax, Strict or None)
+|
+| Note: These settings (with the exception of 'cookie_prefix' and
+| 'cookie_httponly') will also affect sessions.
+|
+*/
+$config['cookie_prefix'] = '';
+$config['cookie_domain'] = '';
+$config['cookie_path'] = '/';
+$config['cookie_secure'] = FALSE;
+$config['cookie_httponly'] = FALSE;
+$config['cookie_samesite'] = 'Lax';
+
+/*
+|--------------------------------------------------------------------------
+| Standardize newlines
+|--------------------------------------------------------------------------
+|
+| Determines whether to standardize newline characters in input data,
+| meaning to replace \r\n, \r, \n occurrences with the PHP_EOL value.
+|
+| WARNING: This feature is DEPRECATED and currently available only
+| for backwards compatibility purposes!
+|
+*/
+$config['standardize_newlines'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Global XSS Filtering
+|--------------------------------------------------------------------------
+|
+| Determines whether the XSS filter is always active when GET, POST or
+| COOKIE data is encountered
+|
+| WARNING: This feature is DEPRECATED and currently available only
+| for backwards compatibility purposes!
+|
+*/
+$config['global_xss_filtering'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Cross Site Request Forgery
+|--------------------------------------------------------------------------
+| Enables a CSRF cookie token to be set. When set to TRUE, token will be
+| checked on a submitted form. If you are accepting user data, it is strongly
+| recommended CSRF protection be enabled.
+|
+| 'csrf_token_name' = The token name
+| 'csrf_cookie_name' = The cookie name
+| 'csrf_expire' = The number in seconds the token should expire.
+| 'csrf_regenerate' = Regenerate token on every submission
+| 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks
+*/
+$config['csrf_protection'] = FALSE;
+$config['csrf_token_name'] = 'csrf_test_name';
+$config['csrf_cookie_name'] = 'csrf_cookie_name';
+$config['csrf_expire'] = 7200;
+$config['csrf_regenerate'] = TRUE;
+$config['csrf_exclude_uris'] = array();
+
+/*
+|--------------------------------------------------------------------------
+| Output Compression
+|--------------------------------------------------------------------------
+|
+| Enables Gzip output compression for faster page loads. When enabled,
+| the output class will test whether your server supports Gzip.
+| Even if it does, however, not all browsers support compression
+| so enable only if you are reasonably sure your visitors can handle it.
+|
+| Only used if zlib.output_compression is turned off in your php.ini.
+| Please do not use it together with httpd-level output compression.
+|
+| VERY IMPORTANT: If you are getting a blank page when compression is enabled it
+| means you are prematurely outputting something to your browser. It could
+| even be a line of whitespace at the end of one of your scripts. For
+| compression to work, nothing can be sent before the output buffer is called
+| by the output class. Do not 'echo' any values with compression enabled.
+|
+*/
+$config['compress_output'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Master Time Reference
+|--------------------------------------------------------------------------
+|
+| Options are 'local' or any PHP supported timezone. This preference tells
+| the system whether to use your server's local time as the master 'now'
+| reference, or convert it to the configured one timezone. See the 'date
+| helper' page of the user guide for information regarding date handling.
+|
+*/
+$config['time_reference'] = 'local';
+
+/*
+|--------------------------------------------------------------------------
+| Rewrite PHP Short Tags
+|--------------------------------------------------------------------------
+|
+| If your PHP installation does not have short tag support enabled CI
+| can rewrite the tags on-the-fly, enabling you to utilize that syntax
+| in your view files. Options are TRUE or FALSE (boolean)
+|
+| Note: You need to have eval() enabled for this to work.
+|
+*/
+$config['rewrite_short_tags'] = FALSE;
+
+/*
+|--------------------------------------------------------------------------
+| Reverse Proxy IPs
+|--------------------------------------------------------------------------
+|
+| If your server is behind a reverse proxy, you must whitelist the proxy
+| IP addresses from which CodeIgniter should trust headers such as
+| HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify
+| the visitor's IP address.
+|
+| You can use both an array or a comma-separated list of proxy addresses,
+| as well as specifying whole subnets. Here are a few examples:
+|
+| Comma-separated: '10.0.1.200,192.168.5.0/24'
+| Array: array('10.0.1.200', '192.168.5.0/24')
+*/
+$config['proxy_ips'] = '';
diff --git a/www-api/application/config/constants.php b/www-api/application/config/constants.php
new file mode 100644
index 00000000..18d3b4b7
--- /dev/null
+++ b/www-api/application/config/constants.php
@@ -0,0 +1,85 @@
+db->last_query() and profiling of DB queries.
+| When you run a query, with this setting set to TRUE (default),
+| CodeIgniter will store the SQL statement for debugging purposes.
+| However, this may cause high memory usage, especially if you run
+| a lot of SQL queries ... disable this to avoid that problem.
+|
+| The $active_group variable lets you choose which connection group to
+| make active. By default there is only one group (the 'default' group).
+|
+| The $query_builder variables lets you determine whether or not to load
+| the query builder class.
+*/
+$active_group = 'default';
+$query_builder = TRUE;
+
+$db['default'] = array(
+ 'dsn' => '',
+ 'hostname' => 'localhost',
+ 'username' => '',
+ 'password' => '',
+ 'database' => '',
+ 'dbdriver' => 'mysqli',
+ 'dbprefix' => '',
+ 'pconnect' => FALSE,
+ 'db_debug' => (ENVIRONMENT !== 'production'),
+ 'cache_on' => FALSE,
+ 'cachedir' => '',
+ 'char_set' => 'utf8',
+ 'dbcollat' => 'utf8_general_ci',
+ 'swap_pre' => '',
+ 'encrypt' => FALSE,
+ 'compress' => FALSE,
+ 'stricton' => FALSE,
+ 'failover' => array(),
+ 'save_queries' => TRUE
+);
diff --git a/www-api/application/config/doctypes.php b/www-api/application/config/doctypes.php
new file mode 100644
index 00000000..59a7991e
--- /dev/null
+++ b/www-api/application/config/doctypes.php
@@ -0,0 +1,24 @@
+ '',
+ 'xhtml1-strict' => '',
+ 'xhtml1-trans' => '',
+ 'xhtml1-frame' => '',
+ 'xhtml-basic11' => '',
+ 'html5' => '',
+ 'html4-strict' => '',
+ 'html4-trans' => '',
+ 'html4-frame' => '',
+ 'mathml1' => '',
+ 'mathml2' => '',
+ 'svg10' => '',
+ 'svg11' => '',
+ 'svg11-basic' => '',
+ 'svg11-tiny' => '',
+ 'xhtml-math-svg-xh' => '',
+ 'xhtml-math-svg-sh' => '',
+ 'xhtml-rdfa-1' => '',
+ 'xhtml-rdfa-2' => ''
+);
diff --git a/www-api/application/config/foreign_chars.php b/www-api/application/config/foreign_chars.php
new file mode 100644
index 00000000..0231f359
--- /dev/null
+++ b/www-api/application/config/foreign_chars.php
@@ -0,0 +1,114 @@
+ 'ae',
+ '/ö|œ/' => 'oe',
+ '/ü/' => 'ue',
+ '/Ä/' => 'Ae',
+ '/Ü/' => 'Ue',
+ '/Ö/' => 'Oe',
+ '/À|Á|Â|Ã|Ä|Å|Ǻ|Ā|Ă|Ą|Ǎ|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|А/' => 'A',
+ '/à|á|â|ã|å|ǻ|ā|ă|ą|ǎ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a',
+ '/Б/' => 'B',
+ '/б/' => 'b',
+ '/Ç|Ć|Ĉ|Ċ|Č/' => 'C',
+ '/ç|ć|ĉ|ċ|č/' => 'c',
+ '/Д|Δ/' => 'D',
+ '/д|δ/' => 'd',
+ '/Ð|Ď|Đ/' => 'Dj',
+ '/ð|ď|đ/' => 'dj',
+ '/È|É|Ê|Ë|Ē|Ĕ|Ė|Ę|Ě|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E',
+ '/è|é|ê|ë|ē|ĕ|ė|ę|ě|έ|ε|ẽ|ẻ|ẹ|ề|ế|ễ|ể|ệ|е|э/' => 'e',
+ '/Ф/' => 'F',
+ '/ф/' => 'f',
+ '/Ĝ|Ğ|Ġ|Ģ|Γ|Г|Ґ/' => 'G',
+ '/ĝ|ğ|ġ|ģ|γ|г|ґ/' => 'g',
+ '/Ĥ|Ħ/' => 'H',
+ '/ĥ|ħ/' => 'h',
+ '/Ì|Í|Î|Ï|Ĩ|Ī|Ĭ|Ǐ|Į|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I',
+ '/ì|í|î|ï|ĩ|ī|ĭ|ǐ|į|ı|η|ή|ί|ι|ϊ|ỉ|ị|и|ы|ї/' => 'i',
+ '/Ĵ/' => 'J',
+ '/ĵ/' => 'j',
+ '/Θ/' => 'TH',
+ '/θ/' => 'th',
+ '/Ķ|Κ|К/' => 'K',
+ '/ķ|κ|к/' => 'k',
+ '/Ĺ|Ļ|Ľ|Ŀ|Ł|Λ|Л/' => 'L',
+ '/ĺ|ļ|ľ|ŀ|ł|λ|л/' => 'l',
+ '/М/' => 'M',
+ '/м/' => 'm',
+ '/Ñ|Ń|Ņ|Ň|Ν|Н/' => 'N',
+ '/ñ|ń|ņ|ň|ʼn|ν|н/' => 'n',
+ '/Ò|Ó|Ô|Õ|Ō|Ŏ|Ǒ|Ő|Ơ|Ø|Ǿ|Ο|Ό|Ω|Ώ|Ỏ|Ọ|Ồ|Ố|Ỗ|Ổ|Ộ|Ờ|Ớ|Ỡ|Ở|Ợ|О/' => 'O',
+ '/ò|ó|ô|õ|ō|ŏ|ǒ|ő|ơ|ø|ǿ|º|ο|ό|ω|ώ|ỏ|ọ|ồ|ố|ỗ|ổ|ộ|ờ|ớ|ỡ|ở|ợ|о/' => 'o',
+ '/П/' => 'P',
+ '/п/' => 'p',
+ '/Ŕ|Ŗ|Ř|Ρ|Р/' => 'R',
+ '/ŕ|ŗ|ř|ρ|р/' => 'r',
+ '/Ś|Ŝ|Ş|Ș|Š|Σ|С/' => 'S',
+ '/ś|ŝ|ş|ș|š|ſ|σ|ς|с/' => 's',
+ '/Ț|Ţ|Ť|Ŧ|Τ|Т/' => 'T',
+ '/ț|ţ|ť|ŧ|τ|т/' => 't',
+ '/Þ|þ/' => 'th',
+ '/Ù|Ú|Û|Ũ|Ū|Ŭ|Ů|Ű|Ų|Ư|Ǔ|Ǖ|Ǘ|Ǚ|Ǜ|Ũ|Ủ|Ụ|Ừ|Ứ|Ữ|Ử|Ự|У/' => 'U',
+ '/ù|ú|û|ũ|ū|ŭ|ů|ű|ų|ư|ǔ|ǖ|ǘ|ǚ|ǜ|υ|ύ|ϋ|ủ|ụ|ừ|ứ|ữ|ử|ự|у/' => 'u',
+ '/Ƴ|Ɏ|Ỵ|Ẏ|Ӳ|Ӯ|Ў|Ý|Ÿ|Ŷ|Υ|Ύ|Ϋ|Ỳ|Ỹ|Ỷ|Ỵ|Й/' => 'Y',
+ '/ẙ|ʏ|ƴ|ɏ|ỵ|ẏ|ӳ|ӯ|ў|ý|ÿ|ŷ|ỳ|ỹ|ỷ|ỵ|й/' => 'y',
+ '/В/' => 'V',
+ '/в/' => 'v',
+ '/Ŵ/' => 'W',
+ '/ŵ/' => 'w',
+ '/Φ/' => 'F',
+ '/φ/' => 'f',
+ '/Χ/' => 'CH',
+ '/χ/' => 'ch',
+ '/Ź|Ż|Ž|Ζ|З/' => 'Z',
+ '/ź|ż|ž|ζ|з/' => 'z',
+ '/Æ|Ǽ/' => 'AE',
+ '/ß/' => 'ss',
+ '/IJ/' => 'IJ',
+ '/ij/' => 'ij',
+ '/Œ/' => 'OE',
+ '/ƒ/' => 'f',
+ '/Ξ/' => 'KS',
+ '/ξ/' => 'ks',
+ '/Π/' => 'P',
+ '/π/' => 'p',
+ '/Β/' => 'V',
+ '/β/' => 'v',
+ '/Μ/' => 'M',
+ '/μ/' => 'm',
+ '/Ψ/' => 'PS',
+ '/ψ/' => 'ps',
+ '/Ё/' => 'Yo',
+ '/ё/' => 'yo',
+ '/Є/' => 'Ye',
+ '/є/' => 'ye',
+ '/Ї/' => 'Yi',
+ '/Ж/' => 'Zh',
+ '/ж/' => 'zh',
+ '/Х/' => 'Kh',
+ '/х/' => 'kh',
+ '/Ц/' => 'Ts',
+ '/ц/' => 'ts',
+ '/Ч/' => 'Ch',
+ '/ч/' => 'ch',
+ '/Ш/' => 'Sh',
+ '/ш/' => 'sh',
+ '/Щ/' => 'Shch',
+ '/щ/' => 'shch',
+ '/Ъ|ъ|Ь|ь/' => '',
+ '/Ю/' => 'Yu',
+ '/ю/' => 'yu',
+ '/Я/' => 'Ya',
+ '/я/' => 'ya'
+);
diff --git a/www-api/application/config/hooks.php b/www-api/application/config/hooks.php
new file mode 100644
index 00000000..79c5c162
--- /dev/null
+++ b/www-api/application/config/hooks.php
@@ -0,0 +1,13 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/config/memcached.php b/www-api/application/config/memcached.php
new file mode 100644
index 00000000..65a14961
--- /dev/null
+++ b/www-api/application/config/memcached.php
@@ -0,0 +1,19 @@
+ array(
+ 'hostname' => '127.0.0.1',
+ 'port' => '11211',
+ 'weight' => '1',
+ ),
+);
diff --git a/www-api/application/config/migration.php b/www-api/application/config/migration.php
new file mode 100644
index 00000000..4b585a65
--- /dev/null
+++ b/www-api/application/config/migration.php
@@ -0,0 +1,84 @@
+migration->current() this is the version that schema will
+| be upgraded / downgraded to.
+|
+*/
+$config['migration_version'] = 0;
+
+/*
+|--------------------------------------------------------------------------
+| Migrations Path
+|--------------------------------------------------------------------------
+|
+| Path to your migrations folder.
+| Typically, it will be within your application path.
+| Also, writing permission is required within the migrations path.
+|
+*/
+$config['migration_path'] = APPPATH.'migrations/';
diff --git a/www-api/application/config/mimes.php b/www-api/application/config/mimes.php
new file mode 100644
index 00000000..b2e989fe
--- /dev/null
+++ b/www-api/application/config/mimes.php
@@ -0,0 +1,186 @@
+ array('application/mac-binhex40', 'application/mac-binhex', 'application/x-binhex40', 'application/x-mac-binhex40'),
+ 'cpt' => 'application/mac-compactpro',
+ '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', 'text/plain'),
+ 'bin' => array('application/macbinary', 'application/mac-binary', 'application/octet-stream', 'application/x-binary', 'application/x-macbinary'),
+ 'dms' => 'application/octet-stream',
+ 'lha' => 'application/octet-stream',
+ 'lzh' => 'application/octet-stream',
+ 'exe' => array('application/octet-stream', 'application/x-msdownload'),
+ 'class' => 'application/octet-stream',
+ 'psd' => array('application/x-photoshop', 'image/vnd.adobe.photoshop'),
+ 'so' => 'application/octet-stream',
+ 'sea' => 'application/octet-stream',
+ 'dll' => 'application/octet-stream',
+ 'oda' => 'application/oda',
+ 'pdf' => array('application/pdf', 'application/force-download', 'application/x-download', 'binary/octet-stream'),
+ 'ai' => array('application/pdf', 'application/postscript'),
+ 'eps' => 'application/postscript',
+ 'ps' => 'application/postscript',
+ 'smi' => 'application/smil',
+ 'smil' => 'application/smil',
+ 'mif' => 'application/vnd.mif',
+ 'xls' => array('application/vnd.ms-excel', 'application/msexcel', 'application/x-msexcel', 'application/x-ms-excel', 'application/x-excel', 'application/x-dos_ms_excel', 'application/xls', 'application/x-xls', 'application/excel', 'application/download', 'application/vnd.ms-office', 'application/msword'),
+ 'ppt' => array('application/powerpoint', 'application/vnd.ms-powerpoint', 'application/vnd.ms-office', 'application/msword'),
+ 'pptx' => array('application/vnd.openxmlformats-officedocument.presentationml.presentation', 'application/x-zip', 'application/zip'),
+ 'wbxml' => 'application/wbxml',
+ 'wmlc' => 'application/wmlc',
+ 'dcr' => 'application/x-director',
+ 'dir' => 'application/x-director',
+ 'dxr' => 'application/x-director',
+ 'dvi' => 'application/x-dvi',
+ 'gtar' => 'application/x-gtar',
+ 'gz' => 'application/x-gzip',
+ 'gzip' => 'application/x-gzip',
+ 'php' => array('application/x-httpd-php', 'application/php', 'application/x-php', 'text/php', 'text/x-php', 'application/x-httpd-php-source'),
+ 'php4' => 'application/x-httpd-php',
+ 'php3' => 'application/x-httpd-php',
+ 'phtml' => 'application/x-httpd-php',
+ 'phps' => 'application/x-httpd-php-source',
+ 'js' => array('application/x-javascript', 'text/plain'),
+ 'swf' => 'application/x-shockwave-flash',
+ 'sit' => 'application/x-stuffit',
+ 'tar' => 'application/x-tar',
+ 'tgz' => array('application/x-tar', 'application/x-gzip-compressed'),
+ 'z' => 'application/x-compress',
+ 'xhtml' => 'application/xhtml+xml',
+ 'xht' => 'application/xhtml+xml',
+ 'zip' => array('application/x-zip', 'application/zip', 'application/x-zip-compressed', 'application/s-compressed', 'multipart/x-zip'),
+ 'rar' => array('application/x-rar', 'application/rar', 'application/x-rar-compressed'),
+ 'mid' => 'audio/midi',
+ 'midi' => 'audio/midi',
+ 'mpga' => 'audio/mpeg',
+ 'mp2' => 'audio/mpeg',
+ 'mp3' => array('audio/mpeg', 'audio/mpg', 'audio/mpeg3', 'audio/mp3'),
+ 'aif' => array('audio/x-aiff', 'audio/aiff'),
+ 'aiff' => array('audio/x-aiff', 'audio/aiff'),
+ 'aifc' => 'audio/x-aiff',
+ 'ram' => 'audio/x-pn-realaudio',
+ 'rm' => 'audio/x-pn-realaudio',
+ 'rpm' => 'audio/x-pn-realaudio-plugin',
+ 'ra' => 'audio/x-realaudio',
+ 'rv' => 'video/vnd.rn-realvideo',
+ 'wav' => array('audio/x-wav', 'audio/wave', 'audio/wav'),
+ 'bmp' => array('image/bmp', 'image/x-bmp', 'image/x-bitmap', 'image/x-xbitmap', 'image/x-win-bitmap', 'image/x-windows-bmp', 'image/ms-bmp', 'image/x-ms-bmp', 'application/bmp', 'application/x-bmp', 'application/x-win-bitmap'),
+ 'gif' => 'image/gif',
+ 'jpeg' => array('image/jpeg', 'image/pjpeg'),
+ 'jpg' => array('image/jpeg', 'image/pjpeg'),
+ 'jpe' => array('image/jpeg', 'image/pjpeg'),
+ 'jp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'j2k' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'jpf' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'jpg2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'jpx' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'jpm' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'mj2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'mjp2' => array('image/jp2', 'video/mj2', 'image/jpx', 'image/jpm'),
+ 'png' => array('image/png', 'image/x-png'),
+ 'tiff' => 'image/tiff',
+ 'tif' => 'image/tiff',
+ 'heic' => 'image/heic',
+ 'heif' => 'image/heif',
+ 'css' => array('text/css', 'text/plain'),
+ 'html' => array('text/html', 'text/plain'),
+ 'htm' => array('text/html', 'text/plain'),
+ 'shtml' => array('text/html', 'text/plain'),
+ 'txt' => 'text/plain',
+ 'text' => 'text/plain',
+ 'log' => array('text/plain', 'text/x-log'),
+ 'rtx' => 'text/richtext',
+ 'rtf' => 'text/rtf',
+ 'xml' => array('application/xml', 'text/xml', 'text/plain'),
+ 'xsl' => array('application/xml', 'text/xsl', 'text/xml'),
+ 'mpeg' => 'video/mpeg',
+ 'mpg' => 'video/mpeg',
+ 'mpe' => 'video/mpeg',
+ 'qt' => 'video/quicktime',
+ 'mov' => 'video/quicktime',
+ 'avi' => array('video/x-msvideo', 'video/msvideo', 'video/avi', 'application/x-troff-msvideo'),
+ 'movie' => 'video/x-sgi-movie',
+ 'doc' => array('application/msword', 'application/vnd.ms-office'),
+ 'docx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword', 'application/x-zip'),
+ 'dot' => array('application/msword', 'application/vnd.ms-office'),
+ 'dotx' => array('application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/zip', 'application/msword'),
+ 'xlsx' => array('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/zip', 'application/vnd.ms-excel', 'application/msword', 'application/x-zip'),
+ 'word' => array('application/msword', 'application/octet-stream'),
+ 'xl' => 'application/excel',
+ 'eml' => 'message/rfc822',
+ 'json' => array('application/json', 'text/json'),
+ 'pem' => array('application/x-x509-user-cert', 'application/x-pem-file', 'application/octet-stream'),
+ 'p10' => array('application/x-pkcs10', 'application/pkcs10'),
+ 'p12' => 'application/x-pkcs12',
+ 'p7a' => 'application/x-pkcs7-signature',
+ 'p7c' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
+ 'p7m' => array('application/pkcs7-mime', 'application/x-pkcs7-mime'),
+ 'p7r' => 'application/x-pkcs7-certreqresp',
+ 'p7s' => 'application/pkcs7-signature',
+ 'crt' => array('application/x-x509-ca-cert', 'application/x-x509-user-cert', 'application/pkix-cert'),
+ 'crl' => array('application/pkix-crl', 'application/pkcs-crl'),
+ 'der' => 'application/x-x509-ca-cert',
+ 'kdb' => 'application/octet-stream',
+ 'pgp' => 'application/pgp',
+ 'gpg' => 'application/gpg-keys',
+ 'sst' => 'application/octet-stream',
+ 'csr' => 'application/octet-stream',
+ 'rsa' => 'application/x-pkcs7',
+ 'cer' => array('application/pkix-cert', 'application/x-x509-ca-cert'),
+ '3g2' => 'video/3gpp2',
+ '3gp' => array('video/3gp', 'video/3gpp'),
+ 'mp4' => 'video/mp4',
+ 'm4a' => 'audio/x-m4a',
+ 'f4v' => array('video/mp4', 'video/x-f4v'),
+ 'flv' => 'video/x-flv',
+ 'webm' => 'video/webm',
+ 'aac' => array('audio/x-aac', 'audio/aac'),
+ 'm4u' => 'application/vnd.mpegurl',
+ 'm3u' => 'text/plain',
+ 'xspf' => 'application/xspf+xml',
+ 'vlc' => 'application/videolan',
+ 'wmv' => array('video/x-ms-wmv', 'video/x-ms-asf'),
+ 'au' => 'audio/x-au',
+ 'ac3' => 'audio/ac3',
+ 'flac' => 'audio/x-flac',
+ 'ogg' => array('audio/ogg', 'video/ogg', 'application/ogg'),
+ 'kmz' => array('application/vnd.google-earth.kmz', 'application/zip', 'application/x-zip'),
+ 'kml' => array('application/vnd.google-earth.kml+xml', 'application/xml', 'text/xml'),
+ 'ics' => 'text/calendar',
+ 'ical' => 'text/calendar',
+ 'zsh' => 'text/x-scriptzsh',
+ '7z' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'),
+ '7zip' => array('application/x-7z-compressed', 'application/x-compressed', 'application/x-zip-compressed', 'application/zip', 'multipart/x-zip'),
+ 'cdr' => array('application/cdr', 'application/coreldraw', 'application/x-cdr', 'application/x-coreldraw', 'image/cdr', 'image/x-cdr', 'zz-application/zz-winassoc-cdr'),
+ 'wma' => array('audio/x-ms-wma', 'video/x-ms-asf'),
+ 'jar' => array('application/java-archive', 'application/x-java-application', 'application/x-jar', 'application/x-compressed'),
+ 'svg' => array('image/svg+xml', 'image/svg', 'application/xml', 'text/xml'),
+ 'vcf' => 'text/x-vcard',
+ 'srt' => array('text/srt', 'text/plain'),
+ 'vtt' => array('text/vtt', 'text/plain'),
+ 'ico' => array('image/x-icon', 'image/x-ico', 'image/vnd.microsoft.icon'),
+ 'odc' => 'application/vnd.oasis.opendocument.chart',
+ 'otc' => 'application/vnd.oasis.opendocument.chart-template',
+ 'odf' => 'application/vnd.oasis.opendocument.formula',
+ 'otf' => 'application/vnd.oasis.opendocument.formula-template',
+ 'odg' => 'application/vnd.oasis.opendocument.graphics',
+ 'otg' => 'application/vnd.oasis.opendocument.graphics-template',
+ 'odi' => 'application/vnd.oasis.opendocument.image',
+ 'oti' => 'application/vnd.oasis.opendocument.image-template',
+ 'odp' => 'application/vnd.oasis.opendocument.presentation',
+ 'otp' => 'application/vnd.oasis.opendocument.presentation-template',
+ 'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
+ 'ots' => 'application/vnd.oasis.opendocument.spreadsheet-template',
+ 'odt' => 'application/vnd.oasis.opendocument.text',
+ 'odm' => 'application/vnd.oasis.opendocument.text-master',
+ 'ott' => 'application/vnd.oasis.opendocument.text-template',
+ 'oth' => 'application/vnd.oasis.opendocument.text-web'
+);
diff --git a/www-api/application/config/profiler.php b/www-api/application/config/profiler.php
new file mode 100644
index 00000000..3436e931
--- /dev/null
+++ b/www-api/application/config/profiler.php
@@ -0,0 +1,14 @@
+ my_controller/index
+| my-controller/my-method -> my_controller/my_method
+*/
+$route['default_controller'] = 'welcome';
+$route['404_override'] = '';
+$route['translate_uri_dashes'] = FALSE;
diff --git a/www-api/application/config/smileys.php b/www-api/application/config/smileys.php
new file mode 100644
index 00000000..a9b9191c
--- /dev/null
+++ b/www-api/application/config/smileys.php
@@ -0,0 +1,64 @@
+ array('grin.gif', '19', '19', 'grin'),
+ ':lol:' => array('lol.gif', '19', '19', 'LOL'),
+ ':cheese:' => array('cheese.gif', '19', '19', 'cheese'),
+ ':)' => array('smile.gif', '19', '19', 'smile'),
+ ';-)' => array('wink.gif', '19', '19', 'wink'),
+ ';)' => array('wink.gif', '19', '19', 'wink'),
+ ':smirk:' => array('smirk.gif', '19', '19', 'smirk'),
+ ':roll:' => array('rolleyes.gif', '19', '19', 'rolleyes'),
+ ':-S' => array('confused.gif', '19', '19', 'confused'),
+ ':wow:' => array('surprise.gif', '19', '19', 'surprised'),
+ ':bug:' => array('bigsurprise.gif', '19', '19', 'big surprise'),
+ ':-P' => array('tongue_laugh.gif', '19', '19', 'tongue laugh'),
+ '%-P' => array('tongue_rolleye.gif', '19', '19', 'tongue rolleye'),
+ ';-P' => array('tongue_wink.gif', '19', '19', 'tongue wink'),
+ ':P' => array('raspberry.gif', '19', '19', 'raspberry'),
+ ':blank:' => array('blank.gif', '19', '19', 'blank stare'),
+ ':long:' => array('longface.gif', '19', '19', 'long face'),
+ ':ohh:' => array('ohh.gif', '19', '19', 'ohh'),
+ ':grrr:' => array('grrr.gif', '19', '19', 'grrr'),
+ ':gulp:' => array('gulp.gif', '19', '19', 'gulp'),
+ '8-/' => array('ohoh.gif', '19', '19', 'oh oh'),
+ ':down:' => array('downer.gif', '19', '19', 'downer'),
+ ':red:' => array('embarrassed.gif', '19', '19', 'red face'),
+ ':sick:' => array('sick.gif', '19', '19', 'sick'),
+ ':shut:' => array('shuteye.gif', '19', '19', 'shut eye'),
+ ':-/' => array('hmm.gif', '19', '19', 'hmmm'),
+ '>:(' => array('mad.gif', '19', '19', 'mad'),
+ ':mad:' => array('mad.gif', '19', '19', 'mad'),
+ '>:-(' => array('angry.gif', '19', '19', 'angry'),
+ ':angry:' => array('angry.gif', '19', '19', 'angry'),
+ ':zip:' => array('zip.gif', '19', '19', 'zipper'),
+ ':kiss:' => array('kiss.gif', '19', '19', 'kiss'),
+ ':ahhh:' => array('shock.gif', '19', '19', 'shock'),
+ ':coolsmile:' => array('shade_smile.gif', '19', '19', 'cool smile'),
+ ':coolsmirk:' => array('shade_smirk.gif', '19', '19', 'cool smirk'),
+ ':coolgrin:' => array('shade_grin.gif', '19', '19', 'cool grin'),
+ ':coolhmm:' => array('shade_hmm.gif', '19', '19', 'cool hmm'),
+ ':coolmad:' => array('shade_mad.gif', '19', '19', 'cool mad'),
+ ':coolcheese:' => array('shade_cheese.gif', '19', '19', 'cool cheese'),
+ ':vampire:' => array('vampire.gif', '19', '19', 'vampire'),
+ ':snake:' => array('snake.gif', '19', '19', 'snake'),
+ ':exclaim:' => array('exclaim.gif', '19', '19', 'exclaim'),
+ ':question:' => array('question.gif', '19', '19', 'question')
+
+);
diff --git a/www-api/application/config/user_agents.php b/www-api/application/config/user_agents.php
new file mode 100644
index 00000000..5e1f6afb
--- /dev/null
+++ b/www-api/application/config/user_agents.php
@@ -0,0 +1,222 @@
+ 'Windows 10',
+ 'windows nt 6.3' => 'Windows 8.1',
+ 'windows nt 6.2' => 'Windows 8',
+ 'windows nt 6.1' => 'Windows 7',
+ 'windows nt 6.0' => 'Windows Vista',
+ 'windows nt 5.2' => 'Windows 2003',
+ 'windows nt 5.1' => 'Windows XP',
+ 'windows nt 5.0' => 'Windows 2000',
+ 'windows nt 4.0' => 'Windows NT 4.0',
+ 'winnt4.0' => 'Windows NT 4.0',
+ 'winnt 4.0' => 'Windows NT',
+ 'winnt' => 'Windows NT',
+ 'windows 98' => 'Windows 98',
+ 'win98' => 'Windows 98',
+ 'windows 95' => 'Windows 95',
+ 'win95' => 'Windows 95',
+ 'windows phone' => 'Windows Phone',
+ 'windows' => 'Unknown Windows OS',
+ 'android' => 'Android',
+ 'blackberry' => 'BlackBerry',
+ 'iphone' => 'iOS',
+ 'ipad' => 'iOS',
+ 'ipod' => 'iOS',
+ 'os x' => 'Mac OS X',
+ 'ppc mac' => 'Power PC Mac',
+ 'freebsd' => 'FreeBSD',
+ 'ppc' => 'Macintosh',
+ 'linux' => 'Linux',
+ 'debian' => 'Debian',
+ 'sunos' => 'Sun Solaris',
+ 'beos' => 'BeOS',
+ 'apachebench' => 'ApacheBench',
+ 'aix' => 'AIX',
+ 'irix' => 'Irix',
+ 'osf' => 'DEC OSF',
+ 'hp-ux' => 'HP-UX',
+ 'netbsd' => 'NetBSD',
+ 'bsdi' => 'BSDi',
+ 'openbsd' => 'OpenBSD',
+ 'gnu' => 'GNU/Linux',
+ 'unix' => 'Unknown Unix OS',
+ 'symbian' => 'Symbian OS'
+);
+
+
+// The order of this array should NOT be changed. Many browsers return
+// multiple browser types so we want to identify the sub-type first.
+$browsers = array(
+ 'OPR' => 'Opera',
+ 'Flock' => 'Flock',
+ 'Edge' => 'Edge',
+ 'Chrome' => 'Chrome',
+ // Opera 10+ always reports Opera/9.80 and appends Version/ to the user agent string
+ 'Opera.*?Version' => 'Opera',
+ 'Opera' => 'Opera',
+ 'MSIE' => 'Internet Explorer',
+ 'Internet Explorer' => 'Internet Explorer',
+ 'Trident.* rv' => 'Internet Explorer',
+ 'Shiira' => 'Shiira',
+ 'Firefox' => 'Firefox',
+ 'Chimera' => 'Chimera',
+ 'Phoenix' => 'Phoenix',
+ 'Firebird' => 'Firebird',
+ 'Camino' => 'Camino',
+ 'Netscape' => 'Netscape',
+ 'OmniWeb' => 'OmniWeb',
+ 'Safari' => 'Safari',
+ 'Mozilla' => 'Mozilla',
+ 'Konqueror' => 'Konqueror',
+ 'icab' => 'iCab',
+ 'Lynx' => 'Lynx',
+ 'Links' => 'Links',
+ 'hotjava' => 'HotJava',
+ 'amaya' => 'Amaya',
+ 'IBrowse' => 'IBrowse',
+ 'Maxthon' => 'Maxthon',
+ 'Ubuntu' => 'Ubuntu Web Browser'
+);
+
+$mobiles = array(
+ // legacy array, old values commented out
+ 'mobileexplorer' => 'Mobile Explorer',
+// 'openwave' => 'Open Wave',
+// 'opera mini' => 'Opera Mini',
+// 'operamini' => 'Opera Mini',
+// 'elaine' => 'Palm',
+ 'palmsource' => 'Palm',
+// 'digital paths' => 'Palm',
+// 'avantgo' => 'Avantgo',
+// 'xiino' => 'Xiino',
+ 'palmscape' => 'Palmscape',
+// 'nokia' => 'Nokia',
+// 'ericsson' => 'Ericsson',
+// 'blackberry' => 'BlackBerry',
+// 'motorola' => 'Motorola'
+
+ // Phones and Manufacturers
+ 'motorola' => 'Motorola',
+ 'nokia' => 'Nokia',
+ 'nexus' => 'Nexus',
+ 'palm' => 'Palm',
+ 'iphone' => 'Apple iPhone',
+ 'ipad' => 'iPad',
+ 'ipod' => 'Apple iPod Touch',
+ 'sony' => 'Sony Ericsson',
+ 'ericsson' => 'Sony Ericsson',
+ 'blackberry' => 'BlackBerry',
+ 'cocoon' => 'O2 Cocoon',
+ 'blazer' => 'Treo',
+ 'lg' => 'LG',
+ 'amoi' => 'Amoi',
+ 'xda' => 'XDA',
+ 'mda' => 'MDA',
+ 'vario' => 'Vario',
+ 'htc' => 'HTC',
+ 'samsung' => 'Samsung',
+ 'sharp' => 'Sharp',
+ 'sie-' => 'Siemens',
+ 'alcatel' => 'Alcatel',
+ 'benq' => 'BenQ',
+ 'ipaq' => 'HP iPaq',
+ 'mot-' => 'Motorola',
+ 'playstation portable' => 'PlayStation Portable',
+ 'playstation 3' => 'PlayStation 3',
+ 'playstation vita' => 'PlayStation Vita',
+ 'hiptop' => 'Danger Hiptop',
+ 'nec-' => 'NEC',
+ 'panasonic' => 'Panasonic',
+ 'philips' => 'Philips',
+ 'sagem' => 'Sagem',
+ 'sanyo' => 'Sanyo',
+ 'spv' => 'SPV',
+ 'zte' => 'ZTE',
+ 'sendo' => 'Sendo',
+ 'nintendo dsi' => 'Nintendo DSi',
+ 'nintendo ds' => 'Nintendo DS',
+ 'nintendo 3ds' => 'Nintendo 3DS',
+ 'wii' => 'Nintendo Wii',
+ 'open web' => 'Open Web',
+ 'openweb' => 'OpenWeb',
+ 'meizu' => 'Meizu',
+ 'huawei' => 'Huawei',
+ 'xiaomi' => 'Xiaomi',
+ 'oppo' => 'Oppo',
+ 'vivo' => 'Vivo',
+ 'infinix' => 'Infinix',
+
+ // Operating Systems
+ 'android' => 'Android',
+ 'symbian' => 'Symbian',
+ 'SymbianOS' => 'SymbianOS',
+ 'elaine' => 'Palm',
+ 'series60' => 'Symbian S60',
+ 'windows ce' => 'Windows CE',
+
+ // Browsers
+ 'obigo' => 'Obigo',
+ 'netfront' => 'Netfront Browser',
+ 'openwave' => 'Openwave Browser',
+ 'mobilexplorer' => 'Mobile Explorer',
+ 'operamini' => 'Opera Mini',
+ 'opera mini' => 'Opera Mini',
+ 'opera mobi' => 'Opera Mobile',
+ 'fennec' => 'Firefox Mobile',
+
+ // Other
+ 'digital paths' => 'Digital Paths',
+ 'avantgo' => 'AvantGo',
+ 'xiino' => 'Xiino',
+ 'novarra' => 'Novarra Transcoder',
+ 'vodafone' => 'Vodafone',
+ 'docomo' => 'NTT DoCoMo',
+ 'o2' => 'O2',
+
+ // Fallback
+ 'mobile' => 'Generic Mobile',
+ 'wireless' => 'Generic Mobile',
+ 'j2me' => 'Generic Mobile',
+ 'midp' => 'Generic Mobile',
+ 'cldc' => 'Generic Mobile',
+ 'up.link' => 'Generic Mobile',
+ 'up.browser' => 'Generic Mobile',
+ 'smartphone' => 'Generic Mobile',
+ 'cellphone' => 'Generic Mobile'
+);
+
+// There are hundreds of bots but these are the most common.
+$robots = array(
+ 'googlebot' => 'Googlebot',
+ 'msnbot' => 'MSNBot',
+ 'baiduspider' => 'Baiduspider',
+ 'bingbot' => 'Bing',
+ 'slurp' => 'Inktomi Slurp',
+ 'yahoo' => 'Yahoo',
+ 'ask jeeves' => 'Ask Jeeves',
+ 'fastcrawler' => 'FastCrawler',
+ 'infoseek' => 'InfoSeek Robot 1.0',
+ 'lycos' => 'Lycos',
+ 'yandex' => 'YandexBot',
+ 'mediapartners-google' => 'MediaPartners Google',
+ 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler',
+ 'adsbot-google' => 'AdsBot Google',
+ 'feedfetcher-google' => 'Feedfetcher Google',
+ 'curious george' => 'Curious George',
+ 'ia_archiver' => 'Alexa Crawler',
+ 'MJ12bot' => 'Majestic-12',
+ 'Uptimebot' => 'Uptimebot',
+ 'UptimeRobot' => 'UptimeRobot'
+);
diff --git a/www-api/application/controllers/Welcome.php b/www-api/application/controllers/Welcome.php
new file mode 100644
index 00000000..5f82771b
--- /dev/null
+++ b/www-api/application/controllers/Welcome.php
@@ -0,0 +1,25 @@
+
+ * @see https://codeigniter.com/userguide3/general/urls.html
+ */
+ public function index()
+ {
+ $this->load->view('welcome_message');
+ }
+}
diff --git a/www-api/application/controllers/index.html b/www-api/application/controllers/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/controllers/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/core/index.html b/www-api/application/core/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/core/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/helpers/index.html b/www-api/application/helpers/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/helpers/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/hooks/index.html b/www-api/application/hooks/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/hooks/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/index.html b/www-api/application/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/language/english/index.html b/www-api/application/language/english/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/language/english/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/language/index.html b/www-api/application/language/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/language/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/libraries/index.html b/www-api/application/libraries/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/libraries/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/logs/index.html b/www-api/application/logs/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/logs/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/models/index.html b/www-api/application/models/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/models/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/third_party/index.html b/www-api/application/third_party/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/third_party/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/views/errors/cli/error_404.php b/www-api/application/views/errors/cli/error_404.php
new file mode 100644
index 00000000..6984b61e
--- /dev/null
+++ b/www-api/application/views/errors/cli/error_404.php
@@ -0,0 +1,8 @@
+
+
+An uncaught Exception was encountered
+
+Type:
+Message:
+Filename: getFile(), "\n"; ?>
+Line Number: getLine(); ?>
+
+
+
+Backtrace:
+getTrace() as $error): ?>
+
+ File:
+ Line:
+ Function:
+
+
+
+
diff --git a/www-api/application/views/errors/cli/error_general.php b/www-api/application/views/errors/cli/error_general.php
new file mode 100644
index 00000000..6984b61e
--- /dev/null
+++ b/www-api/application/views/errors/cli/error_general.php
@@ -0,0 +1,8 @@
+
+
+A PHP Error was encountered
+
+Severity:
+Message:
+Filename:
+Line Number:
+
+
+
+Backtrace:
+
+
+ File:
+ Line:
+ Function:
+
+
+
+
diff --git a/www-api/application/views/errors/cli/index.html b/www-api/application/views/errors/cli/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/views/errors/cli/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/views/errors/html/error_404.php b/www-api/application/views/errors/html/error_404.php
new file mode 100644
index 00000000..756ea9d6
--- /dev/null
+++ b/www-api/application/views/errors/html/error_404.php
@@ -0,0 +1,64 @@
+
+
+
+
+404 Page Not Found
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/www-api/application/views/errors/html/error_db.php b/www-api/application/views/errors/html/error_db.php
new file mode 100644
index 00000000..f5a43f63
--- /dev/null
+++ b/www-api/application/views/errors/html/error_db.php
@@ -0,0 +1,64 @@
+
+
+
+
+Database Error
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/www-api/application/views/errors/html/error_exception.php b/www-api/application/views/errors/html/error_exception.php
new file mode 100644
index 00000000..87848866
--- /dev/null
+++ b/www-api/application/views/errors/html/error_exception.php
@@ -0,0 +1,32 @@
+
+
+
+
+
An uncaught Exception was encountered
+
+
Type:
+
Message:
+
Filename: getFile(); ?>
+
Line Number: getLine(); ?>
+
+
+
+
Backtrace:
+ getTrace() as $error): ?>
+
+
+
+
+ File:
+ Line:
+ Function:
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/www-api/application/views/errors/html/error_general.php b/www-api/application/views/errors/html/error_general.php
new file mode 100644
index 00000000..fc3b2eba
--- /dev/null
+++ b/www-api/application/views/errors/html/error_general.php
@@ -0,0 +1,64 @@
+
+
+
+
+Error
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/www-api/application/views/errors/html/error_php.php b/www-api/application/views/errors/html/error_php.php
new file mode 100644
index 00000000..b146f9c5
--- /dev/null
+++ b/www-api/application/views/errors/html/error_php.php
@@ -0,0 +1,33 @@
+
+
+
+
+
A PHP Error was encountered
+
+
Severity:
+
Message:
+
Filename:
+
Line Number:
+
+
+
+
Backtrace:
+
+
+
+
+
+ File:
+ Line:
+ Function:
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/www-api/application/views/errors/html/index.html b/www-api/application/views/errors/html/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/views/errors/html/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/views/errors/index.html b/www-api/application/views/errors/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/views/errors/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/views/index.html b/www-api/application/views/index.html
new file mode 100644
index 00000000..b702fbc3
--- /dev/null
+++ b/www-api/application/views/index.html
@@ -0,0 +1,11 @@
+
+
+
+ 403 Forbidden
+
+
+
+Directory access is forbidden.
+
+
+
diff --git a/www-api/application/views/welcome_message.php b/www-api/application/views/welcome_message.php
new file mode 100644
index 00000000..9db22bc5
--- /dev/null
+++ b/www-api/application/views/welcome_message.php
@@ -0,0 +1,100 @@
+
+
+
+
+ Welcome to CodeIgniter
+
+
+
+
+
+
+
Welcome to CodeIgniter!
+
+
+
The page you are looking at is being generated dynamically by CodeIgniter.
+
+
If you would like to edit this page you'll find it located at:
+
application/views/welcome_message.php
+
+
The corresponding controller for this page is found at:
+
application/controllers/Welcome.php
+
+
If you are exploring CodeIgniter for the very first time, you should start by reading the User Guide.
+
+
+
+
+
+
+
diff --git a/www-api/composer.json b/www-api/composer.json
new file mode 100644
index 00000000..01e65f40
--- /dev/null
+++ b/www-api/composer.json
@@ -0,0 +1,35 @@
+{
+ "description": "The CodeIgniter framework",
+ "name": "codeigniter/framework",
+ "type": "project",
+ "homepage": "https://codeigniter.com",
+ "license": "MIT",
+ "support": {
+ "forum": "http://forum.codeigniter.com/",
+ "wiki": "https://github.com/bcit-ci/CodeIgniter/wiki",
+ "slack": "https://codeigniterchat.slack.com",
+ "source": "https://github.com/bcit-ci/CodeIgniter"
+ },
+ "require": {
+ "php": ">=5.3.7"
+ },
+ "suggest": {
+ "paragonie/random_compat": "Provides better randomness in PHP 5.x"
+ },
+ "scripts": {
+ "test:coverage": [
+ "@putenv XDEBUG_MODE=coverage",
+ "phpunit --color=always --coverage-text --configuration tests/travis/sqlite.phpunit.xml"
+ ],
+ "post-install-cmd": [
+ "sed -i s/name{0}/name[0]/ vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php"
+ ],
+ "post-update-cmd": [
+ "sed -i s/name{0}/name[0]/ vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php"
+ ]
+ },
+ "require-dev": {
+ "mikey179/vfsstream": "1.6.*",
+ "phpunit/phpunit": "4.* || 5.* || 9.*"
+ }
+}
diff --git a/www-api/index.php b/www-api/index.php
new file mode 100644
index 00000000..11f8c628
--- /dev/null
+++ b/www-api/index.php
@@ -0,0 +1,315 @@
+='))
+ {
+ error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED & ~E_STRICT & ~E_USER_NOTICE & ~E_USER_DEPRECATED);
+ }
+ else
+ {
+ error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_USER_NOTICE);
+ }
+ break;
+
+ default:
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'The application environment is not set correctly.';
+ exit(1); // EXIT_ERROR
+}
+
+/*
+ *---------------------------------------------------------------
+ * SYSTEM DIRECTORY NAME
+ *---------------------------------------------------------------
+ *
+ * This variable must contain the name of your "system" directory.
+ * Set the path if it is not in the same directory as this file.
+ */
+ $system_path = 'system';
+
+/*
+ *---------------------------------------------------------------
+ * APPLICATION DIRECTORY NAME
+ *---------------------------------------------------------------
+ *
+ * If you want this front controller to use a different "application"
+ * directory than the default one you can set its name here. The directory
+ * can also be renamed or relocated anywhere on your server. If you do,
+ * use an absolute (full) server path.
+ * For more info please see the user guide:
+ *
+ * https://codeigniter.com/userguide3/general/managing_apps.html
+ *
+ * NO TRAILING SLASH!
+ */
+ $application_folder = 'application';
+
+/*
+ *---------------------------------------------------------------
+ * VIEW DIRECTORY NAME
+ *---------------------------------------------------------------
+ *
+ * If you want to move the view directory out of the application
+ * directory, set the path to it here. The directory can be renamed
+ * and relocated anywhere on your server. If blank, it will default
+ * to the standard location inside your application directory.
+ * If you do move this, use an absolute (full) server path.
+ *
+ * NO TRAILING SLASH!
+ */
+ $view_folder = '';
+
+
+/*
+ * --------------------------------------------------------------------
+ * DEFAULT CONTROLLER
+ * --------------------------------------------------------------------
+ *
+ * Normally you will set your default controller in the routes.php file.
+ * You can, however, force a custom routing by hard-coding a
+ * specific controller class/function here. For most applications, you
+ * WILL NOT set your routing here, but it's an option for those
+ * special instances where you might want to override the standard
+ * routing in a specific front controller that shares a common CI installation.
+ *
+ * IMPORTANT: If you set the routing here, NO OTHER controller will be
+ * callable. In essence, this preference limits your application to ONE
+ * specific controller. Leave the function name blank if you need
+ * to call functions dynamically via the URI.
+ *
+ * Un-comment the $routing array below to use this feature
+ */
+ // The directory name, relative to the "controllers" directory. Leave blank
+ // if your controller is not in a sub-directory within the "controllers" one
+ // $routing['directory'] = '';
+
+ // The controller class file name. Example: mycontroller
+ // $routing['controller'] = '';
+
+ // The controller function you wish to be called.
+ // $routing['function'] = '';
+
+
+/*
+ * -------------------------------------------------------------------
+ * CUSTOM CONFIG VALUES
+ * -------------------------------------------------------------------
+ *
+ * The $assign_to_config array below will be passed dynamically to the
+ * config class when initialized. This allows you to set custom config
+ * items or override any default config values found in the config.php file.
+ * This can be handy as it permits you to share one application between
+ * multiple front controller files, with each file containing different
+ * config values.
+ *
+ * Un-comment the $assign_to_config array below to use this feature
+ */
+ // $assign_to_config['name_of_config_item'] = 'value of config item';
+
+
+
+// --------------------------------------------------------------------
+// END OF USER CONFIGURABLE SETTINGS. DO NOT EDIT BELOW THIS LINE
+// --------------------------------------------------------------------
+
+/*
+ * ---------------------------------------------------------------
+ * Resolve the system path for increased reliability
+ * ---------------------------------------------------------------
+ */
+
+ // Set the current directory correctly for CLI requests
+ if (defined('STDIN'))
+ {
+ chdir(dirname(__FILE__));
+ }
+
+ if (($_temp = realpath($system_path)) !== FALSE)
+ {
+ $system_path = $_temp.DIRECTORY_SEPARATOR;
+ }
+ else
+ {
+ // Ensure there's a trailing slash
+ $system_path = strtr(
+ rtrim($system_path, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ ).DIRECTORY_SEPARATOR;
+ }
+
+ // Is the system path correct?
+ if ( ! is_dir($system_path))
+ {
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'Your system folder path does not appear to be set correctly. Please open the following file and correct this: '.pathinfo(__FILE__, PATHINFO_BASENAME);
+ exit(3); // EXIT_CONFIG
+ }
+
+/*
+ * -------------------------------------------------------------------
+ * Now that we know the path, set the main path constants
+ * -------------------------------------------------------------------
+ */
+ // The name of THIS file
+ define('SELF', pathinfo(__FILE__, PATHINFO_BASENAME));
+
+ // Path to the system directory
+ define('BASEPATH', $system_path);
+
+ // Path to the front controller (this file) directory
+ define('FCPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
+
+ // Name of the "system" directory
+ define('SYSDIR', basename(BASEPATH));
+
+ // The path to the "application" directory
+ if (is_dir($application_folder))
+ {
+ if (($_temp = realpath($application_folder)) !== FALSE)
+ {
+ $application_folder = $_temp;
+ }
+ else
+ {
+ $application_folder = strtr(
+ rtrim($application_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ }
+ elseif (is_dir(BASEPATH.$application_folder.DIRECTORY_SEPARATOR))
+ {
+ $application_folder = BASEPATH.strtr(
+ trim($application_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ else
+ {
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'Your application folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
+ exit(3); // EXIT_CONFIG
+ }
+
+ define('APPPATH', $application_folder.DIRECTORY_SEPARATOR);
+
+ // The path to the "views" directory
+ if ( ! isset($view_folder[0]) && is_dir(APPPATH.'views'.DIRECTORY_SEPARATOR))
+ {
+ $view_folder = APPPATH.'views';
+ }
+ elseif (is_dir($view_folder))
+ {
+ if (($_temp = realpath($view_folder)) !== FALSE)
+ {
+ $view_folder = $_temp;
+ }
+ else
+ {
+ $view_folder = strtr(
+ rtrim($view_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ }
+ elseif (is_dir(APPPATH.$view_folder.DIRECTORY_SEPARATOR))
+ {
+ $view_folder = APPPATH.strtr(
+ trim($view_folder, '/\\'),
+ '/\\',
+ DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR
+ );
+ }
+ else
+ {
+ header('HTTP/1.1 503 Service Unavailable.', TRUE, 503);
+ echo 'Your view folder path does not appear to be set correctly. Please open the following file and correct this: '.SELF;
+ exit(3); // EXIT_CONFIG
+ }
+
+ define('VIEWPATH', $view_folder.DIRECTORY_SEPARATOR);
+
+/*
+ * --------------------------------------------------------------------
+ * LOAD THE BOOTSTRAP FILE
+ * --------------------------------------------------------------------
+ *
+ * And away we go...
+ */
+require_once BASEPATH.'core/CodeIgniter.php';
diff --git a/www-api/license.txt b/www-api/license.txt
new file mode 100644
index 00000000..82be622d
--- /dev/null
+++ b/www-api/license.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2019 - 2022, CodeIgniter Foundation
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/www-api/public/.htaccess b/www-api/public/.htaccess
deleted file mode 100644
index a5d6c2a5..00000000
--- a/www-api/public/.htaccess
+++ /dev/null
@@ -1,49 +0,0 @@
-# Disable directory browsing
-Options All -Indexes
-
-# ----------------------------------------------------------------------
-# Rewrite engine
-# ----------------------------------------------------------------------
-
-# Turning on the rewrite engine is necessary for the following rules and features.
-# FollowSymLinks must be enabled for this to work.
-
- Options +FollowSymlinks
- RewriteEngine On
-
- # If you installed CodeIgniter in a subfolder, you will need to
- # change the following line to match the subfolder you need.
- # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase
- # RewriteBase /
-
- # Redirect Trailing Slashes...
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteCond %{REQUEST_URI} (.+)/$
- RewriteRule ^ %1 [L,R=301]
-
- # Rewrite "www.example.com -> example.com"
- RewriteCond %{HTTPS} !=on
- RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
- RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
-
- # Checks to see if the user is attempting to access a valid file,
- # such as an image or css document, if this isn't true it sends the
- # request to the front controller, index.php
- RewriteCond %{REQUEST_FILENAME} !-f
- RewriteCond %{REQUEST_FILENAME} !-d
- RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA]
-
- # Ensure Authorization header is passed along
- RewriteCond %{HTTP:Authorization} .
- RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
-
-
-
- # If we don't have mod_rewrite installed, all 404's
- # can be sent to index.php, and everything works as normal.
- ErrorDocument 404 index.php
-
-
-# Disable server signature start
- ServerSignature Off
-# Disable server signature end
diff --git a/www-api/public/backend.php b/www-api/public/backend.php
new file mode 100644
index 00000000..b7eb8386
--- /dev/null
+++ b/www-api/public/backend.php
@@ -0,0 +1,97 @@
+USER = $USER;
+ }
+
+ public function wrenchboard_api($in, $out = array()) {
+ if (!is_array($in)) {
+ $in = array();
+ }
+ if (!is_array($out)) {
+ $out = array();
+ }
+ if (self::DEBUG_API_CALLS) {
+ $stack = debug_backtrace();
+ $log = json_encode($stack);
+ error_log($log);
+ error_log(json_encode($in));
+ }
+ $this->wrenchboard_load();
+ return $this->wrenchboard->wrenchboard_api($in, $out);
+ }
+
+ public function logMessage($in) {
+ if ($in == null || trim($in) == "") {
+ return null;
+ }
+ if (self::DEBUG_API_CALLS) {
+ $stack = debug_backtrace();
+ $log = json_encode($stack);
+ error_log($log);
+ error_log($in);
+ }
+ $this->wrenchboard_load();
+ return $this->wrenchboard->logMessage($in);
+ }
+
+ public function cfgReadChar($in) {
+ if ($in == null || trim($in) == "") {
+ return null;
+ }
+ if (self::DEBUG_API_CALLS) {
+ $stack = debug_backtrace();
+ $log = json_encode($stack);
+ error_log($log);
+ error_log($in);
+ }
+ $this->wrenchboard_load();
+ return $this->wrenchboard->cfgReadChar($in);
+ }
+
+ public function cfgReadLong($in) {
+ if ($in == null || trim($in) == "") {
+ return 0;
+ }
+ if (self::DEBUG_API_CALLS) {
+ $stack = debug_backtrace();
+ $log = json_encode($stack);
+ error_log($log);
+ error_log($in);
+ }
+ $this->wrenchboard_load();
+ return $this->wrenchboard->cfgReadLong($in);
+ }
+
+ private function wrenchboard_load() {
+// global $wrenchboard;
+ // $this->$USER = $_SERVER['SCRIPT_FILENAME'];
+ $wrenchboard_class = 'wrenchboard_api_' . $this->USER . '\\WrenchBoard';
+ if (!is_object($this->wrenchboard)) {
+ $this->wrenchboard = new $wrenchboard_class();
+ }
+/* if (is_object($wrenchboard) && is_object($wrenchboard->wrenchboard)) {
+ $this->wrenchboard = $wrenchboard->wrenchboard;
+ } else if (is_object($wrenchboard)) {
+ $this->wrenchboard = $wrenchboard;
+ } else if (!is_object($this->wrenchboard)) {
+ $this->wrenchboard = new $wrenchboard_class();
+ }
+*/
+ }
+ }
+ global $wrenchboard;
+ $wrenchboard = new WrenchBoardAPIWrapper();
+}
+?>
diff --git a/www-api/public/favicon.ico b/www-api/public/favicon.ico
deleted file mode 100644
index 7ecfce21..00000000
Binary files a/www-api/public/favicon.ico and /dev/null differ
diff --git a/www-api/public/index.php b/www-api/public/index.php
deleted file mode 100644
index 96e7f45f..00000000
--- a/www-api/public/index.php
+++ /dev/null
@@ -1,67 +0,0 @@
-systemDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'bootstrap.php';
-
-// Load environment settings from .env files into $_SERVER and $_ENV
-require_once SYSTEMPATH . 'Config/DotEnv.php';
-(new CodeIgniter\Config\DotEnv(ROOTPATH))->load();
-
-/*
- * ---------------------------------------------------------------
- * GRAB OUR CODEIGNITER INSTANCE
- * ---------------------------------------------------------------
- *
- * The CodeIgniter class contains the core functionality to make
- * the application run, and does all of the dirty work to get
- * the pieces all working together.
- */
-
-$app = Config\Services::codeigniter();
-$app->initialize();
-$context = is_cli() ? 'php-cli' : 'web';
-$app->setContext($context);
-
-/*
- *---------------------------------------------------------------
- * LAUNCH THE APPLICATION
- *---------------------------------------------------------------
- * Now that everything is setup, it's time to actually fire
- * up the engines and make this app do its thang.
- */
-
-$app->run();
diff --git a/www-api/public/robots.txt b/www-api/public/robots.txt
deleted file mode 100644
index 9e60f970..00000000
--- a/www-api/public/robots.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-User-agent: *
-Disallow:
diff --git a/www-api/public/svs/api/.htaccess b/www-api/public/svs/api/.htaccess
new file mode 100644
index 00000000..1939eddc
--- /dev/null
+++ b/www-api/public/svs/api/.htaccess
@@ -0,0 +1,22 @@
+
+
+RewriteEngine On
+RewriteBase /svs/api/
+#RewriteBase /
+
+#Checks to
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^(.*)$ index.php?endpoint=$1 [L,NC,QSA]
+
+
+
+
+ # If we don't have mod_rewrite installed, all 404's
+ # can be sent to index.php, and everything works as normal.
+ # Submitted by: ElliotHaughin
+
+ErrorDocument 404 /index.php
+
+
+
diff --git a/www-api/public/svs/api/index.php b/www-api/public/svs/api/index.php
new file mode 100644
index 00000000..908848f2
--- /dev/null
+++ b/www-api/public/svs/api/index.php
@@ -0,0 +1,2 @@
+ array('POST'),
+ 'generics' => array('POST')
+);
+
+header("Access-Control-Allow-Origin: *");
+header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
+header("Access-Control-Allow-Headers: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
+header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
+header('Content-type: application/json');
+
+if ("OPTIONS" === $_SERVER['REQUEST_METHOD']) {
+ exit();
+}
+
+$endpoint = strtolower(str_replace('/svs/user/', '', strtok($_SERVER['REQUEST_URI'], '?')));
+
+$id = 0; // update, get & delete actions require ID
+if (substr($endpoint, 0, 19) == 'gettransportrequest' || substr($endpoint, 0, 13) == 'updateprofile') {
+ $endpoint = strtok($endpoint, '/');
+ $id = strtok('/');
+}
+
+if (!isset($endpoints[$endpoint])) {
+ header('HTTP/1.1 400 Bad Request');
+ header('Status: 400 Bad Request');
+ echo "{\"status\":\"Invalid endpoint url WRB\"}";
+ exit();
+}
+
+$methods = $endpoints[$endpoint];
+
+if (array_search($_SERVER['REQUEST_METHOD'], $methods) === false) {
+ header('HTTP/1.1 405 Method Not Allowed');
+ header('Status: 405 Method Not Allowed');
+ echo "{\"status\":\"Invalid request method\"}";
+ exit();
+}
+
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ $in = flatten(json_decode(file_get_contents('php://input'), true));
+}
+if ($_SERVER["REQUEST_METHOD"] == "PUT") {
+ parse_str(file_get_contents('php://input'), $in);
+}
+if ($_SERVER["REQUEST_METHOD"] == "GET") {
+ $in = $_GET;
+}
+$in["loc"] = $_SERVER["REMOTE_ADDR"];
+switch ($endpoint) {
+ case 'generics':
+ case 'apigate':
+ //$in["action"] = WRENCHBOARD_ACCOUNT_LOGIN;
+ break;
+}
+
+
+
+$in["pid"] = 100;
+$out = array();
+$ret = $wrenchboard->wrenchboard_api($in, $out);
+$out['internal_return'] = $ret; // this is reserved array parameter - to be caprured and reoved before you use the out array()
+
+header("HTTP/1.1 200 OK");
+header("Status: 200 OK");
+//$out = array_merge($in, $out); // DEBUG
+echo json_encode(processOutJson($in, $out));
+exit();
+
+function flatten($data, $parentkey = "") {
+ $result = array();
+ foreach ($data as $key => $val) {
+ if (is_array($val)) {
+ $result = array_merge($result, flatten($val, $parentkey . $key . "_"));
+ } else {
+ $result[$parentkey . $key] = $val;
+ }
+ }
+ return $result;
+}
+
+
diff --git a/www-api/public/svs/bko/.htaccess b/www-api/public/svs/bko/.htaccess
new file mode 100644
index 00000000..07c8e917
--- /dev/null
+++ b/www-api/public/svs/bko/.htaccess
@@ -0,0 +1,21 @@
+
+
+RewriteEngine On
+RewriteBase /svs/bko/
+
+#Checks to
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^(.*)$ bkove.php?endpoint=$1 [L,NC,QSA]
+
+
+
+
+ # If we don't have mod_rewrite installed, all 404's
+ # can be sent to index.php, and everything works as normal.
+ # Submitted by: ElliotHaughin
+
+ErrorDocument 404 /bkove.php
+
+
+
diff --git a/www-api/public/svs/bko/bkove.php b/www-api/public/svs/bko/bkove.php
new file mode 100644
index 00000000..b21b33fc
--- /dev/null
+++ b/www-api/public/svs/bko/bkove.php
@@ -0,0 +1,105 @@
+ array('POST')
+);
+
+$call_backend = true; // sometimes we need to overwite the call to the extenstion API
+$local_out = []; // use local out to send output when the result is not from the extenstion
+$ret = -1;
+
+//echo "Ameye 000 9";
+//exit();
+
+header("Access-Control-Allow-Origin: *");
+header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
+header("Access-Control-Allow-Headers: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
+header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
+header('Content-type: application/json');
+
+if ("OPTIONS" === $_SERVER['REQUEST_METHOD']) {
+ exit();
+}
+
+$endpoint = strtolower(str_replace('/svs/bko/', '', strtok($_SERVER['REQUEST_URI'], '?')));
+
+$id = 0; // update, get & delete actions require ID
+if (substr($endpoint, 0, 19) == 'gettransportrequest' || substr($endpoint, 0, 13) == 'updateprofile') {
+ $endpoint = strtok($endpoint, '/');
+ $id = strtok('/');
+}
+
+if (!isset($endpoints[$endpoint])) {
+ header('HTTP/1.1 400 Bad Request');
+ header('Status: 400 Bad Request');
+ echo "{\"status\":\"Invalid endpoint url WRB\"}";
+ exit();
+}
+
+$methods = $endpoints[$endpoint];
+
+if (array_search($_SERVER['REQUEST_METHOD'], $methods) === false) {
+ header('HTTP/1.1 405 Method Not Allowed');
+ header('Status: 405 Method Not Allowed');
+ echo "{\"status\":\"Invalid request method\"}";
+ exit();
+}
+
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ $in = flatten(json_decode(file_get_contents('php://input'), true));
+}
+if ($_SERVER["REQUEST_METHOD"] == "PUT") {
+ parse_str(file_get_contents('php://input'), $in);
+}
+if ($_SERVER["REQUEST_METHOD"] == "GET") {
+ $in = $_GET;
+}
+$in["loc"] = $_SERVER["REMOTE_ADDR"];
+switch ($endpoint) {
+ case 'generics':
+ break;
+}
+
+
+
+$in["pid"] = 100;
+
+//file_put_contents("in_debug.log", $in); // DEBUG
+
+$out = array();
+if ( $call_backend == true){
+ $ret = $wrenchboard->wrenchboard_api($in, $out);
+ $out['internal_return'] = $ret; // this is reserved array parameter - to be captured and received before you use the out array()
+}
+else
+{
+ $out = $local_out;
+}
+
+
+header("HTTP/1.1 200 OK");
+header("Status: 200 OK");
+//$out = array_merge($in, $out); // DEBUG
+echo json_encode(processOutJson($in, $out));
+exit();
+
+function flatten($data, $parentkey = "") {
+ $result = array();
+ foreach ($data as $key => $val) {
+ if (is_array($val)) {
+ $result = array_merge($result, flatten($val, $parentkey . $key . "_"));
+ } else {
+ $result[$parentkey . $key] = $val;
+ }
+ }
+ return $result;
+}
+
+
+// vi:ts=2
diff --git a/www-api/public/svs/config.php b/www-api/public/svs/config.php
new file mode 100644
index 00000000..8a6df5f6
--- /dev/null
+++ b/www-api/public/svs/config.php
@@ -0,0 +1,4 @@
+
diff --git a/www-api/public/svs/constants.php b/www-api/public/svs/constants.php
new file mode 100644
index 00000000..19821bb0
--- /dev/null
+++ b/www-api/public/svs/constants.php
@@ -0,0 +1,226 @@
+ $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "assign_id" => $out["assign_id_${key}"],
+ "title" => $out["title_${key}"],
+ "description" => $out["description_${key}"],
+ "card_type" => $out["card_type_${key}"],
+ "card_style" => $out["card_style_${key}"],
+ "card_icon" => $out["card_icon_${key}"] );
+ }
+
+ break;
+
+ case WRENCHBOARD_COUPON_MEMLIST:
+ case WRENCHBOARD_COUPON_PENDLIST:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "coupon_id" => $out["coupon_id_${key}"],
+ "code" => $out["code_${key}"],
+ "amount" => $out["amount_${key}"],
+ "added" => $out["added_${key}"],
+ "status" => $out["status_${key}"]
+ );
+ }
+
+ break;
+
+ case WRENCHBOARD_MOBILE_TASKMESSAGE:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "title" => $out["title_${key}"],
+ "msg" => $out["msg_${key}"],
+ "msg_id" => $out["msg_id_${key}"],
+ "date" => $out["date_${key}"]
+ );
+ }
+
+ break;
+
+ case WRENCHBOARD_START_JOBLIST:
+ case WRENCHBOARD_ACCOUNT_JOBLIST:
+ case WRENCHBOARD_ACCOUNT_PENDJOB:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "title" => $out["title_${key}"],
+ "description" => $out["description_${key}"],
+ "id" => $out["id_${key}"],
+ "job_description" => $out["job_description_${key}"],
+ "price" => $out["price_${key}"],
+ "timeline_days" => $out["timeline_days_${key}"],
+ "expire" => $out["expire_${key}"],
+ "sent" => $out["sent_${key}"]
+ );
+ }
+
+ break;
+ case WRENCHBOARD_MOBILE_ACTIVEJOB:
+ case WRENCHBOARD_MOBILE_OFFERSLIST:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "title" => $out["title_${key}"],
+ "description" => $out["description_${key}"],
+ "id" => $out["id_${key}"],
+ "job_description" => $out["job_description_${key}"],
+ "price" => $out["price_${key}"],
+ "timeline_days" => $out["timeline_days_${key}"],
+
+ "contract_id" => $out["contract_id_${key}"],
+ "job_id" => $out["job_id_${key}"],
+ "contract" => $out["contract_${key}"],
+ "status_description" => $out["status_description_${key}"],
+
+ "delivery_date" => $out["delivery_date_${key}"]
+ );
+ }
+
+ break;
+ case WRENCHBOARD_MOBILE_MESSAGE:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "msg" => $out["msg_${key}"],
+ "msg_id" => $out["msg_id_${key}"],
+ "msg_date" => $out["msg_date_${key}"],
+ "msg_from" => $out["msg_from_${key}"]
+ );
+ }
+ break;
+
+ case WRENCHBOARD_MOBILE_PAYMENTHX:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "fee" => $out["fee_${key}"],
+ "amount" => $out["amount_${key}"],
+ "recipient" => $out["recipient_${key}"],
+ "confirmation" => $out["confirmation_${key}"],
+ "status" => $out["status_${key}"],
+ "trx_date" => $out["trx_date_${key}"],
+ "trx_id" => $out["trx_id_${key}"]
+ );
+ }
+ break;
+
+ case WRENCHBOARD_USER_GETBANKLIST:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "recipient" => $out["recipient_${key}"],
+ "account_no" => $out["account_no_${key}"],
+ "bank_id" => $out["bank_id_${key}"],
+ "added" => $out["added_${key}"]
+ );
+ }
+
+ break;
+
+ case WRENCHBOARD_ACCOUNT_WALLETS:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "currency" => $out["currency_${key}"],
+ "amount" => $out["amount_${key}"],
+ "symbol" => $out["symbol_${key}"],
+ "description" => $out["description_${key}"],
+ "action_type" => $out["action_type_${key}"],
+ "code" => $out["code_${key}"]
+ );
+ }
+ break;
+
+ default:
+ return $out;
+ }
+
+ return $res;
+}
+
+function getBlogData(){
+ return [
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/universitty.jpg",
+ 'post_date' => "2018-06-25T18:54:22.000Z",
+ 'post_date_gmt' => "2018-06-25T18:54:22.000Z",
+ 'post_content' => "Globalization spells danger for the type of jobs that will be available at graduation. The nature of jobs changes so often that it could frustrate for the students. The changes also present new opportunities. Globalization also ensures that job can come anonymously from any part of the world and transaction can be completed privately.\n\nThis is where WrenchBoard comes in, rather than focus on your primary education as your source of income, the new economy will look at your skills as this guide. Your question is to self-examine and attributes values to what you have that others need to make their own or goal complete.\n\nUniversity students can earn extra income along with their regular educational and school work by taking part-time tasks online. To get a project up and running there are a lot of components of service that every business goes through and there are those tasks that students can attend to. Students are in best position to do an initial critique of sites, write articles that bear innocence or interest meddling or test an app for a company in beta phase.\n\nThe online nature of the jobs gives the student the necessary flexibility to operate and added the benefit of interacting with people that don’t think like them, it is an opportunity for the larger world. It is getting very hard to manufacture excuses for not to be involved with one online job or the other when the opportunities and the capabilities collide. A student should be made aware of the fact that life is going to get busier once the excuse of the school is removed.\n\nThere are many jobs students can easily do online\n\n \t- \tOnline marketing - most students have Facebooks and other social environments with tons of friends or connection. Somebody on this planet needs that profile or demography and will be will to pay for it if there is a way to do so
\n \t- \nTeaching - being a student also has the benefit of living in environment where you play with commercial tools, somebody have question about those tools you are playing with that they are willing to pay for - for example, student work with expensive robots in labs and an industrial hand may have questions that you can check out in your experiment environment
\n \t- \nWriting Articles/Blogging -
\n \t- \nSurveys/Research
\n \t- Campaigns
\n
",
+ 'post_title' => "Online Jobs for University Students",
+ ],
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/time_manageent.jpg",
+ 'post_date' => "2017-11-23T14:05:51.000Z",
+ 'post_date_gmt' => "2017-11-23T14:05:51.000Z",
+ 'post_content' => "There are different types of online jobs and some pay more money than others do while some typing jobs may need special equipment, education, or training in order to do them. The advantage of an online job is that you can work at any time of the day around your personal schedule. You can even work in the evening or at night.\n\nYour income from an online job will also depend on the kind of job you do, your experience and your skills.\n\nPrice management\n\nFirstly, you will need to establish the services you will offer your clients and a business essentially succeeds by filling a void or a niche in the market.\n\nEnsure you are familiar with the different online jobs out there as each job category pays differently. The categories of online jobs include Copywriting, SEO copywriting, Content writing, Proofreading, editing, freelance writing, social media marketing and professional blogging. You do not have to work in one field only; you can work in various fields. Research on how much each field pays; this is so you do not sell yourself short and earn less money than you should be earning.\n\nAlways do your best work for every project as the quality of your work will speak for you and you can gauge your prices better while establishing your reputation.\n\nNetworking is also essential both online and in person. You can use social media platforms like LinkedIn to network online. The more you work towards being noticed, the more clients and projects you will get.\n\nTime management \n\nWorking an online business means, you will be working from home in most cases and time management is an essential part of working online. Here are a few tips to help you manage your time better with an online job.\n\n \t- Remove all the extra tabs from your web browser, as they can be reminders of the fact that the internet is a vast wormhole of your attention. Open fewer tabs if you want to have a more productive workday.
\n \t- Remove papers from your desktop as a ton of paperwork on your desktop could discourage you from remaining focused. Ensure you clear your desktop after each workday.
\n \t- Avoid social media interruptions as social media can hinder your productivity if you do not practice mindfulness. You can set up a specific time to socialize before your workday begins or just before retiring after your workday.
\n \t- Block any needless distractions because at times pure silence might be all you need to do to enhance your production. Turn your radio, television, or telephone off. Avoid visiting any social media platforms, ignore email notifications, and even close your browser.
\n \t- Select the best time for you to work; you may find that you are more productive during certain hours of the day. Find out what your optimal time frame is and work during said hours so that you get more work done. Most importantly, ensure you follow your schedule strictly.
\n
\n ",
+ 'post_title' => "Time and price management when working an online job",
+ ],
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/man_reading.jpg",
+ 'post_date' => "2017-11-23T14:04:49.000Z",
+ 'post_date_gmt' => "2017-11-23T14:04:49.000Z",
+ 'post_content' => "Content syndication involves methods of content republication on other websites so you can reach a wider audience. Syndication of your content is a great way to enhance your brand awareness and your reach, direct traffic to your article, and build links. The internet is vast and it is not reasonable to assume that everyone you want to reach will read your content simply because you published it on your own site. Syndicating your content gets it to a different audience who might have never known it was there in the first place. Content syndication is a good and cheap way to further your content. It is a content marketing strategy. There are 4 kinds of content syndication you should know of:\n\n \t- Syndicating content (3rd party) on your website
\n
\nPublishers can ask different websites for permission to display their content on your website or blog. Your site should have roughly 10% syndicated content ideally. Even though it might be unoriginal, it is always good to feature useful content that your readers will find beneficial and worth reading. It is difficult to find great authors committed to writing content for you when you run a website or blog with multiple authors. Ask an influencer on whether you can feature their existing content as a reasonable resolution. Syndicated content diversifies your site content instantly by highlighting something valuable and new to your target audience.\n\n \t- Syndicating your content on other blogs or websites
\n
\nPublishers can syndicate their content to be displayed on another partner website or sites. You can either create content that is not original for your partner who will just be republishing your content. Alternatively, you can agree on a split which both sides find acceptable i.e. you can give them syndicated content for one month and produce original content the next month. If the agreement calls for 1-4 posts monthly, one of them must at least be original.\n\n \t- Publish your content on websites syndicating their content
\n
\nAnother way to syndicate your content is by contributing regularly to websites already syndicating their content. Think of it this way, if you are publishing your content for a specific website on a regular basis and they are content syndicators, their content would also end up on other significant partner websites.\n\n \t- Self-service syndication
\n
\nPublishers are also able to syndicate their own content with Medium as a great place to start with this endeavor. Medium allows you to import your already existing content from the internet edit, format, and publishing it. It allows you to run your own publications using minimal effort. LinkedIn is another platform you can use to republish your own website content so it reaches a bigger audience.\n\nYou have tools available at your disposal that can help you get your content to a wider target audience while enhancing traffic to your website, establishing a stronger following, and developing your reputation.",
+ 'post_title' => "How to use syndication techniques to promote your articles online",
+ ],
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/wrechboard-sample.jpg",
+ 'post_date' => "2017-11-23T14:03:39.000Z",
+ 'post_date_gmt' => "2017-11-23T14:03:39.000Z",
+ 'post_content' => "Paying mind to similarity index and why ignoring it could have serious repercussions \n\nThe similarity index is a term you should be familiar with as an online writer. It is defined as the composite number that is highlighted after matching two texts to determine how similar the content from both pieces is. It is typically displayed as a percentage and the displayed number measures the percentage of your article that the program found the matching text for. This is regardless of proper citation in your work or lack thereof.\n\nIf the similarity index is high this could mean the writer has quoted various other works to a large extent even if it is legitimate.\n\nIt is understandable that you will want to offer quality content for search engines in terms of consideration and indexation and this can lead you to weed your indexable content down. You may also be worried that search engines will not be able to comprehend your content due to existing similar pages because of things like product variations. It will be unwise for you to rush into a decision that could damage your SEO in the process of trying to make search engines happy while destroying your organic visibility in the process.\n\nYou can make use of canonical tags to instruct crawling search engines of the representative alternatives of similar or duplicate content. You just have to place these tags within your source code head section. Canonical tags are very effective in dealing with similar or duplicate content. The easiest way to determine whether you have similar content on your website is to review the site manually while addressing sections of the site appearing to have different URLs but similar content. Take some of the URLs and use tools such as Similar Page Checker or simply review the site for any similar content using Siteliner.\n\nYou may also want to consider consolidating multiple pages into one or expanding certain pages if you have multiple pages that appear to be similar. For example, if you have a site with two distinct pages for different but related topics but the information is the same on both these pages, you may either expand each page further to encompass original content about each topic or merge both pages into one about both topics.\n\nSimilar content can present an issue if not addressed:\n\nYour website will suffer in terms of ranking and you may end up losing traffic. Both losses typically originate from 2 main issues\n\n- Search engines rarely show multiple options of similar content in order to give users an optimum search experience. They will, therefore, be forced to select the best version which will be shown as the best result diluting visibility of websites with similar or duplicate content.\n\n- Equity of links will also be diluted further because other websites will have to choose the best option from the duplicates. As opposed to all the inbound links directing to one content piece, they will link to several pieces distributing the equity of the links among these duplicates. Inbound links are considered a ranking factor so they can affect the search visibility of certain pieces of content.\n\nThe overall result is that the piece of content will not get the search visibility it deserves.\n\n ",
+ 'post_title' => "Paying mind to similarity index",
+ ]
+ ];
+//return $blogData;
+}
+
+function getBlogItem(){
+ return [
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/universitty.jpg",
+ 'post_date' => "2018-06-25T18:54:22.000Z",
+ 'post_date_gmt' => "2018-06-25T18:54:22.000Z",
+ 'post_content' => "Globalization spells danger for the type of jobs that will be available at graduation. The nature of jobs changes so often that it could frustrate for the students. The changes also present new opportunities. Globalization also ensures that job can come anonymously from any part of the world and transaction can be completed privately.\n\nThis is where WrenchBoard comes in, rather than focus on your primary education as your source of income, the new economy will look at your skills as this guide. Your question is to self-examine and attributes values to what you have that others need to make their own or goal complete.\n\nUniversity students can earn extra income along with their regular educational and school work by taking part-time tasks online. To get a project up and running there are a lot of components of service that every business goes through and there are those tasks that students can attend to. Students are in best position to do an initial critique of sites, write articles that bear innocence or interest meddling or test an app for a company in beta phase.\n\nThe online nature of the jobs gives the student the necessary flexibility to operate and added the benefit of interacting with people that don’t think like them, it is an opportunity for the larger world. It is getting very hard to manufacture excuses for not to be involved with one online job or the other when the opportunities and the capabilities collide. A student should be made aware of the fact that life is going to get busier once the excuse of the school is removed.\n\nThere are many jobs students can easily do online\n\n \t- \tOnline marketing - most students have Facebooks and other social environments with tons of friends or connection. Somebody on this planet needs that profile or demography and will be will to pay for it if there is a way to do so
\n \t- \nTeaching - being a student also has the benefit of living in environment where you play with commercial tools, somebody have question about those tools you are playing with that they are willing to pay for - for example, student work with expensive robots in labs and an industrial hand may have questions that you can check out in your experiment environment
\n \t- \nWriting Articles/Blogging -
\n \t- \nSurveys/Research
\n \t- Campaigns
\n
",
+ 'post_title' => "Online Jobs for University Students ITEM",
+ ]
+ ];
+//return $blogData;
+}
\ No newline at end of file
diff --git a/www-api/public/svs/user/.htaccess b/www-api/public/svs/user/.htaccess
new file mode 100644
index 00000000..d92dc5d8
--- /dev/null
+++ b/www-api/public/svs/user/.htaccess
@@ -0,0 +1,22 @@
+
+
+RewriteEngine On
+RewriteBase /svs/user/
+#RewriteBase /
+
+#Checks to
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteRule ^(.*)$ userve.php?endpoint=$1 [L,NC,QSA]
+
+
+
+
+ # If we don't have mod_rewrite installed, all 404's
+ # can be sent to index.php, and everything works as normal.
+ # Submitted by: ElliotHaughin
+
+ErrorDocument 404 /userve.php
+
+
+
diff --git a/www-api/public/svs/user/Dconfig.php b/www-api/public/svs/user/Dconfig.php
new file mode 100644
index 00000000..3a6a15ea
--- /dev/null
+++ b/www-api/public/svs/user/Dconfig.php
@@ -0,0 +1,7 @@
+
diff --git a/www-api/public/svs/user/Dconstants.php b/www-api/public/svs/user/Dconstants.php
new file mode 100644
index 00000000..4cda8cd8
--- /dev/null
+++ b/www-api/public/svs/user/Dconstants.php
@@ -0,0 +1,185 @@
+ $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "title" => $out["title_${key}"],
+ "description" => $out["description_${key}"],
+ "id" => $out["id_${key}"]
+ );
+ }
+
+ break;
+ case MEDTRANS_USER_GET_LANGUAGE:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "language" => $out["language_${key}"],
+ "code" => $out["code_${key}"]
+ );
+ }
+ break;
+
+ case MEDTRANS_TRANSP_LISTLOCATION:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "agent_id" => $out["agent_id_${key}"],
+ "street" => $out["street_${key}"],
+ "city" => $out["city_${key}"],
+ "id" => $out["id_${key}"],
+ "state" => $out["state_${key}"],
+ "zipcode" => $out["zipcode_${key}"],
+ "state" => $out["state_${key}"]
+ );
+ }
+
+ break;
+
+ case MEDTRANS_TRANSP_GETREASON:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "key" => $out["lkey_${key}"],
+ "name" => $out["name_${key}"],
+ "lorder" => $out["lorder_${key}"]
+ );
+ }
+
+
+ break;
+
+ default:
+ return $out;
+ }
+
+ return $res;
+}
diff --git a/www-api/public/svs/user/Duserve.php b/www-api/public/svs/user/Duserve.php
new file mode 100644
index 00000000..bae38a8b
--- /dev/null
+++ b/www-api/public/svs/user/Duserve.php
@@ -0,0 +1,101 @@
+ array('POST'),
+ 'userlogin' => array('POST'),
+ 'startjoblist' => array('POST')
+);
+/*
+header("Access-Control-Allow-Origin: *");
+header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
+header("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
+//header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
+header('Content-type: application/json');
+
+if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
+ die();
+}
+*/
+
+header("Access-Control-Allow-Origin: *");
+header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
+header("Access-Control-Allow-Headers: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
+header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
+header('Content-type: application/json');
+
+if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
+ exit();
+}
+
+$endpoint = strtolower(str_replace('/svs/user/', '', strtok($_SERVER['REQUEST_URI'],'?')));
+
+$id = 0; // update, get & delete actions require ID
+if (substr($endpoint,0,19)=='gettransportrequest'
+ || substr($endpoint,0,13)=='updateprofile') {
+ $endpoint = strtok($endpoint,'/');
+ $id = strtok('/');
+}
+
+if (!isset($endpoints[$endpoint])) {
+ header('HTTP/1.1 400 Bad Request');
+ header('Status: 400 Bad Request');
+ echo "{\"status\":\"Invalid endpoint url\"}";
+ exit();
+}
+
+$methods = $endpoints[$endpoint];
+
+if (array_search($_SERVER['REQUEST_METHOD'], $methods)===false) {
+ header('HTTP/1.1 405 Method Not Allowed');
+ header('Status: 405 Method Not Allowed');
+ echo "{\"status\":\"Invalid request method\"}";
+ exit();
+}
+
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ $in = flatten(json_decode(file_get_contents('php://input'), true));
+}
+if ($_SERVER["REQUEST_METHOD"] == "PUT") {
+ parse_str(file_get_contents('php://input'), $in);
+}
+
+switch ($endpoint) {
+ case 'createuser': $in["action"] = WRENCHBOARD_ACCOUNT_PENDING; $in["street1"] = $in["streetaddress"]; $in["zipcode"] = $in["zip"]; $in["country"] = "US"; $in["loc"] = $_SERVER["REMOTE_ADDR"]; break;
+ case 'userlogin': $in["action"] = WRENCHBOARD_ACCOUNT_LOGIN; break;
+ case 'startjoblist': $in["action"] = WRENCHBOARD_START_JOBLIST; break;
+
+}
+$in["pid"] = 100;
+
+//file_put_contents("in_debug.log", $in); // DEBUG
+
+$out = array();
+$ret = $wrenchboard->wrenchboard_api($in, $out);
+$out['internal_return'] = $ret; // this is reserved array parameter - to be caprured and reoved before you use the out array()
+
+header("HTTP/1.1 200 OK");
+header("Status: 200 OK");
+//$out = array_merge($in, $out); // DEBUG
+echo json_encode(processOutJson($in, $out));
+exit();
+
+function flatten($data, $parentkey="") {
+ $result = array();
+ foreach ($data as $key=>$val) {
+ if (is_array($val)) {
+ $result = array_merge($result, flatten($val, $parentkey.$key."_"));
+ } else {
+ $result[$parentkey.$key] = $val;
+ }
+ }
+ return $result;
+}
+
+
+
+// vi:ts=2
diff --git a/www-api/public/svs/user/config.php b/www-api/public/svs/user/config.php
new file mode 100644
index 00000000..8a6df5f6
--- /dev/null
+++ b/www-api/public/svs/user/config.php
@@ -0,0 +1,4 @@
+
diff --git a/www-api/public/svs/user/constants.php b/www-api/public/svs/user/constants.php
new file mode 100644
index 00000000..19d684b4
--- /dev/null
+++ b/www-api/public/svs/user/constants.php
@@ -0,0 +1,230 @@
+";
+ $text = preg_replace($tags, $replacement, $text);
+ $text = preg_replace("/=\"\"/", "=", $text);
+ $text = str_replace("\\n", "
", $text);
+
+ $text = str_replace('""\"','',$text);
+ $text = str_replace('"\""','',$text);
+ $text = str_replace(' ','',$text);
+
+ $text = str_replace('href=\\"\"http://','',$text);
+ $text = str_replace('href=\\"\"https://','',$text);
+
+ return $text;
+}
+function processOutJson($in, $out) {
+
+
+// id AS coupon_id, ca.code, ca.amount, ca.added::date,ca.status
+ switch ($in["action"]) {
+ case WRENCHBOARD_CARDS_GETCARDLIST:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "assign_id" => $out["assign_id_${key}"],
+ "title" => $out["title_${key}"],
+ "description" => $out["description_${key}"],
+ "card_type" => $out["card_type_${key}"],
+ "card_style" => $out["card_style_${key}"],
+ "card_icon" => $out["card_icon_${key}"] );
+ }
+
+ break;
+
+ case WRENCHBOARD_COUPON_MEMLIST:
+ case WRENCHBOARD_COUPON_PENDLIST:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "coupon_id" => $out["coupon_id_${key}"],
+ "code" => $out["code_${key}"],
+ "amount" => $out["amount_${key}"],
+ "added" => $out["added_${key}"],
+ "status" => $out["status_${key}"]
+ );
+ }
+
+ break;
+
+ case WRENCHBOARD_MOBILE_TASKMESSAGE:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "title" => $out["title_${key}"],
+ "msg" => $out["msg_${key}"],
+ "msg_id" => $out["msg_id_${key}"],
+ "date" => $out["date_${key}"]
+ );
+ }
+
+ break;
+
+ case WRENCHBOARD_START_JOBLIST:
+ case WRENCHBOARD_ACCOUNT_JOBLIST:
+ case WRENCHBOARD_ACCOUNT_PENDJOB:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "title" => $out["title_${key}"],
+ "description" => $out["description_${key}"],
+ "id" => $out["id_${key}"],
+ "job_description" => cleanUpDescription($out["job_description_${key}"]),
+ "price" => $out["price_${key}"],
+ "timeline_days" => $out["timeline_days_${key}"],
+ "expire" => $out["expire_${key}"],
+ "sent" => $out["sent_${key}"],
+ "offer_code" => $out["offer_code_${key}"]
+ );
+ }
+
+ break;
+ case WRENCHBOARD_MOBILE_ACTIVEJOB:
+ case WRENCHBOARD_MOBILE_OFFERSLIST:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "title" => $out["title_${key}"],
+ "description" => $out["description_${key}"],
+ "id" => $out["id_${key}"],
+ "job_description" => $out["job_description_${key}"],
+ "price" => $out["price_${key}"],
+ "timeline_days" => $out["timeline_days_${key}"],
+
+ "contract_id" => $out["contract_id_${key}"],
+ "job_id" => $out["job_id_${key}"],
+ "contract" => $out["contract_${key}"],
+ "status_description" => $out["status_description_${key}"],
+
+ "delivery_date" => $out["delivery_date_${key}"]
+ );
+ }
+
+ break;
+ case WRENCHBOARD_MOBILE_MESSAGE:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "msg" => $out["msg_${key}"],
+ "msg_id" => $out["msg_id_${key}"],
+ "msg_date" => $out["msg_date_${key}"],
+ "msg_from" => $out["msg_from_${key}"],
+ "reply" => $out["reply_${key}"],
+ "message_mode" => $out["message_mode_${key}"],
+ "uid" => $out["uid_${key}"],
+ "memo" => $out["memo_${key}"]
+ );
+ }
+ break;
+
+ case WRENCHBOARD_MOBILE_PAYMENTHX:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "fee" => $out["fee_${key}"],
+ "amount" => $out["amount_${key}"],
+ "recipient" => $out["recipient_${key}"],
+ "confirmation" => $out["confirmation_${key}"],
+ "status" => $out["status_${key}"],
+ "trx_date" => $out["trx_date_${key}"],
+ "trx_id" => $out["trx_id_${key}"]
+ );
+ }
+ break;
+
+ case WRENCHBOARD_USER_GETBANKLIST:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "recipient" => $out["recipient_${key}"],
+ "account_no" => $out["account_no_${key}"],
+ "bank_id" => $out["bank_id_${key}"],
+ "added" => $out["added_${key}"]
+ );
+ }
+
+ break;
+
+ case WRENCHBOARD_ACCOUNT_WALLETS:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "currency" => $out["currency_${key}"],
+ "amount" => $out["amount_${key}"],
+ "symbol" => $out["symbol_${key}"],
+ "description" => $out["description_${key}"],
+ "action_type" => $out["action_type_${key}"],
+ "code" => $out["code_${key}"]
+ );
+ }
+ break;
+
+ default:
+ return $out;
+ }
+
+ return $res;
+}
+
+function getBlogData(){
+ return [
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/universitty.jpg",
+ 'post_date' => "2018-06-25T18:54:22.000Z",
+ 'post_date_gmt' => "2018-06-25T18:54:22.000Z",
+ 'post_content' => "Globalization spells danger for the type of jobs that will be available at graduation. The nature of jobs changes so often that it could frustrate for the students. The changes also present new opportunities. Globalization also ensures that job can come anonymously from any part of the world and transaction can be completed privately.\n\nThis is where WrenchBoard comes in, rather than focus on your primary education as your source of income, the new economy will look at your skills as this guide. Your question is to self-examine and attributes values to what you have that others need to make their own or goal complete.\n\nUniversity students can earn extra income along with their regular educational and school work by taking part-time tasks online. To get a project up and running there are a lot of components of service that every business goes through and there are those tasks that students can attend to. Students are in best position to do an initial critique of sites, write articles that bear innocence or interest meddling or test an app for a company in beta phase.\n\nThe online nature of the jobs gives the student the necessary flexibility to operate and added the benefit of interacting with people that don’t think like them, it is an opportunity for the larger world. It is getting very hard to manufacture excuses for not to be involved with one online job or the other when the opportunities and the capabilities collide. A student should be made aware of the fact that life is going to get busier once the excuse of the school is removed.\n\nThere are many jobs students can easily do online\n\n \t- \tOnline marketing - most students have Facebooks and other social environments with tons of friends or connection. Somebody on this planet needs that profile or demography and will be will to pay for it if there is a way to do so
\n \t- \nTeaching - being a student also has the benefit of living in environment where you play with commercial tools, somebody have question about those tools you are playing with that they are willing to pay for - for example, student work with expensive robots in labs and an industrial hand may have questions that you can check out in your experiment environment
\n \t- \nWriting Articles/Blogging -
\n \t- \nSurveys/Research
\n \t- Campaigns
\n
",
+ 'post_title' => "Online Jobs for University Students",
+ ],
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/time_manageent.jpg",
+ 'post_date' => "2017-11-23T14:05:51.000Z",
+ 'post_date_gmt' => "2017-11-23T14:05:51.000Z",
+ 'post_content' => "There are different types of online jobs and some pay more money than others do while some typing jobs may need special equipment, education, or training in order to do them. The advantage of an online job is that you can work at any time of the day around your personal schedule. You can even work in the evening or at night.\n\nYour income from an online job will also depend on the kind of job you do, your experience and your skills.\n\nPrice management\n\nFirstly, you will need to establish the services you will offer your clients and a business essentially succeeds by filling a void or a niche in the market.\n\nEnsure you are familiar with the different online jobs out there as each job category pays differently. The categories of online jobs include Copywriting, SEO copywriting, Content writing, Proofreading, editing, freelance writing, social media marketing and professional blogging. You do not have to work in one field only; you can work in various fields. Research on how much each field pays; this is so you do not sell yourself short and earn less money than you should be earning.\n\nAlways do your best work for every project as the quality of your work will speak for you and you can gauge your prices better while establishing your reputation.\n\nNetworking is also essential both online and in person. You can use social media platforms like LinkedIn to network online. The more you work towards being noticed, the more clients and projects you will get.\n\nTime management \n\nWorking an online business means, you will be working from home in most cases and time management is an essential part of working online. Here are a few tips to help you manage your time better with an online job.\n\n \t- Remove all the extra tabs from your web browser, as they can be reminders of the fact that the internet is a vast wormhole of your attention. Open fewer tabs if you want to have a more productive workday.
\n \t- Remove papers from your desktop as a ton of paperwork on your desktop could discourage you from remaining focused. Ensure you clear your desktop after each workday.
\n \t- Avoid social media interruptions as social media can hinder your productivity if you do not practice mindfulness. You can set up a specific time to socialize before your workday begins or just before retiring after your workday.
\n \t- Block any needless distractions because at times pure silence might be all you need to do to enhance your production. Turn your radio, television, or telephone off. Avoid visiting any social media platforms, ignore email notifications, and even close your browser.
\n \t- Select the best time for you to work; you may find that you are more productive during certain hours of the day. Find out what your optimal time frame is and work during said hours so that you get more work done. Most importantly, ensure you follow your schedule strictly.
\n
\n ",
+ 'post_title' => "Time and price management when working an online job",
+ ],
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/man_reading.jpg",
+ 'post_date' => "2017-11-23T14:04:49.000Z",
+ 'post_date_gmt' => "2017-11-23T14:04:49.000Z",
+ 'post_content' => "Content syndication involves methods of content republication on other websites so you can reach a wider audience. Syndication of your content is a great way to enhance your brand awareness and your reach, direct traffic to your article, and build links. The internet is vast and it is not reasonable to assume that everyone you want to reach will read your content simply because you published it on your own site. Syndicating your content gets it to a different audience who might have never known it was there in the first place. Content syndication is a good and cheap way to further your content. It is a content marketing strategy. There are 4 kinds of content syndication you should know of:\n\n \t- Syndicating content (3rd party) on your website
\n
\nPublishers can ask different websites for permission to display their content on your website or blog. Your site should have roughly 10% syndicated content ideally. Even though it might be unoriginal, it is always good to feature useful content that your readers will find beneficial and worth reading. It is difficult to find great authors committed to writing content for you when you run a website or blog with multiple authors. Ask an influencer on whether you can feature their existing content as a reasonable resolution. Syndicated content diversifies your site content instantly by highlighting something valuable and new to your target audience.\n\n \t- Syndicating your content on other blogs or websites
\n
\nPublishers can syndicate their content to be displayed on another partner website or sites. You can either create content that is not original for your partner who will just be republishing your content. Alternatively, you can agree on a split which both sides find acceptable i.e. you can give them syndicated content for one month and produce original content the next month. If the agreement calls for 1-4 posts monthly, one of them must at least be original.\n\n \t- Publish your content on websites syndicating their content
\n
\nAnother way to syndicate your content is by contributing regularly to websites already syndicating their content. Think of it this way, if you are publishing your content for a specific website on a regular basis and they are content syndicators, their content would also end up on other significant partner websites.\n\n \t- Self-service syndication
\n
\nPublishers are also able to syndicate their own content with Medium as a great place to start with this endeavor. Medium allows you to import your already existing content from the internet edit, format, and publishing it. It allows you to run your own publications using minimal effort. LinkedIn is another platform you can use to republish your own website content so it reaches a bigger audience.\n\nYou have tools available at your disposal that can help you get your content to a wider target audience while enhancing traffic to your website, establishing a stronger following, and developing your reputation.",
+ 'post_title' => "How to use syndication techniques to promote your articles online",
+ ],
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/wrechboard-sample.jpg",
+ 'post_date' => "2017-11-23T14:03:39.000Z",
+ 'post_date_gmt' => "2017-11-23T14:03:39.000Z",
+ 'post_content' => "Paying mind to similarity index and why ignoring it could have serious repercussions \n\nThe similarity index is a term you should be familiar with as an online writer. It is defined as the composite number that is highlighted after matching two texts to determine how similar the content from both pieces is. It is typically displayed as a percentage and the displayed number measures the percentage of your article that the program found the matching text for. This is regardless of proper citation in your work or lack thereof.\n\nIf the similarity index is high this could mean the writer has quoted various other works to a large extent even if it is legitimate.\n\nIt is understandable that you will want to offer quality content for search engines in terms of consideration and indexation and this can lead you to weed your indexable content down. You may also be worried that search engines will not be able to comprehend your content due to existing similar pages because of things like product variations. It will be unwise for you to rush into a decision that could damage your SEO in the process of trying to make search engines happy while destroying your organic visibility in the process.\n\nYou can make use of canonical tags to instruct crawling search engines of the representative alternatives of similar or duplicate content. You just have to place these tags within your source code head section. Canonical tags are very effective in dealing with similar or duplicate content. The easiest way to determine whether you have similar content on your website is to review the site manually while addressing sections of the site appearing to have different URLs but similar content. Take some of the URLs and use tools such as Similar Page Checker or simply review the site for any similar content using Siteliner.\n\nYou may also want to consider consolidating multiple pages into one or expanding certain pages if you have multiple pages that appear to be similar. For example, if you have a site with two distinct pages for different but related topics but the information is the same on both these pages, you may either expand each page further to encompass original content about each topic or merge both pages into one about both topics.\n\nSimilar content can present an issue if not addressed:\n\nYour website will suffer in terms of ranking and you may end up losing traffic. Both losses typically originate from 2 main issues\n\n- Search engines rarely show multiple options of similar content in order to give users an optimum search experience. They will, therefore, be forced to select the best version which will be shown as the best result diluting visibility of websites with similar or duplicate content.\n\n- Equity of links will also be diluted further because other websites will have to choose the best option from the duplicates. As opposed to all the inbound links directing to one content piece, they will link to several pieces distributing the equity of the links among these duplicates. Inbound links are considered a ranking factor so they can affect the search visibility of certain pieces of content.\n\nThe overall result is that the piece of content will not get the search visibility it deserves.\n\n ",
+ 'post_title' => "Paying mind to similarity index",
+ ]
+ ];
+//return $blogData;
+}
+
+function getBlogItem(){
+ return [
+ [
+ 'meta_value' => "https://blog.wrenchboard.com/wp-content/uploads/2022/01/universitty.jpg",
+ 'post_date' => "2018-06-25T18:54:22.000Z",
+ 'post_date_gmt' => "2018-06-25T18:54:22.000Z",
+ 'post_content' => "Globalization spells danger for the type of jobs that will be available at graduation. The nature of jobs changes so often that it could frustrate for the students. The changes also present new opportunities. Globalization also ensures that job can come anonymously from any part of the world and transaction can be completed privately.\n\nThis is where WrenchBoard comes in, rather than focus on your primary education as your source of income, the new economy will look at your skills as this guide. Your question is to self-examine and attributes values to what you have that others need to make their own or goal complete.\n\nUniversity students can earn extra income along with their regular educational and school work by taking part-time tasks online. To get a project up and running there are a lot of components of service that every business goes through and there are those tasks that students can attend to. Students are in best position to do an initial critique of sites, write articles that bear innocence or interest meddling or test an app for a company in beta phase.\n\nThe online nature of the jobs gives the student the necessary flexibility to operate and added the benefit of interacting with people that don’t think like them, it is an opportunity for the larger world. It is getting very hard to manufacture excuses for not to be involved with one online job or the other when the opportunities and the capabilities collide. A student should be made aware of the fact that life is going to get busier once the excuse of the school is removed.\n\nThere are many jobs students can easily do online\n\n \t- \tOnline marketing - most students have Facebooks and other social environments with tons of friends or connection. Somebody on this planet needs that profile or demography and will be will to pay for it if there is a way to do so
\n \t- \nTeaching - being a student also has the benefit of living in environment where you play with commercial tools, somebody have question about those tools you are playing with that they are willing to pay for - for example, student work with expensive robots in labs and an industrial hand may have questions that you can check out in your experiment environment
\n \t- \nWriting Articles/Blogging -
\n \t- \nSurveys/Research
\n \t- Campaigns
\n
",
+ 'post_title' => "Online Jobs for University Students ITEM",
+ ]
+ ];
+//return $blogData;
+}
\ No newline at end of file
diff --git a/www-api/public/svs/user/formerter.php b/www-api/public/svs/user/formerter.php
new file mode 100644
index 00000000..c135f18e
--- /dev/null
+++ b/www-api/public/svs/user/formerter.php
@@ -0,0 +1,144 @@
+ $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "transport_date" => $out["transport_date_${key}"],
+ "firstname" => $out["firstname_${key}"],
+ "lastname" => $out["lastname_${key}"],
+ "from_phone" => $out["from_phone_${key}"],
+ "from_street" => $out["from_street_${key}"],
+ "to_street" => $out["to_street_${key}"],
+ "from_city" => $out["from_city_${key}"],
+ "to_city" => $out["to_city_${key}"],
+ "from_state" => $out["from_state_${key}"],
+ "to_state" => $out["to_state_${key}"],
+ "from_zipcode" => $out["from_zipcode_${key}"],
+ "to_zipcode" => $out["to_zipcode_${key}"],
+ "flags" => $out["flags_${key}"],
+ "miles" => $out["distance_${key}"],
+ "transport" => $out["transport_${key}"],
+ "translate" => $out["translate_${key}"],
+ "lang_code" => $out["lang_code_${key}"],
+ "language" => $out["language_${key}"]
+ );
+ }
+
+ break;
+ case MEDTRANS_USER_GET_LANGUAGE:
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "language" => $out["language_${key}"],
+ "code" => $out["code_${key}"]
+ );
+ }
+ break;
+
+ case MEDTRANS_TRANSP_LISTLOCATION:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "agent_id" => $out["agent_id_${key}"],
+ "street" => $out["street_${key}"],
+ "city" => $out["city_${key}"],
+ "id" => $out["id_${key}"],
+ "state" => $out["state_${key}"],
+ "zipcode" => $out["zipcode_${key}"],
+ "state" => $out["state_${key}"]
+ );
+ }
+
+ break;
+
+ case MEDTRANS_TRANSP_GETREASON:
+
+ $total = $out["total_record"];
+ $res = array(
+ "status" => $out["status"],
+ "total_record" => ($total - 1),
+ "internal_return" => $out["internal_return"],
+ "result_list" => array(),
+ );
+ for ($i = 0; $i < $total; $i++) {
+ $key = sprintf("%05d", $i);
+ $res["result_list"][] = array(
+ "key" => $out["lkey_${key}"],
+ "name" => $out["name_${key}"],
+ "lorder" => $out["lorder_${key}"]
+ );
+ }
+
+
+ break;
+
+ default:
+ return $out;
+ }
+
+ return $res;
+}
diff --git a/www-api/public/svs/user/index.php b/www-api/public/svs/user/index.php
new file mode 100644
index 00000000..7081ab5c
--- /dev/null
+++ b/www-api/public/svs/user/index.php
@@ -0,0 +1 @@
+ array('POST'),
+ 'generics' => array('POST'),
+ 'createuser' => array('POST'),
+ 'createmobileuser' => array('POST'),
+ 'completemobileuser' => array('POST'),
+ 'startresetpasword' => array('POST'),
+ 'userlogin' => array('POST'),
+ 'startjoblist' => array('POST'),
+ 'dashdata' => array('POST'),
+ 'getjobsdata' => array('POST'),
+ 'offerslist' => array('POST'),
+ 'activejoblist' => array('POST'),
+ 'loadprofile' => array('POST'),
+ 'account' => array('POST'),
+ 'message' => array('POST'),
+ 'pendingjob' => array('POST'),
+ 'paymenthx' => array('POST'),
+ 'getjob' => array('POST'),
+ 'mybanklist' => array('POST'),
+ 'sendmoney' => array('POST'),
+ 'sendinterest' => array('POST'),
+ 'sendmoneyfee' => array('POST'),
+ 'getpendingjobs' => array('POST'),
+ 'taskmessage' => array('POST'),
+ 'sendtaskmessage' => array('POST'),
+ 'getwallets' => array('POST'),
+ 'sitecontact' => array('POST'),
+ 'signupcountry' => array('POST'),
+ 'userscards' => array('POST'),
+ 'blogdata' => array('POST'),
+ 'blogitem' => array('POST'),
+ 'couponhx' => array('POST'),
+ 'couponpending' => array('POST'),
+ 'couponredeem' => array('POST'),
+ 'sendinterestmessage' => array('POST'),
+ 'replyinterestmessage' => array('POST')
+);
+
+$call_backend = true; // sometimes we need to overwite the call to the extenstion API
+$local_out = []; // use local out to send output when the result is not from the extenstion
+$ret = -1;
+
+/*
+ header("Access-Control-Allow-Origin: *");
+ header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
+ header("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
+ //header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
+ header('Content-type: application/json');
+ if ( "OPTIONS" === $_SERVER['REQUEST_METHOD'] ) {
+ die();
+ }
+ */
+
+header("Access-Control-Allow-Origin: *");
+header("Access-Control-Expose-Headers: Access-Control-Allow-Origin");
+header("Access-Control-Allow-Headers: Cache-Control, Pragma, Origin, Authorization, Content-Type, X-Requested-With");
+header("Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS");
+header('Content-type: application/json');
+
+if ("OPTIONS" === $_SERVER['REQUEST_METHOD']) {
+ exit();
+}
+
+$endpoint = strtolower(str_replace('/svs/user/', '', strtok($_SERVER['REQUEST_URI'], '?')));
+
+$id = 0; // update, get & delete actions require ID
+if (substr($endpoint, 0, 19) == 'gettransportrequest' || substr($endpoint, 0, 13) == 'updateprofile') {
+ $endpoint = strtok($endpoint, '/');
+ $id = strtok('/');
+}
+
+if (!isset($endpoints[$endpoint])) {
+ header('HTTP/1.1 400 Bad Request');
+ header('Status: 400 Bad Request');
+ echo "{\"status\":\"Invalid endpoint url WRB\"}";
+ exit();
+}
+
+$methods = $endpoints[$endpoint];
+
+if (array_search($_SERVER['REQUEST_METHOD'], $methods) === false) {
+ header('HTTP/1.1 405 Method Not Allowed');
+ header('Status: 405 Method Not Allowed');
+ echo "{\"status\":\"Invalid request method\"}";
+ exit();
+}
+
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ $in = flatten(json_decode(file_get_contents('php://input'), true));
+}
+if ($_SERVER["REQUEST_METHOD"] == "PUT") {
+ parse_str(file_get_contents('php://input'), $in);
+}
+if ($_SERVER["REQUEST_METHOD"] == "GET") {
+ $in = $_GET;
+}
+$in["loc"] = $_SERVER["REMOTE_ADDR"];
+switch ($endpoint) {
+ case 'replyinterestmessage':
+ $in["action"] = WRENCHBOARD_JOB_REPLY_QUESTION;
+ break;
+ case 'sendinterestmessage':
+ // $in['offer_code'] = $this->input->get('offer_code');
+ $in['yourmessage'] = $in["question"];
+ //$in['member_id'] = $_SESSION['member_id']; // just maing sure
+ $in['msg_type'] = 'JOB';
+ // $in['action'] = WRENCHBOARD_JOB_SEND_QUESTION;
+
+ $in["action"] = WRENCHBOARD_JOB_SEND_QUESTION;
+ break;
+ case 'couponredeem':
+ $in["action"] = WRENCHBOARD_COUPON_REDEEM;
+ break;
+ case 'couponpending':
+ $in["action"] = WRENCHBOARD_COUPON_PENDLIST;
+ break;
+ case 'couponhx':
+ $in["action"] = WRENCHBOARD_COUPON_MEMLIST;
+ break;
+ case 'signupcountry':
+ $local_out = [
+ 'result'=>'100',
+ 'signup_country'=>[
+ ['NG', 'Nigeria'],
+ ['US', 'United States']
+ ]
+ ];
+ $call_backend = false;
+ break;
+ case 'blogitem':
+ $blogData = getBlogItem();
+ $local_out = [
+ 'result'=>'100',
+ 'blog_data'=> $blogData
+ ];
+ $call_backend = false;
+ break;
+ case 'blogdata':
+ $blogData = getBlogData();
+ $local_out = [
+ 'result'=>'100',
+ 'blog_data'=> $blogData
+ ];
+ $call_backend = false;
+ break;
+ case 'userscards':
+ $in["action"] = WRENCHBOARD_CARDS_GETCARDLIST;
+ $local_out = [
+ 'result'=>'100',
+ 'result_list'=>[
+ ['title'=>'This is your coupon',
+ 'description'=>'This is the description of the description',
+ 'card_type'=>'COUPON',
+ 'card_style' =>'card1',
+ 'card_icon' =>'icon1',
+ 'assign_id'=> 0,
+ 'Nigeria'],
+ ['title'=>'A Recommended Story',
+ 'description'=>'This is the description of the description',
+ 'card_type'=>'BLOG',
+ 'card_style' =>'card2',
+ 'card_icon' =>'icon1',
+ 'assign_id'=> 0,
+ 'United States'],
+ ['title'=>'You have a new task sent to you',
+ 'description'=>'This is the description of the description',
+ 'card_type'=>'NEWTASK',
+ 'card_style' =>'card1',
+ 'card_icon' =>'icon1',
+ 'assign_id'=> 0,
+ 'United States'],
+ ['title'=>'You just Earned some token',
+ 'description'=>'This is the description of the description',
+ 'card_type'=>'TOKEN',
+ 'card_style' =>'card2',
+ 'card_icon' =>'icon1',
+ 'assign_id'=> 0,
+ 'United States']
+ ]
+ ];
+ // $call_backend = false;
+
+ break;
+ case 'sitecontact':
+ $local_out = ['result'=>'100','msg'=>'Received'];
+ $call_backend = false;
+ break;
+ case 'generics':
+ case 'apigate':
+ //$in["action"] = WRENCHBOARD_ACCOUNT_LOGIN;
+ break;
+ case 'startjoblist': $in["action"] = WRENCHBOARD_START_JOBLIST;
+ if (!array_key_exists("limit",$in)) $in["limit"] = 10;
+ if (!array_key_exists("page",$in)) $in["page"] = 1;
+ break;
+
+ case 'createmobileuser': $in["action"] = WRENCHBOARD_CREATE_MOBILEUSER;
+ $in["loc"] = $_SERVER["REMOTE_ADDR"];
+ $in["news"] = 0;
+ $in["terms"] = 1;
+ $in["mobile"] = "MOBILE";
+ break;
+ case 'completemobileuser': $in["action"] = WRENCHBOARD_COMPLETE_MOBILEUSER;
+ $in["loc"] = $_SERVER["REMOTE_ADDR"];
+ break;
+
+ case 'startresetpasword':
+ $in["action"] = WRENCHBOARD_RESET_PASSWORD;
+ break;
+ case 'createuser': $in["action"] = WRENCHBOARD_ACCOUNT_PENDING;
+ $in["street1"] = $in["streetaddress"];
+ $in["zipcode"] = $in["zip"];
+ $in["country"] = "US";
+ $in["loc"] = $_SERVER["REMOTE_ADDR"];
+ $in["mobile"] = "MOBILE";
+ break;
+ case 'activejoblist': $in["action"] = WRENCHBOARD_MOBILE_ACTIVEJOB;
+ break;
+ case 'message': $in["action"] = WRENCHBOARD_MOBILE_MESSAGE;
+
+ break;
+ case 'paymenthx': $in["action"] = WRENCHBOARD_MOBILE_PAYMENTHX;
+
+ break;
+ case 'getjobsdata': $in["action"] = WRENCHBOARD_ACCOUNT_JOBLIST;
+ break;
+
+ case 'userlogin': $in["action"] = WRENCHBOARD_ACCOUNT_LOGIN;
+ $in["login_mode"] = MOBILE_LOGIN;
+ break;
+
+ case 'dashdata': $in["action"] = WRENCHBOARD_ACCOUNT_DASHDATA;
+ break;
+ case 'offerslist': $in["action"] = WRENCHBOARD_MOBILE_OFFERSLIST;
+ break;
+
+ case 'loadprofile': $in["action"] = WRENCHBOARD_MOBILE_LOADPROFILE;
+ break;
+ case 'account': $in["action"] = WRENCHBOARD_MOBILE_ACCOUNT;
+ break;
+ case 'getpendingjobs':
+ $in["action"] = WRENCHBOARD_ACCOUNT_PENDJOB;
+ break;
+ case 'pendingjob':
+
+ break;
+ case 'getjob':
+
+ break;
+
+ case 'mybanklist':$in["action"] = WRENCHBOARD_USER_GETBANKLIST;
+ break;
+ case 'sendmoney':$in["action"] = WRENCHBOARD_USER_SENDMONEY;
+ $out["internal_return"] = 0;
+ break;
+ case 'sendinterest':$in["action"] = WRENCHBOARD_USER_SENDJOBINT;
+ $out["internal_return"] = 0;
+ break;
+ case 'sendmoneyfee': $in["action"] = WRENCHBOARD_SMONEY_PROCFEE;
+ break;
+ case 'taskmessage': $in["action"] = WRENCHBOARD_MOBILE_TASKMESSAGE;
+ break;
+ case 'sendtaskmessage': $in["action"] = WRENCHBOARD_MOBILE_SENDTASKMESSAGE;
+ break;
+
+ case 'getwallets': $in["action"] = WRENCHBOARD_ACCOUNT_WALLETS;
+ break;
+}
+
+
+
+$in["pid"] = 100;
+
+//file_put_contents("in_debug.log", $in); // DEBUG
+
+$out = array();
+if ( $call_backend == true){
+ $ret = $wrenchboard->wrenchboard_api($in, $out);
+ $out['internal_return'] = $ret; // this is reserved array parameter - to be captured and received before you use the out array()
+}
+else
+{
+ $out = $local_out;
+}
+
+
+header("HTTP/1.1 200 OK");
+header("Status: 200 OK");
+//$out = array_merge($in, $out); // DEBUG
+echo json_encode(processOutJson($in, $out));
+exit();
+
+function flatten($data, $parentkey = "") {
+ $result = array();
+ foreach ($data as $key => $val) {
+ if (is_array($val)) {
+ $result = array_merge($result, flatten($val, $parentkey . $key . "_"));
+ } else {
+ $result[$parentkey . $key] = $val;
+ }
+ }
+ return $result;
+}
+
+
+// vi:ts=2
diff --git a/www-api/readme.rst b/www-api/readme.rst
new file mode 100644
index 00000000..63a55c3f
--- /dev/null
+++ b/www-api/readme.rst
@@ -0,0 +1,71 @@
+###################
+What is CodeIgniter
+###################
+
+CodeIgniter is an Application Development Framework - a toolkit - for people
+who build web sites using PHP. Its goal is to enable you to develop projects
+much faster than you could if you were writing code from scratch, by providing
+a rich set of libraries for commonly needed tasks, as well as a simple
+interface and logical structure to access these libraries. CodeIgniter lets
+you creatively focus on your project by minimizing the amount of code needed
+for a given task.
+
+*******************
+Release Information
+*******************
+
+This repo contains in-development code for future releases. To download the
+latest stable release please visit the `CodeIgniter Downloads
+`_ page.
+
+**************************
+Changelog and New Features
+**************************
+
+You can find a list of all changes for each release in the `user
+guide change log `_.
+
+*******************
+Server Requirements
+*******************
+
+PHP version 5.6 or newer is recommended.
+
+It should work on 5.3.7 as well, but we strongly advise you NOT to run
+such old versions of PHP, because of potential security and performance
+issues, as well as missing features.
+
+************
+Installation
+************
+
+Please see the `installation section `_
+of the CodeIgniter User Guide.
+
+*******
+License
+*******
+
+Please see the `license
+agreement `_.
+
+*********
+Resources
+*********
+
+- `User Guide `_
+- `Contributing Guide `_
+- `Language File Translations `_
+- `Community Forums `_
+- `Community Wiki `_
+- `Community Slack Channel `_
+
+Report security issues to our `Security Panel `_
+or via our `page on HackerOne `_, thank you.
+
+***************
+Acknowledgement
+***************
+
+The CodeIgniter team would like to thank EllisLab, all the
+contributors to the CodeIgniter project and you, the CodeIgniter user.
diff --git a/www-api/system/.htaccess b/www-api/system/.htaccess
new file mode 100644
index 00000000..97c65d2d
--- /dev/null
+++ b/www-api/system/.htaccess
@@ -0,0 +1,6 @@
+
+ Require all denied
+
+
+ Deny from all
+
\ No newline at end of file
diff --git a/www-api/system/core/Benchmark.php b/www-api/system/core/Benchmark.php
new file mode 100644
index 00000000..20ac2f55
--- /dev/null
+++ b/www-api/system/core/Benchmark.php
@@ -0,0 +1,134 @@
+marker[$name] = microtime(TRUE);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Elapsed time
+ *
+ * Calculates the time difference between two marked points.
+ *
+ * If the first parameter is empty this function instead returns the
+ * {elapsed_time} pseudo-variable. This permits the full system
+ * execution time to be shown in a template. The output class will
+ * swap the real value for this variable.
+ *
+ * @param string $point1 A particular marked point
+ * @param string $point2 A particular marked point
+ * @param int $decimals Number of decimal places
+ *
+ * @return string Calculated elapsed time on success,
+ * an '{elapsed_string}' if $point1 is empty
+ * or an empty string if $point1 is not found.
+ */
+ public function elapsed_time($point1 = '', $point2 = '', $decimals = 4)
+ {
+ if ($point1 === '')
+ {
+ return '{elapsed_time}';
+ }
+
+ if ( ! isset($this->marker[$point1]))
+ {
+ return '';
+ }
+
+ if ( ! isset($this->marker[$point2]))
+ {
+ $this->marker[$point2] = microtime(TRUE);
+ }
+
+ return number_format($this->marker[$point2] - $this->marker[$point1], $decimals);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Memory Usage
+ *
+ * Simply returns the {memory_usage} marker.
+ *
+ * This permits it to be put it anywhere in a template
+ * without the memory being calculated until the end.
+ * The output class will swap the real value for this variable.
+ *
+ * @return string '{memory_usage}'
+ */
+ public function memory_usage()
+ {
+ return '{memory_usage}';
+ }
+
+}
diff --git a/www-api/system/core/CodeIgniter.php b/www-api/system/core/CodeIgniter.php
new file mode 100644
index 00000000..56826dcc
--- /dev/null
+++ b/www-api/system/core/CodeIgniter.php
@@ -0,0 +1,560 @@
+ '_ENV', 'G' => '_GET', 'P' => '_POST', 'C' => '_COOKIE', 'S' => '_SERVER') as $key => $superglobal)
+ {
+ if (strpos($_registered, $key) === FALSE)
+ {
+ continue;
+ }
+
+ foreach (array_keys($$superglobal) as $var)
+ {
+ if (isset($GLOBALS[$var]) && ! in_array($var, $_protected, TRUE))
+ {
+ $GLOBALS[$var] = NULL;
+ }
+ }
+ }
+ }
+}
+
+
+/*
+ * ------------------------------------------------------
+ * Define a custom error handler so we can log PHP errors
+ * ------------------------------------------------------
+ */
+ set_error_handler('_error_handler');
+ set_exception_handler('_exception_handler');
+ register_shutdown_function('_shutdown_handler');
+
+/*
+ * ------------------------------------------------------
+ * Set the subclass_prefix
+ * ------------------------------------------------------
+ *
+ * Normally the "subclass_prefix" is set in the config file.
+ * The subclass prefix allows CI to know if a core class is
+ * being extended via a library in the local application
+ * "libraries" folder. Since CI allows config items to be
+ * overridden via data set in the main index.php file,
+ * before proceeding we need to know if a subclass_prefix
+ * override exists. If so, we will set this value now,
+ * before any classes are loaded
+ * Note: Since the config file data is cached it doesn't
+ * hurt to load it here.
+ */
+ if ( ! empty($assign_to_config['subclass_prefix']))
+ {
+ get_config(array('subclass_prefix' => $assign_to_config['subclass_prefix']));
+ }
+
+/*
+ * ------------------------------------------------------
+ * Should we use a Composer autoloader?
+ * ------------------------------------------------------
+ */
+ if ($composer_autoload = config_item('composer_autoload'))
+ {
+ if ($composer_autoload === TRUE)
+ {
+ file_exists(APPPATH.'vendor/autoload.php')
+ ? require_once(APPPATH.'vendor/autoload.php')
+ : log_message('error', '$config[\'composer_autoload\'] is set to TRUE but '.APPPATH.'vendor/autoload.php was not found.');
+ }
+ elseif (file_exists($composer_autoload))
+ {
+ require_once($composer_autoload);
+ }
+ else
+ {
+ log_message('error', 'Could not find the specified $config[\'composer_autoload\'] path: '.$composer_autoload);
+ }
+ }
+
+/*
+ * ------------------------------------------------------
+ * 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
+ * ------------------------------------------------------
+ *
+ * Note: It is important that Config is loaded first as
+ * most other classes depend on it either directly or by
+ * depending on another class that uses it.
+ *
+ */
+ $CFG =& load_class('Config', 'core');
+
+ // Do we have any manually set config items in the index.php file?
+ if (isset($assign_to_config) && is_array($assign_to_config))
+ {
+ foreach ($assign_to_config as $key => $value)
+ {
+ $CFG->set_item($key, $value);
+ }
+ }
+
+/*
+ * ------------------------------------------------------
+ * Important charset-related stuff
+ * ------------------------------------------------------
+ *
+ * Configure mbstring and/or iconv if they are enabled
+ * and set MB_ENABLED and ICONV_ENABLED constants, so
+ * that we don't repeatedly do extension_loaded() or
+ * function_exists() calls.
+ *
+ * Note: UTF-8 class depends on this. It used to be done
+ * in it's constructor, but it's _not_ class-specific.
+ *
+ */
+ $charset = strtoupper(config_item('charset'));
+ ini_set('default_charset', $charset);
+
+ if (extension_loaded('mbstring'))
+ {
+ define('MB_ENABLED', TRUE);
+ // mbstring.internal_encoding is deprecated starting with PHP 5.6
+ // and it's usage triggers E_DEPRECATED messages.
+ @ini_set('mbstring.internal_encoding', $charset);
+ // This is required for mb_convert_encoding() to strip invalid characters.
+ // That's utilized by CI_Utf8, but it's also done for consistency with iconv.
+ mb_substitute_character('none');
+ }
+ else
+ {
+ define('MB_ENABLED', FALSE);
+ }
+
+ // There's an ICONV_IMPL constant, but the PHP manual says that using
+ // iconv's predefined constants is "strongly discouraged".
+ if (extension_loaded('iconv'))
+ {
+ define('ICONV_ENABLED', TRUE);
+ // iconv.internal_encoding is deprecated starting with PHP 5.6
+ // and it's usage triggers E_DEPRECATED messages.
+ @ini_set('iconv.internal_encoding', $charset);
+ }
+ else
+ {
+ define('ICONV_ENABLED', FALSE);
+ }
+
+ if (is_php('5.6'))
+ {
+ ini_set('php.internal_encoding', $charset);
+ }
+
+/*
+ * ------------------------------------------------------
+ * Load compatibility features
+ * ------------------------------------------------------
+ */
+
+ require_once(BASEPATH.'core/compat/mbstring.php');
+ require_once(BASEPATH.'core/compat/hash.php');
+ require_once(BASEPATH.'core/compat/password.php');
+ require_once(BASEPATH.'core/compat/standard.php');
+
+/*
+ * ------------------------------------------------------
+ * Instantiate the UTF-8 class
+ * ------------------------------------------------------
+ */
+ $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', isset($routing) ? $routing : NULL);
+
+/*
+ * ------------------------------------------------------
+ * 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 && $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_once BASEPATH.'core/Controller.php';
+
+ /**
+ * Reference to the CI_Controller method.
+ *
+ * Returns current CI instance object
+ *
+ * @return CI_Controller
+ */
+ function &get_instance()
+ {
+ return CI_Controller::get_instance();
+ }
+
+ if (file_exists(APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php'))
+ {
+ require_once APPPATH.'core/'.$CFG->config['subclass_prefix'].'Controller.php';
+ }
+
+ // Set a mark point for benchmarking
+ $BM->mark('loading_time:_base_classes_end');
+
+/*
+ * ------------------------------------------------------
+ * Sanity checks
+ * ------------------------------------------------------
+ *
+ * The Router class has already validated the request,
+ * leaving us with 3 options here:
+ *
+ * 1) an empty class name, if we reached the default
+ * controller, but it didn't exist;
+ * 2) a query string which doesn't go through a
+ * file_exists() check
+ * 3) a regular request for a non-existing page
+ *
+ * We handle all of these as a 404 error.
+ *
+ * Furthermore, none of the methods in the app controller
+ * or the loader class can be called via the URI, nor can
+ * controller methods that begin with an underscore.
+ */
+
+ $e404 = FALSE;
+ $class = ucfirst($RTR->class);
+ $method = $RTR->method;
+
+ if (empty($class) OR ! file_exists(APPPATH.'controllers/'.$RTR->directory.$class.'.php'))
+ {
+ $e404 = TRUE;
+ }
+ else
+ {
+ require_once(APPPATH.'controllers/'.$RTR->directory.$class.'.php');
+
+ if ( ! class_exists($class, FALSE) OR $method[0] === '_' OR method_exists('CI_Controller', $method))
+ {
+ $e404 = TRUE;
+ }
+ elseif (method_exists($class, '_remap'))
+ {
+ $params = array($method, array_slice($URI->rsegments, 2));
+ $method = '_remap';
+ }
+ elseif ( ! method_exists($class, $method))
+ {
+ $e404 = TRUE;
+ }
+ /**
+ * DO NOT CHANGE THIS, NOTHING ELSE WORKS!
+ *
+ * - method_exists() returns true for non-public methods, which passes the previous elseif
+ * - is_callable() returns false for PHP 4-style constructors, even if there's a __construct()
+ * - method_exists($class, '__construct') won't work because CI_Controller::__construct() is inherited
+ * - People will only complain if this doesn't work, even though it is documented that it shouldn't.
+ *
+ * ReflectionMethod::isConstructor() is the ONLY reliable check,
+ * knowing which method will be executed as a constructor.
+ */
+ else
+ {
+ $reflection = new ReflectionMethod($class, $method);
+ if ( ! $reflection->isPublic() OR $reflection->isConstructor())
+ {
+ $e404 = TRUE;
+ }
+ }
+ }
+
+ if ($e404)
+ {
+ if ( ! empty($RTR->routes['404_override']))
+ {
+ if (sscanf($RTR->routes['404_override'], '%[^/]/%s', $error_class, $error_method) !== 2)
+ {
+ $error_method = 'index';
+ }
+
+ $error_class = ucfirst($error_class);
+
+ if ( ! class_exists($error_class, FALSE))
+ {
+ if (file_exists(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php'))
+ {
+ require_once(APPPATH.'controllers/'.$RTR->directory.$error_class.'.php');
+ $e404 = ! class_exists($error_class, FALSE);
+ }
+ // Were we in a directory? If so, check for a global override
+ elseif ( ! empty($RTR->directory) && file_exists(APPPATH.'controllers/'.$error_class.'.php'))
+ {
+ require_once(APPPATH.'controllers/'.$error_class.'.php');
+ if (($e404 = ! class_exists($error_class, FALSE)) === FALSE)
+ {
+ $RTR->directory = '';
+ }
+ }
+ }
+ else
+ {
+ $e404 = FALSE;
+ }
+ }
+
+ // Did we reset the $e404 flag? If so, set the rsegments, starting from index 1
+ if ( ! $e404)
+ {
+ $class = $error_class;
+ $method = $error_method;
+
+ $URI->rsegments = array(
+ 1 => $class,
+ 2 => $method
+ );
+ }
+ else
+ {
+ show_404($RTR->directory.$class.'/'.$method);
+ }
+ }
+
+ if ($method !== '_remap')
+ {
+ $params = array_slice($URI->rsegments, 2);
+ }
+
+/*
+ * ------------------------------------------------------
+ * 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
+ * ------------------------------------------------------
+ */
+ call_user_func_array(array(&$CI, $method), $params);
+
+ // 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');
diff --git a/www-api/system/core/Common.php b/www-api/system/core/Common.php
new file mode 100644
index 00000000..a56cb146
--- /dev/null
+++ b/www-api/system/core/Common.php
@@ -0,0 +1,849 @@
+=');
+ }
+
+ return $_is_php[$version];
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('is_really_writable'))
+{
+ /**
+ * 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.
+ *
+ * @link https://bugs.php.net/bug.php?id=54709
+ * @param string
+ * @return bool
+ */
+ function is_really_writable($file)
+ {
+ // If we're on a Unix server with safe_mode off we call is_writable
+ if (DIRECTORY_SEPARATOR === '/' && (is_php('5.4') OR ! ini_get('safe_mode')))
+ {
+ 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());
+ if (($fp = @fopen($file, 'ab')) === FALSE)
+ {
+ return FALSE;
+ }
+
+ fclose($fp);
+ @chmod($file, 0777);
+ @unlink($file);
+ return TRUE;
+ }
+ elseif ( ! is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE)
+ {
+ return FALSE;
+ }
+
+ fclose($fp);
+ return TRUE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('load_class'))
+{
+ /**
+ * 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.
+ *
+ * @param string the class name being requested
+ * @param string the directory where the class should be found
+ * @param mixed an optional argument to pass to the class constructor
+ * @return object
+ */
+ function &load_class($class, $directory = 'libraries', $param = NULL)
+ {
+ 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 = 'CI_'.$class;
+
+ if (class_exists($name, FALSE) === FALSE)
+ {
+ require_once($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) === FALSE)
+ {
+ require_once(APPPATH.$directory.'/'.$name.'.php');
+ }
+ }
+
+ // Did we find the class?
+ if ($name === FALSE)
+ {
+ // Note: We use exit() rather than show_error() in order to avoid a
+ // self-referencing loop with the Exceptions class
+ set_status_header(503);
+ echo 'Unable to locate the specified class: '.$class.'.php';
+ exit(5); // EXIT_UNK_CLASS
+ }
+
+ // Keep track of what we just loaded
+ is_loaded($class);
+
+ $_classes[$class] = isset($param)
+ ? new $name($param)
+ : new $name();
+ return $_classes[$class];
+ }
+}
+
+// --------------------------------------------------------------------
+
+if ( ! function_exists('is_loaded'))
+{
+ /**
+ * Keeps track of which libraries have been loaded. This function is
+ * called by the load_class() function above
+ *
+ * @param string
+ * @return array
+ */
+ function &is_loaded($class = '')
+ {
+ static $_is_loaded = array();
+
+ if ($class !== '')
+ {
+ $_is_loaded[strtolower($class)] = $class;
+ }
+
+ return $_is_loaded;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('get_config'))
+{
+ /**
+ * Loads the main config.php file
+ *
+ * This function lets us grab the config file even if the Config class
+ * hasn't been instantiated yet
+ *
+ * @param array
+ * @return array
+ */
+ function &get_config(Array $replace = array())
+ {
+ static $config;
+
+ if (empty($config))
+ {
+ $file_path = APPPATH.'config/config.php';
+ $found = FALSE;
+ if (file_exists($file_path))
+ {
+ $found = TRUE;
+ require($file_path);
+ }
+
+ // Is the config file in the environment folder?
+ if (file_exists($file_path = APPPATH.'config/'.ENVIRONMENT.'/config.php'))
+ {
+ require($file_path);
+ }
+ elseif ( ! $found)
+ {
+ set_status_header(503);
+ echo 'The configuration file does not exist.';
+ exit(3); // EXIT_CONFIG
+ }
+
+ // Does the $config array exist in the file?
+ if ( ! isset($config) OR ! is_array($config))
+ {
+ set_status_header(503);
+ echo 'Your config file does not appear to be formatted correctly.';
+ exit(3); // EXIT_CONFIG
+ }
+ }
+
+ // Are any values being dynamically added or replaced?
+ foreach ($replace as $key => $val)
+ {
+ $config[$key] = $val;
+ }
+
+ return $config;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('config_item'))
+{
+ /**
+ * Returns the specified config item
+ *
+ * @param string
+ * @return mixed
+ */
+ function config_item($item)
+ {
+ static $_config;
+
+ if (empty($_config))
+ {
+ // references cannot be directly assigned to static variables, so we use an array
+ $_config[0] =& get_config();
+ }
+
+ return isset($_config[0][$item]) ? $_config[0][$item] : NULL;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('get_mimes'))
+{
+ /**
+ * Returns the MIME types array from config/mimes.php
+ *
+ * @return array
+ */
+ function &get_mimes()
+ {
+ static $_mimes;
+
+ if (empty($_mimes))
+ {
+ $_mimes = file_exists(APPPATH.'config/mimes.php')
+ ? include(APPPATH.'config/mimes.php')
+ : array();
+
+ if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
+ {
+ $_mimes = array_merge($_mimes, include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'));
+ }
+ }
+
+ return $_mimes;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('is_https'))
+{
+ /**
+ * Is HTTPS?
+ *
+ * Determines if the application is accessed via an encrypted
+ * (HTTPS) connection.
+ *
+ * @return bool
+ */
+ function is_https()
+ {
+ if ( ! empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off')
+ {
+ return TRUE;
+ }
+ elseif (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) === 'https')
+ {
+ return TRUE;
+ }
+ elseif ( ! empty($_SERVER['HTTP_FRONT_END_HTTPS']) && strtolower($_SERVER['HTTP_FRONT_END_HTTPS']) !== 'off')
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('is_cli'))
+{
+
+ /**
+ * Is CLI?
+ *
+ * Test to see if a request was made from the command line.
+ *
+ * @return bool
+ */
+ function is_cli()
+ {
+ return (PHP_SAPI === 'cli' OR defined('STDIN'));
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('show_error'))
+{
+ /**
+ * Error Handler
+ *
+ * This function lets us invoke the exception class and
+ * display errors using the standard error template located
+ * in application/views/errors/error_general.php
+ * This function will send the error page directly to the
+ * browser and exit.
+ *
+ * @param string
+ * @param int
+ * @param string
+ * @return void
+ */
+ function show_error($message, $status_code = 500, $heading = 'An Error Was Encountered')
+ {
+ $status_code = abs($status_code);
+ if ($status_code < 100)
+ {
+ $exit_status = $status_code + 9; // 9 is EXIT__AUTO_MIN
+ $status_code = 500;
+ }
+ else
+ {
+ $exit_status = 1; // EXIT_ERROR
+ }
+
+ $_error =& load_class('Exceptions', 'core');
+ echo $_error->show_error($heading, $message, 'error_general', $status_code);
+ exit($exit_status);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('show_404'))
+{
+ /**
+ * 404 Page Handler
+ *
+ * This function is similar to the show_error() function above
+ * However, instead of the standard error template it displays
+ * 404 errors.
+ *
+ * @param string
+ * @param bool
+ * @return void
+ */
+ function show_404($page = '', $log_error = TRUE)
+ {
+ $_error =& load_class('Exceptions', 'core');
+ $_error->show_404($page, $log_error);
+ exit(4); // EXIT_UNKNOWN_FILE
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('log_message'))
+{
+ /**
+ * Error Logging Interface
+ *
+ * We use this as a simple mechanism to access the logging
+ * class and send messages to be logged.
+ *
+ * @param string the error level: 'error', 'debug' or 'info'
+ * @param string the error message
+ * @return void
+ */
+ function log_message($level, $message)
+ {
+ static $_log;
+
+ if ($_log === NULL)
+ {
+ // references cannot be directly assigned to static variables, so we use an array
+ $_log[0] =& load_class('Log', 'core');
+ }
+
+ $_log[0]->write_log($level, $message);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('set_status_header'))
+{
+ /**
+ * Set HTTP Status Header
+ *
+ * @param int the status code
+ * @param string
+ * @return void
+ */
+ function set_status_header($code = 200, $text = '')
+ {
+ if (is_cli())
+ {
+ return;
+ }
+
+ if (empty($code) OR ! is_numeric($code))
+ {
+ show_error('Status codes must be numeric', 500);
+ }
+
+ if (empty($text))
+ {
+ is_int($code) OR $code = (int) $code;
+ $stati = array(
+ 100 => 'Continue',
+ 101 => 'Switching Protocols',
+
+ 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',
+ 303 => 'See Other',
+ 304 => 'Not Modified',
+ 305 => 'Use Proxy',
+ 307 => 'Temporary Redirect',
+
+ 400 => 'Bad Request',
+ 401 => 'Unauthorized',
+ 402 => 'Payment Required',
+ 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',
+ 422 => 'Unprocessable Entity',
+ 426 => 'Upgrade Required',
+ 428 => 'Precondition Required',
+ 429 => 'Too Many Requests',
+ 431 => 'Request Header Fields Too Large',
+
+ 500 => 'Internal Server Error',
+ 501 => 'Not Implemented',
+ 502 => 'Bad Gateway',
+ 503 => 'Service Unavailable',
+ 504 => 'Gateway Timeout',
+ 505 => 'HTTP Version Not Supported',
+ 511 => 'Network Authentication Required',
+ );
+
+ if (isset($stati[$code]))
+ {
+ $text = $stati[$code];
+ }
+ else
+ {
+ show_error('No status text available. Please check your status code number or supply your own message text.', 500);
+ }
+ }
+
+ if (strpos(PHP_SAPI, 'cgi') === 0)
+ {
+ header('Status: '.$code.' '.$text, TRUE);
+ return;
+ }
+
+ $server_protocol = (isset($_SERVER['SERVER_PROTOCOL']) && in_array($_SERVER['SERVER_PROTOCOL'], array('HTTP/1.0', 'HTTP/1.1', 'HTTP/2', 'HTTP/2.0'), TRUE))
+ ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
+ header($server_protocol.' '.$code.' '.$text, TRUE, $code);
+ }
+}
+
+// --------------------------------------------------------------------
+
+if ( ! function_exists('_error_handler'))
+{
+ /**
+ * Error Handler
+ *
+ * This is the custom error handler that is declared at the (relative)
+ * 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.
+ *
+ * @param int $severity
+ * @param string $message
+ * @param string $filepath
+ * @param int $line
+ * @return void
+ */
+ function _error_handler($severity, $message, $filepath, $line)
+ {
+ $is_error = (((E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR | E_USER_ERROR) & $severity) === $severity);
+
+ // When an error occurred, set the status header to '500 Internal Server Error'
+ // to indicate to the client something went wrong.
+ // This can't be done within the $_error->show_php_error method because
+ // it is only called when the display_errors flag is set (which isn't usually
+ // the case in a production environment) or when errors are ignored because
+ // they are above the error_reporting threshold.
+ if ($is_error)
+ {
+ set_status_header(500);
+ }
+
+ // Should we ignore 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)
+ {
+ return;
+ }
+
+ $_error =& load_class('Exceptions', 'core');
+ $_error->log_exception($severity, $message, $filepath, $line);
+
+ // Should we display the error?
+ if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors')))
+ {
+ $_error->show_php_error($severity, $message, $filepath, $line);
+ }
+
+ // If the error is fatal, the execution of the script should be stopped because
+ // errors can't be recovered from. Halting the script conforms with PHP's
+ // default error handling. See http://www.php.net/manual/en/errorfunc.constants.php
+ if ($is_error)
+ {
+ exit(1); // EXIT_ERROR
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('_exception_handler'))
+{
+ /**
+ * Exception Handler
+ *
+ * Sends uncaught exceptions to the logger and displays them
+ * only if display_errors is On so that they don't show up in
+ * production environments.
+ *
+ * @param Exception $exception
+ * @return void
+ */
+ function _exception_handler($exception)
+ {
+ $_error =& load_class('Exceptions', 'core');
+ $_error->log_exception('error', 'Exception: '.$exception->getMessage(), $exception->getFile(), $exception->getLine());
+
+ is_cli() OR set_status_header(500);
+ // Should we display the error?
+ if (str_ireplace(array('off', 'none', 'no', 'false', 'null'), '', ini_get('display_errors')))
+ {
+ $_error->show_exception($exception);
+ }
+
+ exit(1); // EXIT_ERROR
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('_shutdown_handler'))
+{
+ /**
+ * Shutdown Handler
+ *
+ * This is the shutdown handler that is declared at the top
+ * of CodeIgniter.php. The main reason we use this is to simulate
+ * a complete custom exception handler.
+ *
+ * E_STRICT is purposively neglected because such events may have
+ * been caught. Duplication or none? None is preferred for now.
+ *
+ * @link http://insomanic.me.uk/post/229851073/php-trick-catching-fatal-errors-e-error-with-a
+ * @return void
+ */
+ function _shutdown_handler()
+ {
+ $last_error = error_get_last();
+ if (isset($last_error) &&
+ ($last_error['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_CORE_WARNING | E_COMPILE_ERROR | E_COMPILE_WARNING)))
+ {
+ _error_handler($last_error['type'], $last_error['message'], $last_error['file'], $last_error['line']);
+ }
+ }
+}
+
+// --------------------------------------------------------------------
+
+if ( ! function_exists('remove_invisible_characters'))
+{
+ /**
+ * Remove Invisible Characters
+ *
+ * This prevents sandwiching null characters
+ * between ascii characters, like Java\0script.
+ *
+ * @param string
+ * @param bool
+ * @return string
+ */
+ 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]/i'; // url encoded 00-08, 11, 12, 14, 15
+ $non_displayables[] = '/%1[0-9a-f]/i'; // url encoded 16-31
+ $non_displayables[] = '/%7f/i'; // url encoded 127
+ }
+
+ $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;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('html_escape'))
+{
+ /**
+ * Returns HTML escaped variable.
+ *
+ * @param mixed $var The input string or array of strings to be escaped.
+ * @param bool $double_encode $double_encode set to FALSE prevents escaping twice.
+ * @return mixed The escaped string or array of strings as a result.
+ */
+ function html_escape($var, $double_encode = TRUE)
+ {
+ if (empty($var))
+ {
+ return $var;
+ }
+
+ if (is_array($var))
+ {
+ foreach (array_keys($var) as $key)
+ {
+ $var[$key] = html_escape($var[$key], $double_encode);
+ }
+
+ return $var;
+ }
+
+ return htmlspecialchars($var, ENT_QUOTES, config_item('charset'), $double_encode);
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('_stringify_attributes'))
+{
+ /**
+ * Stringify attributes for use in HTML tags.
+ *
+ * Helper function used to convert a string, array, or object
+ * of attributes to a string.
+ *
+ * @param mixed string, array, object
+ * @param bool
+ * @return string
+ */
+ function _stringify_attributes($attributes, $js = FALSE)
+ {
+ if (empty($attributes))
+ {
+ return NULL;
+ }
+
+ if (is_string($attributes))
+ {
+ return ' '.$attributes;
+ }
+
+ $attributes = (array) $attributes;
+
+ $atts = '';
+ foreach ($attributes as $key => $val)
+ {
+ $atts .= ($js) ? $key.'='.$val.',' : ' '.$key.'="'.$val.'"';
+ }
+
+ return rtrim($atts, ',');
+ }
+}
+
+// ------------------------------------------------------------------------
+
+if ( ! function_exists('function_usable'))
+{
+ /**
+ * Function usable
+ *
+ * Executes a function_exists() check, and if the Suhosin PHP
+ * extension is loaded - checks whether the function that is
+ * checked might be disabled in there as well.
+ *
+ * This is useful as function_exists() will return FALSE for
+ * functions disabled via the *disable_functions* php.ini
+ * setting, but not for *suhosin.executor.func.blacklist* and
+ * *suhosin.executor.disable_eval*. These settings will just
+ * terminate script execution if a disabled function is executed.
+ *
+ * The above described behavior turned out to be a bug in Suhosin,
+ * but even though a fix was committed for 0.9.34 on 2012-02-12,
+ * that version is yet to be released. This function will therefore
+ * be just temporary, but would probably be kept for a few years.
+ *
+ * @link http://www.hardened-php.net/suhosin/
+ * @param string $function_name Function to check for
+ * @return bool TRUE if the function exists and is safe to call,
+ * FALSE otherwise.
+ */
+ function function_usable($function_name)
+ {
+ static $_suhosin_func_blacklist;
+
+ if (function_exists($function_name))
+ {
+ if ( ! isset($_suhosin_func_blacklist))
+ {
+ $_suhosin_func_blacklist = extension_loaded('suhosin')
+ ? explode(',', trim(ini_get('suhosin.executor.func.blacklist')))
+ : array();
+ }
+
+ return ! in_array($function_name, $_suhosin_func_blacklist, TRUE);
+ }
+
+ return FALSE;
+ }
+}
diff --git a/www-api/system/core/Config.php b/www-api/system/core/Config.php
new file mode 100644
index 00000000..2454a9d7
--- /dev/null
+++ b/www-api/system/core/Config.php
@@ -0,0 +1,380 @@
+config =& get_config();
+
+ // Set the base_url automatically if none was provided
+ if (empty($this->config['base_url']))
+ {
+ if (isset($_SERVER['SERVER_ADDR']))
+ {
+ if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE)
+ {
+ $server_addr = '['.$_SERVER['SERVER_ADDR'].']';
+ }
+ else
+ {
+ $server_addr = $_SERVER['SERVER_ADDR'];
+ }
+
+ $base_url = (is_https() ? 'https' : 'http').'://'.$server_addr
+ .substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME'])));
+ }
+ else
+ {
+ $base_url = 'http://localhost/';
+ }
+
+ $this->set_item('base_url', $base_url);
+ }
+
+ log_message('info', 'Config Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Load Config File
+ *
+ * @param string $file Configuration file name
+ * @param bool $use_sections Whether configuration values should be loaded into their own section
+ * @param bool $fail_gracefully Whether to just return FALSE or display an error message
+ * @return bool TRUE if the file was loaded correctly or FALSE on failure
+ */
+ public function load($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
+ {
+ $file = ($file === '') ? 'config' : str_replace('.php', '', $file);
+ $loaded = FALSE;
+
+ foreach ($this->_config_paths as $path)
+ {
+ foreach (array($file, ENVIRONMENT.DIRECTORY_SEPARATOR.$file) as $location)
+ {
+ $file_path = $path.'config/'.$location.'.php';
+ if (in_array($file_path, $this->is_loaded, TRUE))
+ {
+ return TRUE;
+ }
+
+ if ( ! file_exists($file_path))
+ {
+ 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)
+ {
+ $this->config[$file] = isset($this->config[$file])
+ ? array_merge($this->config[$file], $config)
+ : $config;
+ }
+ else
+ {
+ $this->config = array_merge($this->config, $config);
+ }
+
+ $this->is_loaded[] = $file_path;
+ $config = NULL;
+ $loaded = TRUE;
+ log_message('debug', 'Config file loaded: '.$file_path);
+ }
+ }
+
+ if ($loaded === TRUE)
+ {
+ return TRUE;
+ }
+ elseif ($fail_gracefully === TRUE)
+ {
+ return FALSE;
+ }
+
+ show_error('The configuration file '.$file.'.php does not exist.');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch a config file item
+ *
+ * @param string $item Config item name
+ * @param string $index Index name
+ * @return string|null The configuration item or NULL if the item doesn't exist
+ */
+ public function item($item, $index = '')
+ {
+ if ($index == '')
+ {
+ return isset($this->config[$item]) ? $this->config[$item] : NULL;
+ }
+
+ return isset($this->config[$index], $this->config[$index][$item]) ? $this->config[$index][$item] : NULL;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch a config file item with slash appended (if not empty)
+ *
+ * @param string $item Config item name
+ * @return string|null The configuration item or NULL if the item doesn't exist
+ */
+ public function slash_item($item)
+ {
+ if ( ! isset($this->config[$item]))
+ {
+ return NULL;
+ }
+ elseif (trim($this->config[$item]) === '')
+ {
+ return '';
+ }
+
+ return rtrim($this->config[$item], '/').'/';
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Site URL
+ *
+ * Returns base_url . index_page [. uri_string]
+ *
+ * @uses CI_Config::_uri_string()
+ *
+ * @param string|string[] $uri URI string or an array of segments
+ * @param string $protocol
+ * @return string
+ */
+ public function site_url($uri = '', $protocol = NULL)
+ {
+ $base_url = $this->slash_item('base_url');
+
+ if (isset($protocol))
+ {
+ // For protocol-relative links
+ if ($protocol === '')
+ {
+ $base_url = substr($base_url, strpos($base_url, '//'));
+ }
+ else
+ {
+ $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ }
+ }
+
+ if (empty($uri))
+ {
+ return $base_url.$this->item('index_page');
+ }
+
+ $uri = $this->_uri_string($uri);
+
+ if ($this->item('enable_query_strings') === FALSE)
+ {
+ $suffix = isset($this->config['url_suffix']) ? $this->config['url_suffix'] : '';
+
+ if ($suffix !== '')
+ {
+ if (($offset = strpos($uri, '?')) !== FALSE)
+ {
+ $uri = substr($uri, 0, $offset).$suffix.substr($uri, $offset);
+ }
+ else
+ {
+ $uri .= $suffix;
+ }
+ }
+
+ return $base_url.$this->slash_item('index_page').$uri;
+ }
+ elseif (strpos($uri, '?') === FALSE)
+ {
+ $uri = '?'.$uri;
+ }
+
+ return $base_url.$this->item('index_page').$uri;
+ }
+
+ // -------------------------------------------------------------
+
+ /**
+ * Base URL
+ *
+ * Returns base_url [. uri_string]
+ *
+ * @uses CI_Config::_uri_string()
+ *
+ * @param string|string[] $uri URI string or an array of segments
+ * @param string $protocol
+ * @return string
+ */
+ public function base_url($uri = '', $protocol = NULL)
+ {
+ $base_url = $this->slash_item('base_url');
+
+ if (isset($protocol))
+ {
+ // For protocol-relative links
+ if ($protocol === '')
+ {
+ $base_url = substr($base_url, strpos($base_url, '//'));
+ }
+ else
+ {
+ $base_url = $protocol.substr($base_url, strpos($base_url, '://'));
+ }
+ }
+
+ return $base_url.$this->_uri_string($uri);
+ }
+
+ // -------------------------------------------------------------
+
+ /**
+ * Build URI string
+ *
+ * @used-by CI_Config::site_url()
+ * @used-by CI_Config::base_url()
+ *
+ * @param string|string[] $uri URI string or an array of segments
+ * @return string
+ */
+ protected function _uri_string($uri)
+ {
+ if ($this->item('enable_query_strings') === FALSE)
+ {
+ is_array($uri) && $uri = implode('/', $uri);
+ return ltrim($uri, '/');
+ }
+ elseif (is_array($uri))
+ {
+ return http_build_query($uri);
+ }
+
+ return $uri;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * System URL
+ *
+ * @deprecated 3.0.0 Encourages insecure practices
+ * @return string
+ */
+ public function system_url()
+ {
+ $x = explode('/', preg_replace('|/*(.+?)/*$|', '\\1', BASEPATH));
+ return $this->slash_item('base_url').end($x).'/';
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set a config file item
+ *
+ * @param string $item Config item key
+ * @param string $value Config item value
+ * @return void
+ */
+ public function set_item($item, $value)
+ {
+ $this->config[$item] = $value;
+ }
+
+}
diff --git a/www-api/system/core/Controller.php b/www-api/system/core/Controller.php
new file mode 100644
index 00000000..aeccd60e
--- /dev/null
+++ b/www-api/system/core/Controller.php
@@ -0,0 +1,104 @@
+ $class)
+ {
+ $this->$var =& load_class($class);
+ }
+
+ $this->load =& load_class('Loader', 'core');
+ $this->load->initialize();
+ log_message('info', 'Controller Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get the CI singleton
+ *
+ * @static
+ * @return object
+ */
+ public static function &get_instance()
+ {
+ return self::$instance;
+ }
+
+}
diff --git a/www-api/system/core/Exceptions.php b/www-api/system/core/Exceptions.php
new file mode 100644
index 00000000..b1bc2dec
--- /dev/null
+++ b/www-api/system/core/Exceptions.php
@@ -0,0 +1,275 @@
+ 'Error',
+ E_WARNING => 'Warning',
+ E_PARSE => 'Parsing Error',
+ E_NOTICE => 'Notice',
+ E_CORE_ERROR => 'Core Error',
+ E_CORE_WARNING => 'Core Warning',
+ E_COMPILE_ERROR => 'Compile Error',
+ E_COMPILE_WARNING => 'Compile Warning',
+ E_USER_ERROR => 'User Error',
+ E_USER_WARNING => 'User Warning',
+ E_USER_NOTICE => 'User Notice',
+ E_STRICT => 'Runtime Notice'
+ );
+
+ /**
+ * Class constructor
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ $this->ob_level = ob_get_level();
+ // Note: Do not log messages from this constructor.
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Exception Logger
+ *
+ * Logs PHP generated error messages
+ *
+ * @param int $severity Log level
+ * @param string $message Error message
+ * @param string $filepath File path
+ * @param int $line Line number
+ * @return void
+ */
+ public function log_exception($severity, $message, $filepath, $line)
+ {
+ $severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
+ log_message('error', 'Severity: '.$severity.' --> '.$message.' '.$filepath.' '.$line);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * 404 Error Handler
+ *
+ * @uses CI_Exceptions::show_error()
+ *
+ * @param string $page Page URI
+ * @param bool $log_error Whether to log the error
+ * @return void
+ */
+ public function show_404($page = '', $log_error = TRUE)
+ {
+ if (is_cli())
+ {
+ $heading = 'Not Found';
+ $message = 'The controller/method pair you requested was not found.';
+ }
+ else
+ {
+ $heading = '404 Page Not Found';
+ $message = 'The page you requested was not found.';
+ }
+
+ // By default we log this, but allow a dev to skip it
+ if ($log_error)
+ {
+ log_message('error', $heading.': '.$page);
+ }
+
+ echo $this->show_error($heading, $message, 'error_404', 404);
+ exit(4); // EXIT_UNKNOWN_FILE
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * General Error Page
+ *
+ * Takes an error message as input (either as a string or an array)
+ * and displays it using the specified template.
+ *
+ * @param string $heading Page heading
+ * @param string|string[] $message Error message
+ * @param string $template Template name
+ * @param int $status_code (default: 500)
+ *
+ * @return string Error page output
+ */
+ public function show_error($heading, $message, $template = 'error_general', $status_code = 500)
+ {
+ $templates_path = config_item('error_views_path');
+ if (empty($templates_path))
+ {
+ $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ }
+
+ if (is_cli())
+ {
+ $message = "\t".(is_array($message) ? implode("\n\t", $message) : $message);
+ $template = 'cli'.DIRECTORY_SEPARATOR.$template;
+ }
+ else
+ {
+ set_status_header($status_code);
+ $message = ''.(is_array($message) ? implode('
', $message) : $message).'
';
+ $template = 'html'.DIRECTORY_SEPARATOR.$template;
+ }
+
+ if (ob_get_level() > $this->ob_level + 1)
+ {
+ ob_end_flush();
+ }
+ ob_start();
+ include($templates_path.$template.'.php');
+ $buffer = ob_get_contents();
+ ob_end_clean();
+ return $buffer;
+ }
+
+ // --------------------------------------------------------------------
+
+ public function show_exception($exception)
+ {
+ $templates_path = config_item('error_views_path');
+ if (empty($templates_path))
+ {
+ $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ }
+
+ $message = $exception->getMessage();
+ if (empty($message))
+ {
+ $message = '(null)';
+ }
+
+ if (is_cli())
+ {
+ $templates_path .= 'cli'.DIRECTORY_SEPARATOR;
+ }
+ else
+ {
+ $templates_path .= 'html'.DIRECTORY_SEPARATOR;
+ }
+
+ if (ob_get_level() > $this->ob_level + 1)
+ {
+ ob_end_flush();
+ }
+
+ ob_start();
+ include($templates_path.'error_exception.php');
+ $buffer = ob_get_contents();
+ ob_end_clean();
+ echo $buffer;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Native PHP error handler
+ *
+ * @param int $severity Error level
+ * @param string $message Error message
+ * @param string $filepath File path
+ * @param int $line Line number
+ * @return void
+ */
+ public function show_php_error($severity, $message, $filepath, $line)
+ {
+ $templates_path = config_item('error_views_path');
+ if (empty($templates_path))
+ {
+ $templates_path = VIEWPATH.'errors'.DIRECTORY_SEPARATOR;
+ }
+
+ $severity = isset($this->levels[$severity]) ? $this->levels[$severity] : $severity;
+
+ // For safety reasons we don't show the full file path in non-CLI requests
+ if ( ! is_cli())
+ {
+ $filepath = str_replace('\\', '/', $filepath);
+ if (FALSE !== strpos($filepath, '/'))
+ {
+ $x = explode('/', $filepath);
+ $filepath = $x[count($x)-2].'/'.end($x);
+ }
+
+ $template = 'html'.DIRECTORY_SEPARATOR.'error_php';
+ }
+ else
+ {
+ $template = 'cli'.DIRECTORY_SEPARATOR.'error_php';
+ }
+
+ if (ob_get_level() > $this->ob_level + 1)
+ {
+ ob_end_flush();
+ }
+ ob_start();
+ include($templates_path.$template.'.php');
+ $buffer = ob_get_contents();
+ ob_end_clean();
+ echo $buffer;
+ }
+
+}
diff --git a/www-api/system/core/Hooks.php b/www-api/system/core/Hooks.php
new file mode 100644
index 00000000..2246bbcb
--- /dev/null
+++ b/www-api/system/core/Hooks.php
@@ -0,0 +1,267 @@
+item('enable_hooks') === FALSE)
+ {
+ return;
+ }
+
+ // Grab the "hooks" definition file.
+ if (file_exists(APPPATH.'config/hooks.php'))
+ {
+ include(APPPATH.'config/hooks.php');
+ }
+
+ if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/hooks.php'))
+ {
+ include(APPPATH.'config/'.ENVIRONMENT.'/hooks.php');
+ }
+
+ // If there are no hooks, we're done.
+ if ( ! isset($hook) OR ! is_array($hook))
+ {
+ return;
+ }
+
+ $this->hooks =& $hook;
+ $this->enabled = TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Call Hook
+ *
+ * Calls a particular hook. Called by CodeIgniter.php.
+ *
+ * @uses CI_Hooks::_run_hook()
+ *
+ * @param string $which Hook name
+ * @return bool TRUE on success or FALSE on failure
+ */
+ public function call_hook($which = '')
+ {
+ if ( ! $this->enabled OR ! isset($this->hooks[$which]))
+ {
+ return FALSE;
+ }
+
+ if (is_array($this->hooks[$which]) && ! isset($this->hooks[$which]['function']))
+ {
+ foreach ($this->hooks[$which] as $val)
+ {
+ $this->_run_hook($val);
+ }
+ }
+ else
+ {
+ $this->_run_hook($this->hooks[$which]);
+ }
+
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Run Hook
+ *
+ * Runs a particular hook
+ *
+ * @param array $data Hook details
+ * @return bool TRUE on success or FALSE on failure
+ */
+ protected function _run_hook($data)
+ {
+ // Closures/lambda functions and array($object, 'method') callables
+ if (is_callable($data))
+ {
+ is_array($data)
+ ? $data[0]->{$data[1]}()
+ : $data();
+
+ return TRUE;
+ }
+ elseif ( ! is_array($data))
+ {
+ return FALSE;
+ }
+
+ // -----------------------------------
+ // Safety - Prevents run-away loops
+ // -----------------------------------
+
+ // If the script being called happens to have the same
+ // hook call within it a loop can happen
+ if ($this->_in_progress === TRUE)
+ {
+ return;
+ }
+
+ // -----------------------------------
+ // Set file path
+ // -----------------------------------
+
+ if ( ! isset($data['filepath'], $data['filename']))
+ {
+ return FALSE;
+ }
+
+ $filepath = APPPATH.$data['filepath'].'/'.$data['filename'];
+
+ if ( ! file_exists($filepath))
+ {
+ return FALSE;
+ }
+
+ // Determine and class and/or function names
+ $class = empty($data['class']) ? FALSE : $data['class'];
+ $function = empty($data['function']) ? FALSE : $data['function'];
+ $params = isset($data['params']) ? $data['params'] : '';
+
+ if (empty($function))
+ {
+ return FALSE;
+ }
+
+ // Set the _in_progress flag
+ $this->_in_progress = TRUE;
+
+ // Call the requested class and/or function
+ if ($class !== FALSE)
+ {
+ // The object is stored?
+ if (isset($this->_objects[$class]))
+ {
+ if (method_exists($this->_objects[$class], $function))
+ {
+ $this->_objects[$class]->$function($params);
+ }
+ else
+ {
+ return $this->_in_progress = FALSE;
+ }
+ }
+ else
+ {
+ class_exists($class, FALSE) OR require_once($filepath);
+
+ if ( ! class_exists($class, FALSE) OR ! method_exists($class, $function))
+ {
+ return $this->_in_progress = FALSE;
+ }
+
+ // Store the object and execute the method
+ $this->_objects[$class] = new $class();
+ $this->_objects[$class]->$function($params);
+ }
+ }
+ else
+ {
+ function_exists($function) OR require_once($filepath);
+
+ if ( ! function_exists($function))
+ {
+ return $this->_in_progress = FALSE;
+ }
+
+ $function($params);
+ }
+
+ $this->_in_progress = FALSE;
+ return TRUE;
+ }
+
+}
diff --git a/www-api/system/core/Input.php b/www-api/system/core/Input.php
new file mode 100644
index 00000000..eba5f67f
--- /dev/null
+++ b/www-api/system/core/Input.php
@@ -0,0 +1,937 @@
+_allow_get_array = (config_item('allow_get_array') !== FALSE);
+ $this->_enable_xss = (config_item('global_xss_filtering') === TRUE);
+ $this->_enable_csrf = (config_item('csrf_protection') === TRUE);
+ $this->_standardize_newlines = (bool) config_item('standardize_newlines');
+
+ $this->security =& load_class('Security', 'core');
+
+ // Do we need the UTF-8 class?
+ if (UTF8_ENABLED === TRUE)
+ {
+ $this->uni =& load_class('Utf8', 'core');
+ }
+
+ // Sanitize global arrays
+ $this->_sanitize_globals();
+
+ // CSRF Protection check
+ if ($this->_enable_csrf === TRUE && ! is_cli())
+ {
+ $this->security->csrf_verify();
+ }
+
+ log_message('info', 'Input Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch from array
+ *
+ * Internal method used to retrieve values from global arrays.
+ *
+ * @param array &$array $_GET, $_POST, $_COOKIE, $_SERVER, etc.
+ * @param mixed $index Index for item to be fetched from $array
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ protected function _fetch_from_array(&$array, $index = NULL, $xss_clean = NULL)
+ {
+ is_bool($xss_clean) OR $xss_clean = $this->_enable_xss;
+
+ // If $index is NULL, it means that the whole $array is requested
+ isset($index) OR $index = array_keys($array);
+
+ // allow fetching multiple keys at once
+ if (is_array($index))
+ {
+ $output = array();
+ foreach ($index as $key)
+ {
+ $output[$key] = $this->_fetch_from_array($array, $key, $xss_clean);
+ }
+
+ return $output;
+ }
+
+ if (isset($array[$index]))
+ {
+ $value = $array[$index];
+ }
+ elseif (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $index, $matches)) > 1) // Does the index contain array notation
+ {
+ $value = $array;
+ for ($i = 0; $i < $count; $i++)
+ {
+ $key = trim($matches[0][$i], '[]');
+ if ($key === '') // Empty notation will return the value as array
+ {
+ break;
+ }
+
+ if (isset($value[$key]))
+ {
+ $value = $value[$key];
+ }
+ else
+ {
+ return NULL;
+ }
+ }
+ }
+ else
+ {
+ return NULL;
+ }
+
+ return ($xss_clean === TRUE)
+ ? $this->security->xss_clean($value)
+ : $value;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the GET array
+ *
+ * @param mixed $index Index for item to be fetched from $_GET
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function get($index = NULL, $xss_clean = NULL)
+ {
+ return $this->_fetch_from_array($_GET, $index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the POST array
+ *
+ * @param mixed $index Index for item to be fetched from $_POST
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function post($index = NULL, $xss_clean = NULL)
+ {
+ return $this->_fetch_from_array($_POST, $index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from POST data with fallback to GET
+ *
+ * @param string $index Index for item to be fetched from $_POST or $_GET
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function post_get($index, $xss_clean = NULL)
+ {
+ return isset($_POST[$index])
+ ? $this->post($index, $xss_clean)
+ : $this->get($index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from GET data with fallback to POST
+ *
+ * @param string $index Index for item to be fetched from $_GET or $_POST
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function get_post($index, $xss_clean = NULL)
+ {
+ return isset($_GET[$index])
+ ? $this->get($index, $xss_clean)
+ : $this->post($index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the COOKIE array
+ *
+ * @param mixed $index Index for item to be fetched from $_COOKIE
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function cookie($index = NULL, $xss_clean = NULL)
+ {
+ return $this->_fetch_from_array($_COOKIE, $index, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the SERVER array
+ *
+ * @param mixed $index Index for item to be fetched from $_SERVER
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function server($index, $xss_clean = NULL)
+ {
+ return $this->_fetch_from_array($_SERVER, $index, $xss_clean);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Fetch an item from the php://input stream
+ *
+ * Useful when you need to access PUT, DELETE or PATCH request data.
+ *
+ * @param string $index Index for item to be fetched
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return mixed
+ */
+ public function input_stream($index = NULL, $xss_clean = NULL)
+ {
+ // Prior to PHP 5.6, the input stream can only be read once,
+ // so we'll need to check if we have already done that first.
+ if ( ! is_array($this->_input_stream))
+ {
+ // $this->raw_input_stream will trigger __get().
+ parse_str($this->raw_input_stream, $this->_input_stream);
+ is_array($this->_input_stream) OR $this->_input_stream = array();
+ }
+
+ return $this->_fetch_from_array($this->_input_stream, $index, $xss_clean);
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Set cookie
+ *
+ * Accepts an arbitrary number of parameters (up to 7) or an associative
+ * array in the first parameter containing all the values.
+ *
+ * @param string|mixed[] $name Cookie name or an array containing parameters
+ * @param string $value Cookie value
+ * @param int $expire Cookie expiration time in seconds
+ * @param string $domain Cookie domain (e.g.: '.yourdomain.com')
+ * @param string $path Cookie path (default: '/')
+ * @param string $prefix Cookie name prefix
+ * @param bool $secure Whether to only transfer cookies via SSL
+ * @param bool $httponly Whether to only makes the cookie accessible via HTTP (no javascript)
+ * @param string $samesite SameSite attribute
+ * @return void
+ */
+ public function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/', $prefix = '', $secure = NULL, $httponly = NULL, $samesite = NULL)
+ {
+ 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', 'httponly', 'name', 'samesite') as $item)
+ {
+ if (isset($name[$item]))
+ {
+ $$item = $name[$item];
+ }
+ }
+ }
+
+ if ($prefix === '' && config_item('cookie_prefix') !== '')
+ {
+ $prefix = config_item('cookie_prefix');
+ }
+
+ if ($domain == '' && config_item('cookie_domain') != '')
+ {
+ $domain = config_item('cookie_domain');
+ }
+
+ if ($path === '/' && config_item('cookie_path') !== '/')
+ {
+ $path = config_item('cookie_path');
+ }
+
+ $secure = ($secure === NULL && config_item('cookie_secure') !== NULL)
+ ? (bool) config_item('cookie_secure')
+ : (bool) $secure;
+
+ $httponly = ($httponly === NULL && config_item('cookie_httponly') !== NULL)
+ ? (bool) config_item('cookie_httponly')
+ : (bool) $httponly;
+
+ if ( ! is_numeric($expire))
+ {
+ $expire = time() - 86500;
+ }
+ else
+ {
+ $expire = ($expire > 0) ? time() + $expire : 0;
+ }
+
+ isset($samesite) OR $samesite = config_item('cookie_samesite');
+ if (isset($samesite))
+ {
+ $samesite = ucfirst(strtolower($samesite));
+ in_array($samesite, array('Lax', 'Strict', 'None'), TRUE) OR $samesite = 'Lax';
+ }
+ else
+ {
+ $samesite = 'Lax';
+ }
+
+ if ($samesite === 'None' && ! $secure)
+ {
+ log_message('error', $name.' cookie sent with SameSite=None, but without Secure attribute.');
+ }
+
+ if ( ! is_php('7.3'))
+ {
+ $maxage = $expire - time();
+ if ($maxage < 1)
+ {
+ $maxage = 0;
+ }
+
+ $cookie_header = 'Set-Cookie: '.$prefix.$name.'='.rawurlencode($value);
+ $cookie_header .= ($expire === 0 ? '' : '; Expires='.gmdate('D, d-M-Y H:i:s T', $expire)).'; Max-Age='.$maxage;
+ $cookie_header .= '; Path='.$path.($domain !== '' ? '; Domain='.$domain : '');
+ $cookie_header .= ($secure ? '; Secure' : '').($httponly ? '; HttpOnly' : '').'; SameSite='.$samesite;
+ header($cookie_header);
+ return;
+ }
+
+ $setcookie_options = array(
+ 'expires' => $expire,
+ 'path' => $path,
+ 'domain' => $domain,
+ 'secure' => $secure,
+ 'httponly' => $httponly,
+ 'samesite' => $samesite,
+ );
+ setcookie($prefix.$name, $value, $setcookie_options);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch the IP Address
+ *
+ * Determines and validates the visitor's IP address.
+ *
+ * @return string IP address
+ */
+ public function ip_address()
+ {
+ if ($this->ip_address !== FALSE)
+ {
+ return $this->ip_address;
+ }
+
+ $proxy_ips = config_item('proxy_ips');
+ if ( ! empty($proxy_ips) && ! is_array($proxy_ips))
+ {
+ $proxy_ips = explode(',', str_replace(' ', '', $proxy_ips));
+ }
+
+ $this->ip_address = $this->server('REMOTE_ADDR');
+
+ if ($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)) !== NULL)
+ {
+ // 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.
+ sscanf($spoof, '%[^,]', $spoof);
+
+ if ( ! $this->valid_ip($spoof))
+ {
+ $spoof = NULL;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ if ($spoof)
+ {
+ for ($i = 0, $c = count($proxy_ips); $i < $c; $i++)
+ {
+ // Check if we have an IP address or a subnet
+ if (strpos($proxy_ips[$i], '/') === FALSE)
+ {
+ // An IP address (and not a subnet) is specified.
+ // We can compare right away.
+ if ($proxy_ips[$i] === $this->ip_address)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+
+ continue;
+ }
+
+ // We have a subnet ... now the heavy lifting begins
+ isset($separator) OR $separator = $this->valid_ip($this->ip_address, 'ipv6') ? ':' : '.';
+
+ // If the proxy entry doesn't match the IP protocol - skip it
+ if (strpos($proxy_ips[$i], $separator) === FALSE)
+ {
+ continue;
+ }
+
+ // Convert the REMOTE_ADDR IP address to binary, if needed
+ if ( ! isset($ip, $sprintf))
+ {
+ if ($separator === ':')
+ {
+ // Make sure we're have the "full" IPv6 format
+ $ip = explode(':',
+ str_replace('::',
+ str_repeat(':', 9 - substr_count($this->ip_address, ':')),
+ $this->ip_address
+ )
+ );
+
+ for ($j = 0; $j < 8; $j++)
+ {
+ $ip[$j] = intval($ip[$j], 16);
+ }
+
+ $sprintf = '%016b%016b%016b%016b%016b%016b%016b%016b';
+ }
+ else
+ {
+ $ip = explode('.', $this->ip_address);
+ $sprintf = '%08b%08b%08b%08b';
+ }
+
+ $ip = vsprintf($sprintf, $ip);
+ }
+
+ // Split the netmask length off the network address
+ sscanf($proxy_ips[$i], '%[^/]/%d', $netaddr, $masklen);
+
+ // Again, an IPv6 address is most likely in a compressed form
+ if ($separator === ':')
+ {
+ $netaddr = explode(':', str_replace('::', str_repeat(':', 9 - substr_count($netaddr, ':')), $netaddr));
+ for ($j = 0; $j < 8; $j++)
+ {
+ $netaddr[$j] = intval($netaddr[$j], 16);
+ }
+ }
+ else
+ {
+ $netaddr = explode('.', $netaddr);
+ }
+
+ // Convert to binary and finally compare
+ if (strncmp($ip, vsprintf($sprintf, $netaddr), $masklen) === 0)
+ {
+ $this->ip_address = $spoof;
+ break;
+ }
+ }
+ }
+ }
+
+ if ( ! $this->valid_ip($this->ip_address))
+ {
+ return $this->ip_address = '0.0.0.0';
+ }
+
+ return $this->ip_address;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Validate IP Address
+ *
+ * @param string $ip IP address
+ * @param string $which IP protocol: 'ipv4' or 'ipv6'
+ * @return bool
+ */
+ public function valid_ip($ip, $which = '')
+ {
+ switch (strtolower($which))
+ {
+ case 'ipv4':
+ $which = FILTER_FLAG_IPV4;
+ break;
+ case 'ipv6':
+ $which = FILTER_FLAG_IPV6;
+ break;
+ default:
+ $which = 0;
+ break;
+ }
+
+ return (bool) filter_var($ip, FILTER_VALIDATE_IP, $which);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Fetch User Agent string
+ *
+ * @return string|null User Agent string or NULL if it doesn't exist
+ */
+ public function user_agent($xss_clean = NULL)
+ {
+ return $this->_fetch_from_array($_SERVER, 'HTTP_USER_AGENT', $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Sanitize Globals
+ *
+ * Internal method serving for the following purposes:
+ *
+ * - Unsets $_GET data, if query strings are not enabled
+ * - Cleans POST, COOKIE and SERVER data
+ * - Standardizes newline characters to PHP_EOL
+ *
+ * @return void
+ */
+ protected function _sanitize_globals()
+ {
+ // Is $_GET data allowed? If not we'll set the $_GET to an empty array
+ if ($this->_allow_get_array === FALSE)
+ {
+ $_GET = array();
+ }
+ elseif (is_array($_GET))
+ {
+ foreach ($_GET as $key => $val)
+ {
+ $_GET[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ }
+ }
+
+ // Clean $_POST Data
+ if (is_array($_POST))
+ {
+ foreach ($_POST as $key => $val)
+ {
+ $_POST[$this->_clean_input_keys($key)] = $this->_clean_input_data($val);
+ }
+ }
+
+ // Clean $_COOKIE Data
+ if (is_array($_COOKIE))
+ {
+ // 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'],
+ $_COOKIE['$Path'],
+ $_COOKIE['$Domain']
+ );
+
+ foreach ($_COOKIE as $key => $val)
+ {
+ if (($cookie_key = $this->_clean_input_keys($key)) !== FALSE)
+ {
+ $_COOKIE[$cookie_key] = $this->_clean_input_data($val);
+ }
+ else
+ {
+ unset($_COOKIE[$key]);
+ }
+ }
+ }
+
+ // Sanitize PHP_SELF
+ $_SERVER['PHP_SELF'] = strip_tags($_SERVER['PHP_SELF']);
+
+ log_message('debug', 'Global POST, GET and COOKIE data sanitized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Clean Input Data
+ *
+ * Internal method that aids in escaping data and
+ * standardizing newline characters to PHP_EOL.
+ *
+ * @param string|string[] $str Input string(s)
+ * @return string
+ */
+ protected function _clean_input_data($str)
+ {
+ if (is_array($str))
+ {
+ $new_array = array();
+ foreach (array_keys($str) as $key)
+ {
+ $new_array[$this->_clean_input_keys($key)] = $this->_clean_input_data($str[$key]);
+ }
+ 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, FALSE);
+
+ // Standardize newlines if needed
+ if ($this->_standardize_newlines === TRUE)
+ {
+ return preg_replace('/(?:\r\n|[\r\n])/', PHP_EOL, $str);
+ }
+
+ return $str;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Clean Keys
+ *
+ * Internal method that helps 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.
+ *
+ * @param string $str Input string
+ * @param bool $fatal Whether to terminate script exection
+ * or to return FALSE if an invalid
+ * key is encountered
+ * @return string|bool
+ */
+ protected function _clean_input_keys($str, $fatal = TRUE)
+ {
+ if ( ! preg_match('/^[a-z0-9:_\/|-]+$/i', $str))
+ {
+ if ($fatal === TRUE)
+ {
+ return FALSE;
+ }
+ else
+ {
+ set_status_header(503);
+ echo 'Disallowed Key Characters.';
+ exit(7); // EXIT_USER_INPUT
+ }
+ }
+
+ // Clean UTF-8 if supported
+ if (UTF8_ENABLED === TRUE)
+ {
+ return $this->uni->clean_string($str);
+ }
+
+ return $str;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Request Headers
+ *
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return array
+ */
+ public function request_headers($xss_clean = FALSE)
+ {
+ // If header is already defined, return it immediately
+ if ( ! empty($this->headers))
+ {
+ return $this->_fetch_from_array($this->headers, NULL, $xss_clean);
+ }
+
+ // In Apache, you can simply call apache_request_headers()
+ if (function_exists('apache_request_headers'))
+ {
+ $this->headers = apache_request_headers();
+ }
+ else
+ {
+ isset($_SERVER['CONTENT_TYPE']) && $this->headers['Content-Type'] = $_SERVER['CONTENT_TYPE'];
+
+ foreach ($_SERVER as $key => $val)
+ {
+ if (sscanf($key, 'HTTP_%s', $header) === 1)
+ {
+ // take SOME_HEADER and turn it into Some-Header
+ $header = str_replace('_', ' ', strtolower($header));
+ $header = str_replace(' ', '-', ucwords($header));
+
+ $this->headers[$header] = $_SERVER[$key];
+ }
+ }
+ }
+
+ return $this->_fetch_from_array($this->headers, NULL, $xss_clean);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Request Header
+ *
+ * Returns the value of a single member of the headers class member
+ *
+ * @param string $index Header name
+ * @param bool $xss_clean Whether to apply XSS filtering
+ * @return string|null The requested header on success or NULL on failure
+ */
+ public function get_request_header($index, $xss_clean = FALSE)
+ {
+ static $headers;
+
+ if ( ! isset($headers))
+ {
+ empty($this->headers) && $this->request_headers();
+ foreach ($this->headers as $key => $value)
+ {
+ $headers[strtolower($key)] = $value;
+ }
+ }
+
+ $index = strtolower($index);
+
+ if ( ! isset($headers[$index]))
+ {
+ return NULL;
+ }
+
+ return ($xss_clean === TRUE)
+ ? $this->security->xss_clean($headers[$index])
+ : $headers[$index];
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Is AJAX request?
+ *
+ * Test to see if a request contains the HTTP_X_REQUESTED_WITH header.
+ *
+ * @return bool
+ */
+ public function is_ajax_request()
+ {
+ return ( ! empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Is CLI request?
+ *
+ * Test to see if a request was made from the command line.
+ *
+ * @deprecated 3.0.0 Use is_cli() instead
+ * @return bool
+ */
+ public function is_cli_request()
+ {
+ return is_cli();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Request Method
+ *
+ * Return the request method
+ *
+ * @param bool $upper Whether to return in upper or lower case
+ * (default: FALSE)
+ * @return string
+ */
+ public function method($upper = FALSE)
+ {
+ return ($upper)
+ ? strtoupper($this->server('REQUEST_METHOD'))
+ : strtolower($this->server('REQUEST_METHOD'));
+ }
+
+ // ------------------------------------------------------------------------
+
+ /**
+ * Magic __get()
+ *
+ * Allows read access to protected properties
+ *
+ * @param string $name
+ * @return mixed
+ */
+ public function __get($name)
+ {
+ if ($name === 'raw_input_stream')
+ {
+ isset($this->_raw_input_stream) OR $this->_raw_input_stream = file_get_contents('php://input');
+ return $this->_raw_input_stream;
+ }
+ elseif ($name === 'ip_address')
+ {
+ return $this->ip_address;
+ }
+ }
+
+}
diff --git a/www-api/system/core/Lang.php b/www-api/system/core/Lang.php
new file mode 100644
index 00000000..18299060
--- /dev/null
+++ b/www-api/system/core/Lang.php
@@ -0,0 +1,204 @@
+load($value, $idiom, $return, $add_suffix, $alt_path);
+ }
+
+ return;
+ }
+
+ $langfile = str_replace('.php', '', $langfile);
+
+ if ($add_suffix === TRUE)
+ {
+ $langfile = preg_replace('/_lang$/', '', $langfile).'_lang';
+ }
+
+ $langfile .= '.php';
+
+ if (empty($idiom) OR ! preg_match('/^[a-z_-]+$/i', $idiom))
+ {
+ $config =& get_config();
+ $idiom = empty($config['language']) ? 'english' : $config['language'];
+ }
+
+ if ($return === FALSE && isset($this->is_loaded[$langfile]) && $this->is_loaded[$langfile] === $idiom)
+ {
+ return;
+ }
+
+ // Load the base file, so any others found can override it
+ $basepath = BASEPATH.'language/'.$idiom.'/'.$langfile;
+ if (($found = file_exists($basepath)) === TRUE)
+ {
+ include($basepath);
+ }
+
+ // Do we have an alternative path to look in?
+ if ($alt_path !== '')
+ {
+ $alt_path .= 'language/'.$idiom.'/'.$langfile;
+ if (file_exists($alt_path))
+ {
+ include($alt_path);
+ $found = TRUE;
+ }
+ }
+ else
+ {
+ foreach (get_instance()->load->get_package_paths(TRUE) as $package_path)
+ {
+ $package_path .= 'language/'.$idiom.'/'.$langfile;
+ if ($basepath !== $package_path && file_exists($package_path))
+ {
+ include($package_path);
+ $found = TRUE;
+ break;
+ }
+ }
+ }
+
+ if ($found !== TRUE)
+ {
+ show_error('Unable to load the requested language file: language/'.$idiom.'/'.$langfile);
+ }
+
+ if ( ! isset($lang) OR ! is_array($lang))
+ {
+ log_message('error', 'Language file contains no data: language/'.$idiom.'/'.$langfile);
+
+ if ($return === TRUE)
+ {
+ return array();
+ }
+ return;
+ }
+
+ if ($return === TRUE)
+ {
+ return $lang;
+ }
+
+ $this->is_loaded[$langfile] = $idiom;
+ $this->language = array_merge($this->language, $lang);
+
+ log_message('info', 'Language file loaded: language/'.$idiom.'/'.$langfile);
+ return TRUE;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Language line
+ *
+ * Fetches a single line of text from the language array
+ *
+ * @param string $line Language line key
+ * @param bool $log_errors Whether to log an error message if the line is not found
+ * @return string Translation
+ */
+ public function line($line, $log_errors = TRUE)
+ {
+ $value = isset($this->language[$line]) ? $this->language[$line] : FALSE;
+
+ // Because killer robots like unicorns!
+ if ($value === FALSE && $log_errors === TRUE)
+ {
+ log_message('error', 'Could not find the language line "'.$line.'"');
+ }
+
+ return $value;
+ }
+
+}
diff --git a/www-api/system/core/Loader.php b/www-api/system/core/Loader.php
new file mode 100644
index 00000000..a70487e8
--- /dev/null
+++ b/www-api/system/core/Loader.php
@@ -0,0 +1,1416 @@
+ TRUE);
+
+ /**
+ * List of paths to load libraries from
+ *
+ * @var array
+ */
+ protected $_ci_library_paths = array(APPPATH, BASEPATH);
+
+ /**
+ * List of paths to load models from
+ *
+ * @var array
+ */
+ protected $_ci_model_paths = array(APPPATH);
+
+ /**
+ * List of paths to load helpers from
+ *
+ * @var array
+ */
+ protected $_ci_helper_paths = array(APPPATH, BASEPATH);
+
+ /**
+ * List of cached variables
+ *
+ * @var array
+ */
+ protected $_ci_cached_vars = array();
+
+ /**
+ * List of loaded classes
+ *
+ * @var array
+ */
+ protected $_ci_classes = array();
+
+ /**
+ * List of loaded models
+ *
+ * @var array
+ */
+ protected $_ci_models = array();
+
+ /**
+ * List of loaded helpers
+ *
+ * @var array
+ */
+ protected $_ci_helpers = array();
+
+ /**
+ * List of class name mappings
+ *
+ * @var array
+ */
+ protected $_ci_varmap = array(
+ 'unit_test' => 'unit',
+ 'user_agent' => 'agent'
+ );
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Class constructor
+ *
+ * Sets component load paths, gets the initial output buffering level.
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ $this->_ci_ob_level = ob_get_level();
+ $this->_ci_classes =& is_loaded();
+
+ log_message('info', 'Loader Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Initializer
+ *
+ * @todo Figure out a way to move this to the constructor
+ * without breaking *package_path*() methods.
+ * @uses CI_Loader::_ci_autoloader()
+ * @used-by CI_Controller::__construct()
+ * @return void
+ */
+ public function initialize()
+ {
+ $this->_ci_autoloader();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Is Loaded
+ *
+ * A utility method to test if a class is in the self::$_ci_classes array.
+ *
+ * @used-by Mainly used by Form Helper function _get_validation_object().
+ *
+ * @param string $class Class name to check for
+ * @return string|bool Class object name if loaded or FALSE
+ */
+ public function is_loaded($class)
+ {
+ return array_search(ucfirst($class), $this->_ci_classes, TRUE);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Library Loader
+ *
+ * Loads and instantiates libraries.
+ * Designed to be called from application controllers.
+ *
+ * @param mixed $library Library name
+ * @param array $params Optional parameters to pass to the library class constructor
+ * @param string $object_name An optional object name to assign to
+ * @return object
+ */
+ public function library($library, $params = NULL, $object_name = NULL)
+ {
+ if (empty($library))
+ {
+ return $this;
+ }
+ elseif (is_array($library))
+ {
+ foreach ($library as $key => $value)
+ {
+ if (is_int($key))
+ {
+ $this->library($value, $params);
+ }
+ else
+ {
+ $this->library($key, $params, $value);
+ }
+ }
+
+ return $this;
+ }
+
+ if ($params !== NULL && ! is_array($params))
+ {
+ $params = NULL;
+ }
+
+ $this->_ci_load_library($library, $params, $object_name);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Model Loader
+ *
+ * Loads and instantiates models.
+ *
+ * @param mixed $model Model name
+ * @param string $name An optional object name to assign to
+ * @param bool $db_conn An optional database connection configuration to initialize
+ * @return object
+ */
+ public function model($model, $name = '', $db_conn = FALSE)
+ {
+ if (empty($model))
+ {
+ return $this;
+ }
+ elseif (is_array($model))
+ {
+ foreach ($model as $key => $value)
+ {
+ is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn);
+ }
+
+ return $this;
+ }
+
+ $path = '';
+
+ // Is the model in a sub-folder? If so, parse out the filename and path.
+ if (($last_slash = strrpos($model, '/')) !== FALSE)
+ {
+ // The path is in front of the last slash
+ $path = substr($model, 0, ++$last_slash);
+
+ // And the model name behind it
+ $model = substr($model, $last_slash);
+ }
+
+ if (empty($name))
+ {
+ $name = $model;
+ }
+
+ if (in_array($name, $this->_ci_models, TRUE))
+ {
+ return $this;
+ }
+
+ $CI =& get_instance();
+ if (isset($CI->$name))
+ {
+ throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name);
+ }
+
+ if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE))
+ {
+ if ($db_conn === TRUE)
+ {
+ $db_conn = '';
+ }
+
+ $this->database($db_conn, FALSE, TRUE);
+ }
+
+ // Note: All of the code under this condition used to be just:
+ //
+ // load_class('Model', 'core');
+ //
+ // However, load_class() instantiates classes
+ // to cache them for later use and that prevents
+ // MY_Model from being an abstract class and is
+ // sub-optimal otherwise anyway.
+ if ( ! class_exists('CI_Model', FALSE))
+ {
+ $app_path = APPPATH.'core'.DIRECTORY_SEPARATOR;
+ if (file_exists($app_path.'Model.php'))
+ {
+ require_once($app_path.'Model.php');
+ if ( ! class_exists('CI_Model', FALSE))
+ {
+ throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model");
+ }
+
+ log_message('info', 'CI_Model class loaded');
+ }
+ elseif ( ! class_exists('CI_Model', FALSE))
+ {
+ require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php');
+ }
+
+ $class = config_item('subclass_prefix').'Model';
+ if (file_exists($app_path.$class.'.php'))
+ {
+ require_once($app_path.$class.'.php');
+ if ( ! class_exists($class, FALSE))
+ {
+ throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class);
+ }
+
+ log_message('info', config_item('subclass_prefix').'Model class loaded');
+ }
+ }
+
+ $model = ucfirst($model);
+ if ( ! class_exists($model, FALSE))
+ {
+ foreach ($this->_ci_model_paths as $mod_path)
+ {
+ if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
+ {
+ continue;
+ }
+
+ require_once($mod_path.'models/'.$path.$model.'.php');
+ if ( ! class_exists($model, FALSE))
+ {
+ throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model);
+ }
+
+ break;
+ }
+
+ if ( ! class_exists($model, FALSE))
+ {
+ throw new RuntimeException('Unable to locate the model you have specified: '.$model);
+ }
+ }
+ elseif ( ! is_subclass_of($model, 'CI_Model'))
+ {
+ throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model");
+ }
+
+ $this->_ci_models[] = $name;
+ $model = new $model();
+ $CI->$name = $model;
+ log_message('info', 'Model "'.get_class($model).'" initialized');
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Database Loader
+ *
+ * @param mixed $params Database configuration options
+ * @param bool $return Whether to return the database object
+ * @param bool $query_builder Whether to enable Query Builder
+ * (overrides the configuration setting)
+ *
+ * @return object|bool Database object if $return is set to TRUE,
+ * FALSE on failure, CI_Loader instance in any other case
+ */
+ public function database($params = '', $return = FALSE, $query_builder = NULL)
+ {
+ // Grab the super object
+ $CI =& get_instance();
+
+ // Do we even need to load the database class?
+ if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id))
+ {
+ return FALSE;
+ }
+
+ require_once(BASEPATH.'database/DB.php');
+
+ if ($return === TRUE)
+ {
+ return DB($params, $query_builder);
+ }
+
+ // Initialize the db variable. Needed to prevent
+ // reference errors with some configurations
+ $CI->db = '';
+
+ // Load the DB class
+ $CI->db =& DB($params, $query_builder);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Load the Database Utilities Class
+ *
+ * @param object $db Database object
+ * @param bool $return Whether to return the DB Utilities class object or not
+ * @return object
+ */
+ public function dbutil($db = NULL, $return = FALSE)
+ {
+ $CI =& get_instance();
+
+ if ( ! is_object($db) OR ! ($db instanceof CI_DB))
+ {
+ class_exists('CI_DB', FALSE) OR $this->database();
+ $db =& $CI->db;
+ }
+
+ require_once(BASEPATH.'database/DB_utility.php');
+ require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php');
+ $class = 'CI_DB_'.$db->dbdriver.'_utility';
+
+ if ($return === TRUE)
+ {
+ return new $class($db);
+ }
+
+ $CI->dbutil = new $class($db);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Load the Database Forge Class
+ *
+ * @param object $db Database object
+ * @param bool $return Whether to return the DB Forge class object or not
+ * @return object
+ */
+ public function dbforge($db = NULL, $return = FALSE)
+ {
+ $CI =& get_instance();
+ if ( ! is_object($db) OR ! ($db instanceof CI_DB))
+ {
+ class_exists('CI_DB', FALSE) OR $this->database();
+ $db =& $CI->db;
+ }
+
+ require_once(BASEPATH.'database/DB_forge.php');
+ require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php');
+
+ if ( ! empty($db->subdriver))
+ {
+ $driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php';
+ if (file_exists($driver_path))
+ {
+ require_once($driver_path);
+ $class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge';
+ }
+ }
+ else
+ {
+ $class = 'CI_DB_'.$db->dbdriver.'_forge';
+ }
+
+ if ($return === TRUE)
+ {
+ return new $class($db);
+ }
+
+ $CI->dbforge = new $class($db);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * View Loader
+ *
+ * Loads "view" files.
+ *
+ * @param string $view View name
+ * @param array $vars An associative array of data
+ * to be extracted for use in the view
+ * @param bool $return Whether to return the view output
+ * or leave it to the Output class
+ * @return object|string
+ */
+ public function view($view, $vars = array(), $return = FALSE)
+ {
+ return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return));
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Generic File Loader
+ *
+ * @param string $path File path
+ * @param bool $return Whether to return the file output
+ * @return object|string
+ */
+ 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.
+ *
+ * @param array|object|string $vars
+ * An associative array or object containing values
+ * to be set, or a value's name if string
+ * @param string $val Value to set, only used if $vars is a string
+ * @return object
+ */
+ public function vars($vars, $val = '')
+ {
+ $vars = is_string($vars)
+ ? array($vars => $val)
+ : $this->_ci_prepare_view_vars($vars);
+
+ foreach ($vars as $key => $val)
+ {
+ $this->_ci_cached_vars[$key] = $val;
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Clear Cached Variables
+ *
+ * Clears the cached variables.
+ *
+ * @return CI_Loader
+ */
+ public function clear_vars()
+ {
+ $this->_ci_cached_vars = array();
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Variable
+ *
+ * Check if a variable is set and retrieve it.
+ *
+ * @param string $key Variable name
+ * @return mixed The variable or NULL if not found
+ */
+ public function get_var($key)
+ {
+ return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Variables
+ *
+ * Retrieves all loaded variables.
+ *
+ * @return array
+ */
+ public function get_vars()
+ {
+ return $this->_ci_cached_vars;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Helper Loader
+ *
+ * @param string|string[] $helpers Helper name(s)
+ * @return object
+ */
+ public function helper($helpers = array())
+ {
+ is_array($helpers) OR $helpers = array($helpers);
+ foreach ($helpers as &$helper)
+ {
+ $filename = basename($helper);
+ $filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename));
+ $filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper';
+ $helper = $filepath.$filename;
+
+ if (isset($this->_ci_helpers[$helper]))
+ {
+ continue;
+ }
+
+ // Is this a helper extension request?
+ $ext_helper = config_item('subclass_prefix').$filename;
+ $ext_loaded = FALSE;
+ foreach ($this->_ci_helper_paths as $path)
+ {
+ if (file_exists($path.'helpers/'.$ext_helper.'.php'))
+ {
+ include_once($path.'helpers/'.$ext_helper.'.php');
+ $ext_loaded = TRUE;
+ }
+ }
+
+ // If we have loaded extensions - check if the base one is here
+ if ($ext_loaded === TRUE)
+ {
+ $base_helper = BASEPATH.'helpers/'.$helper.'.php';
+ if ( ! file_exists($base_helper))
+ {
+ show_error('Unable to load the requested file: helpers/'.$helper.'.php');
+ }
+
+ include_once($base_helper);
+ $this->_ci_helpers[$helper] = TRUE;
+ log_message('info', 'Helper loaded: '.$helper);
+ continue;
+ }
+
+ // No extensions found ... try loading regular helpers and/or overrides
+ foreach ($this->_ci_helper_paths as $path)
+ {
+ if (file_exists($path.'helpers/'.$helper.'.php'))
+ {
+ include_once($path.'helpers/'.$helper.'.php');
+
+ $this->_ci_helpers[$helper] = TRUE;
+ log_message('info', 'Helper loaded: '.$helper);
+ break;
+ }
+ }
+
+ // unable to load the helper
+ if ( ! isset($this->_ci_helpers[$helper]))
+ {
+ show_error('Unable to load the requested file: helpers/'.$helper.'.php');
+ }
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Load Helpers
+ *
+ * An alias for the helper() method in case the developer has
+ * written the plural form of it.
+ *
+ * @uses CI_Loader::helper()
+ * @param string|string[] $helpers Helper name(s)
+ * @return object
+ */
+ public function helpers($helpers = array())
+ {
+ return $this->helper($helpers);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Language Loader
+ *
+ * Loads language files.
+ *
+ * @param string|string[] $files List of language file names to load
+ * @param string Language name
+ * @return object
+ */
+ public function language($files, $lang = '')
+ {
+ get_instance()->lang->load($files, $lang);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Config Loader
+ *
+ * Loads a config file (an alias for CI_Config::load()).
+ *
+ * @uses CI_Config::load()
+ * @param string $file Configuration file name
+ * @param bool $use_sections Whether configuration values should be loaded into their own section
+ * @param bool $fail_gracefully Whether to just return FALSE or display an error message
+ * @return bool TRUE if the file was loaded correctly or FALSE on failure
+ */
+ public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE)
+ {
+ return get_instance()->config->load($file, $use_sections, $fail_gracefully);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Driver Loader
+ *
+ * Loads a driver library.
+ *
+ * @param string|string[] $library Driver name(s)
+ * @param array $params Optional parameters to pass to the driver
+ * @param string $object_name An optional object name to assign to
+ *
+ * @return object|bool Object or FALSE on failure if $library is a string
+ * and $object_name is set. CI_Loader instance otherwise.
+ */
+ public function driver($library, $params = NULL, $object_name = NULL)
+ {
+ if (is_array($library))
+ {
+ foreach ($library as $key => $value)
+ {
+ if (is_int($key))
+ {
+ $this->driver($value, $params);
+ }
+ else
+ {
+ $this->driver($key, $params, $value);
+ }
+ }
+
+ return $this;
+ }
+ elseif (empty($library))
+ {
+ return FALSE;
+ }
+
+ if ( ! class_exists('CI_Driver_Library', FALSE))
+ {
+ // We aren't instantiating an object here, just making the base class available
+ require BASEPATH.'libraries/Driver.php';
+ }
+
+ // 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);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Add Package Path
+ *
+ * Prepends a parent path to the library, model, helper and config
+ * path arrays.
+ *
+ * @see CI_Loader::$_ci_library_paths
+ * @see CI_Loader::$_ci_model_paths
+ * @see CI_Loader::$_ci_helper_paths
+ * @see CI_Config::$_config_paths
+ *
+ * @param string $path Path to add
+ * @param bool $view_cascade (default: TRUE)
+ * @return object
+ */
+ public function add_package_path($path, $view_cascade = TRUE)
+ {
+ $path = rtrim($path, '/').'/';
+
+ array_unshift($this->_ci_library_paths, $path);
+ array_unshift($this->_ci_model_paths, $path);
+ array_unshift($this->_ci_helper_paths, $path);
+
+ $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;
+
+ // Add config file path
+ $config =& $this->_ci_get_component('config');
+ $config->_config_paths[] = $path;
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Package Paths
+ *
+ * Return a list of all package paths.
+ *
+ * @param bool $include_base Whether to include BASEPATH (default: FALSE)
+ * @return array
+ */
+ public function get_package_paths($include_base = FALSE)
+ {
+ return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Remove Package Path
+ *
+ * Remove a path from the library, model, helper and/or config
+ * path arrays if it exists. If no path is provided, the most recently
+ * added path will be removed removed.
+ *
+ * @param string $path Path to remove
+ * @return object
+ */
+ public function remove_package_path($path = '')
+ {
+ $config =& $this->_ci_get_component('config');
+
+ if ($path === '')
+ {
+ array_shift($this->_ci_library_paths);
+ array_shift($this->_ci_model_paths);
+ array_shift($this->_ci_helper_paths);
+ array_shift($this->_ci_view_paths);
+ array_pop($config->_config_paths);
+ }
+ else
+ {
+ $path = rtrim($path, '/').'/';
+ foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var)
+ {
+ if (($key = array_search($path, $this->{$var})) !== FALSE)
+ {
+ 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)));
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Internal CI Data Loader
+ *
+ * Used to load views and files.
+ *
+ * Variables are prefixed with _ci_ to avoid symbol collision with
+ * variables made available to view files.
+ *
+ * @used-by CI_Loader::view()
+ * @used-by CI_Loader::file()
+ * @param array $_ci_data Data to load
+ * @return object
+ */
+ protected function _ci_load($_ci_data)
+ {
+ // Set the default data variables
+ foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
+ {
+ $$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE;
+ }
+
+ $file_exists = FALSE;
+
+ // Set the path to the requested file
+ if (is_string($_ci_path) && $_ci_path !== '')
+ {
+ $_ci_x = explode('/', $_ci_path);
+ $_ci_file = end($_ci_x);
+ }
+ else
+ {
+ $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
+ $_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view;
+
+ foreach ($this->_ci_view_paths as $_ci_view_file => $cascade)
+ {
+ if (file_exists($_ci_view_file.$_ci_file))
+ {
+ $_ci_path = $_ci_view_file.$_ci_file;
+ $file_exists = TRUE;
+ break;
+ }
+
+ if ( ! $cascade)
+ {
+ break;
+ }
+ }
+ }
+
+ if ( ! $file_exists && ! file_exists($_ci_path))
+ {
+ show_error('Unable to load the requested file: '.$_ci_file);
+ }
+
+ // This allows anything loaded using $this->load (views, files, etc.)
+ // to become accessible from within the Controller and Model functions.
+ $_ci_CI =& get_instance();
+ foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
+ {
+ if ( ! isset($this->$_ci_key))
+ {
+ $this->$_ci_key =& $_ci_CI->$_ci_key;
+ }
+ }
+
+ /*
+ * Extract and cache variables
+ *
+ * You can either set variables using the dedicated $this->load->vars()
+ * function or via the second parameter of this function. We'll merge
+ * the two types and cache them so that views that are embedded within
+ * other views can have access to these variables.
+ */
+ empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
+ extract($this->_ci_cached_vars);
+
+ /*
+ * Buffer the output
+ *
+ * We buffer the output for two reasons:
+ * 1. Speed. You get a significant speed boost.
+ * 2. So that the final rendered template can be post-processed by
+ * the output class. Why do we need post processing? For one thing,
+ * in order to show the elapsed page load time. Unless we can
+ * intercept the content right before it's sent to the browser and
+ * then stop the timer it won't be accurate.
+ */
+ ob_start();
+
+ // If the PHP installation does not support short tags we'll
+ // do a little string replacement, changing the short tags
+ // to standard PHP echo statements.
+ if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE)
+ {
+ echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('=', ' $this->_ci_ob_level + 1)
+ {
+ ob_end_flush();
+ }
+ else
+ {
+ $_ci_CI->output->append_output(ob_get_contents());
+ @ob_end_clean();
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Internal CI Library Loader
+ *
+ * @used-by CI_Loader::library()
+ * @uses CI_Loader::_ci_init_library()
+ *
+ * @param string $class Class name to load
+ * @param mixed $params Optional parameters to pass to the class constructor
+ * @param string $object_name Optional object name to assign to
+ * @return void
+ */
+ protected function _ci_load_library($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('.php', '', trim($class, '/'));
+
+ // Was the path included with the class name?
+ // We look for a slash to determine this
+ if (($last_slash = strrpos($class, '/')) !== FALSE)
+ {
+ // Extract the path
+ $subdir = substr($class, 0, ++$last_slash);
+
+ // Get the filename from the path
+ $class = substr($class, $last_slash);
+ }
+ else
+ {
+ $subdir = '';
+ }
+
+ $class = ucfirst($class);
+
+ // Is this a stock library? There are a few special conditions if so ...
+ if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php'))
+ {
+ return $this->_ci_load_stock_library($class, $subdir, $params, $object_name);
+ }
+
+ // Safety: Was the class already loaded by a previous call?
+ if (class_exists($class, FALSE))
+ {
+ $property = $object_name;
+ if (empty($property))
+ {
+ $property = strtolower($class);
+ isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property];
+ }
+
+ $CI =& get_instance();
+ if (isset($CI->$property))
+ {
+ log_message('debug', $class.' class already loaded. Second attempt ignored.');
+ return;
+ }
+
+ return $this->_ci_init_library($class, '', $params, $object_name);
+ }
+
+ // Let's search for the requested library file and load it.
+ foreach ($this->_ci_library_paths as $path)
+ {
+ // BASEPATH has already been checked for
+ if ($path === BASEPATH)
+ {
+ continue;
+ }
+
+ $filepath = $path.'libraries/'.$subdir.$class.'.php';
+ // Does the file exist? No? Bummer...
+ if ( ! file_exists($filepath))
+ {
+ continue;
+ }
+
+ include_once($filepath);
+ return $this->_ci_init_library($class, '', $params, $object_name);
+ }
+
+ // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
+ if ($subdir === '')
+ {
+ return $this->_ci_load_library($class.'/'.$class, $params, $object_name);
+ }
+
+ // If we got this far we were unable to find the requested class.
+ log_message('error', 'Unable to load the requested class: '.$class);
+ show_error('Unable to load the requested class: '.$class);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Internal CI Stock Library Loader
+ *
+ * @used-by CI_Loader::_ci_load_library()
+ * @uses CI_Loader::_ci_init_library()
+ *
+ * @param string $library_name Library name to load
+ * @param string $file_path Path to the library filename, relative to libraries/
+ * @param mixed $params Optional parameters to pass to the class constructor
+ * @param string $object_name Optional object name to assign to
+ * @return void
+ */
+ protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name)
+ {
+ $prefix = 'CI_';
+
+ if (class_exists($prefix.$library_name, FALSE))
+ {
+ if (class_exists(config_item('subclass_prefix').$library_name, FALSE))
+ {
+ $prefix = config_item('subclass_prefix');
+ }
+
+ $property = $object_name;
+ if (empty($property))
+ {
+ $property = strtolower($library_name);
+ isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property];
+ }
+
+ $CI =& get_instance();
+ if ( ! isset($CI->$property))
+ {
+ return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
+ }
+
+ log_message('debug', $library_name.' class already loaded. Second attempt ignored.');
+ return;
+ }
+
+ $paths = $this->_ci_library_paths;
+ array_pop($paths); // BASEPATH
+ array_pop($paths); // APPPATH (needs to be the first path checked)
+ array_unshift($paths, APPPATH);
+
+ foreach ($paths as $path)
+ {
+ if (file_exists($path = $path.'libraries/'.$file_path.$library_name.'.php'))
+ {
+ // Override
+ include_once($path);
+ if (class_exists($prefix.$library_name, FALSE))
+ {
+ return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
+ }
+
+ log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name);
+ }
+ }
+
+ include_once(BASEPATH.'libraries/'.$file_path.$library_name.'.php');
+
+ // Check for extensions
+ $subclass = config_item('subclass_prefix').$library_name;
+ foreach ($paths as $path)
+ {
+ if (file_exists($path = $path.'libraries/'.$file_path.$subclass.'.php'))
+ {
+ include_once($path);
+ if (class_exists($subclass, FALSE))
+ {
+ $prefix = config_item('subclass_prefix');
+ break;
+ }
+
+ log_message('debug', $path.' exists, but does not declare '.$subclass);
+ }
+ }
+
+ return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Internal CI Library Instantiator
+ *
+ * @used-by CI_Loader::_ci_load_stock_library()
+ * @used-by CI_Loader::_ci_load_library()
+ *
+ * @param string $class Class name
+ * @param string $prefix Class name prefix
+ * @param array|null|bool $config Optional configuration to pass to the class constructor:
+ * FALSE to skip;
+ * NULL to search in config paths;
+ * array containing configuration data
+ * @param string $object_name Optional object name to assign to
+ * @return void
+ */
+ protected function _ci_init_library($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)
+ {
+ // Fetch the config paths containing any package paths
+ $config_component = $this->_ci_get_component('config');
+
+ if (is_array($config_component->_config_paths))
+ {
+ $found = FALSE;
+ 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. Load global first,
+ // override with environment next
+ if (file_exists($path.'config/'.strtolower($class).'.php'))
+ {
+ include($path.'config/'.strtolower($class).'.php');
+ $found = TRUE;
+ }
+ elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php'))
+ {
+ include($path.'config/'.ucfirst(strtolower($class)).'.php');
+ $found = TRUE;
+ }
+
+ if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
+ {
+ include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
+ $found = TRUE;
+ }
+ elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
+ {
+ include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
+ $found = TRUE;
+ }
+
+ // Break on the first found configuration, thus package
+ // files are not overridden by default paths
+ if ($found === TRUE)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ $class_name = $prefix.$class;
+
+ // Is the class name valid?
+ if ( ! class_exists($class_name, FALSE))
+ {
+ log_message('error', 'Non-existent class: '.$class_name);
+ show_error('Non-existent class: '.$class_name);
+ }
+
+ // Set the variable name we will assign the class to
+ // Was a custom class name supplied? If so we'll use it
+ if (empty($object_name))
+ {
+ $object_name = strtolower($class);
+ if (isset($this->_ci_varmap[$object_name]))
+ {
+ $object_name = $this->_ci_varmap[$object_name];
+ }
+ }
+
+ // Don't overwrite existing properties
+ $CI =& get_instance();
+ if (isset($CI->$object_name))
+ {
+ if ($CI->$object_name instanceof $class_name)
+ {
+ log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted.");
+ return;
+ }
+
+ show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance.");
+ }
+
+ // Save the class name and object name
+ $this->_ci_classes[$object_name] = $class;
+
+ // Instantiate the class
+ $CI->$object_name = isset($config)
+ ? new $class_name($config)
+ : new $class_name();
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * CI Autoloader
+ *
+ * Loads component listed in the config/autoload.php file.
+ *
+ * @used-by CI_Loader::initialize()
+ * @return void
+ */
+ protected function _ci_autoloader()
+ {
+ if (file_exists(APPPATH.'config/autoload.php'))
+ {
+ include(APPPATH.'config/autoload.php');
+ }
+
+ if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
+ {
+ include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
+ }
+
+ if ( ! isset($autoload))
+ {
+ return;
+ }
+
+ // 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)
+ {
+ foreach ($autoload['config'] as $val)
+ {
+ $this->config($val);
+ }
+ }
+
+ // Autoload helpers and languages
+ foreach (array('helper', 'language') as $type)
+ {
+ if (isset($autoload[$type]) && count($autoload[$type]) > 0)
+ {
+ $this->$type($autoload[$type]);
+ }
+ }
+
+ // Autoload drivers
+ if (isset($autoload['drivers']))
+ {
+ $this->driver($autoload['drivers']);
+ }
+
+ // Load libraries
+ if (isset($autoload['libraries']) && count($autoload['libraries']) > 0)
+ {
+ // Load the database driver.
+ if (in_array('database', $autoload['libraries']))
+ {
+ $this->database();
+ $autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
+ }
+
+ // Load all other libraries
+ $this->library($autoload['libraries']);
+ }
+
+ // Autoload models
+ if (isset($autoload['model']))
+ {
+ $this->model($autoload['model']);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Prepare variables for _ci_vars, to be later extract()-ed inside views
+ *
+ * Converts objects to associative arrays and filters-out internal
+ * variable names (i.e. keys prefixed with '_ci_').
+ *
+ * @param mixed $vars
+ * @return array
+ */
+ protected function _ci_prepare_view_vars($vars)
+ {
+ if ( ! is_array($vars))
+ {
+ $vars = is_object($vars)
+ ? get_object_vars($vars)
+ : array();
+ }
+
+ foreach (array_keys($vars) as $key)
+ {
+ if (strncmp($key, '_ci_', 4) === 0)
+ {
+ unset($vars[$key]);
+ }
+ }
+
+ return $vars;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * CI Component getter
+ *
+ * Get a reference to a specific library or model.
+ *
+ * @param string $component Component name
+ * @return bool
+ */
+ protected function &_ci_get_component($component)
+ {
+ $CI =& get_instance();
+ return $CI->$component;
+ }
+}
diff --git a/www-api/system/core/Log.php b/www-api/system/core/Log.php
new file mode 100644
index 00000000..ca3e38a7
--- /dev/null
+++ b/www-api/system/core/Log.php
@@ -0,0 +1,297 @@
+ 1, 'DEBUG' => 2, 'INFO' => 3, 'ALL' => 4);
+
+ /**
+ * mbstring.func_overload flag
+ *
+ * @var bool
+ */
+ protected static $func_overload;
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Class constructor
+ *
+ * @return void
+ */
+ public function __construct()
+ {
+ $config =& get_config();
+
+ isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload'));
+
+ $this->_log_path = ($config['log_path'] !== '') ? $config['log_path'] : APPPATH.'logs/';
+ $this->_file_ext = (isset($config['log_file_extension']) && $config['log_file_extension'] !== '')
+ ? ltrim($config['log_file_extension'], '.') : 'php';
+
+ file_exists($this->_log_path) OR mkdir($this->_log_path, 0755, TRUE);
+
+ if ( ! is_dir($this->_log_path) OR ! is_really_writable($this->_log_path))
+ {
+ $this->_enabled = FALSE;
+ }
+
+ if (is_numeric($config['log_threshold']))
+ {
+ $this->_threshold = (int) $config['log_threshold'];
+ }
+ elseif (is_array($config['log_threshold']))
+ {
+ $this->_threshold = 0;
+ $this->_threshold_array = array_flip($config['log_threshold']);
+ }
+
+ if ( ! empty($config['log_date_format']))
+ {
+ $this->_date_fmt = $config['log_date_format'];
+ }
+
+ if ( ! empty($config['log_file_permissions']) && is_int($config['log_file_permissions']))
+ {
+ $this->_file_permissions = $config['log_file_permissions'];
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Write Log File
+ *
+ * Generally this function will be called using the global log_message() function
+ *
+ * @param string $level The error level: 'error', 'debug' or 'info'
+ * @param string $msg The error message
+ * @return bool
+ */
+ public function write_log($level, $msg)
+ {
+ if ($this->_enabled === FALSE)
+ {
+ return FALSE;
+ }
+
+ $level = strtoupper($level);
+
+ if (( ! isset($this->_levels[$level]) OR ($this->_levels[$level] > $this->_threshold))
+ && ! isset($this->_threshold_array[$this->_levels[$level]]))
+ {
+ return FALSE;
+ }
+
+ $filepath = $this->_log_path.'log-'.date('Y-m-d').'.'.$this->_file_ext;
+ $message = '';
+
+ if ( ! file_exists($filepath))
+ {
+ $newfile = TRUE;
+ // Only add protection to php files
+ if ($this->_file_ext === 'php')
+ {
+ $message .= "\n\n";
+ }
+ }
+
+ if ( ! $fp = @fopen($filepath, 'ab'))
+ {
+ return FALSE;
+ }
+
+ flock($fp, LOCK_EX);
+
+ // Instantiating DateTime with microseconds appended to initial date is needed for proper support of this format
+ if (strpos($this->_date_fmt, 'u') !== FALSE)
+ {
+ $microtime_full = microtime(TRUE);
+ $microtime_short = sprintf("%06d", ($microtime_full - floor($microtime_full)) * 1000000);
+ $date = new DateTime(date('Y-m-d H:i:s.'.$microtime_short, $microtime_full));
+ $date = $date->format($this->_date_fmt);
+ }
+ else
+ {
+ $date = date($this->_date_fmt);
+ }
+
+ $message .= $this->_format_line($level, $date, $msg);
+
+ for ($written = 0, $length = self::strlen($message); $written < $length; $written += $result)
+ {
+ if (($result = fwrite($fp, self::substr($message, $written))) === FALSE)
+ {
+ break;
+ }
+ }
+
+ flock($fp, LOCK_UN);
+ fclose($fp);
+
+ if (isset($newfile) && $newfile === TRUE)
+ {
+ chmod($filepath, $this->_file_permissions);
+ }
+
+ return is_int($result);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Format the log line.
+ *
+ * This is for extensibility of log formatting
+ * If you want to change the log format, extend the CI_Log class and override this method
+ *
+ * @param string $level The error level
+ * @param string $date Formatted date string
+ * @param string $message The log message
+ * @return string Formatted log line with a new line character at the end
+ */
+ protected function _format_line($level, $date, $message)
+ {
+ return $level.' - '.$date.' --> '.$message.PHP_EOL;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Byte-safe strlen()
+ *
+ * @param string $str
+ * @return int
+ */
+ protected static function strlen($str)
+ {
+ return (self::$func_overload)
+ ? mb_strlen($str, '8bit')
+ : strlen($str);
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Byte-safe substr()
+ *
+ * @param string $str
+ * @param int $start
+ * @param int $length
+ * @return string
+ */
+ protected static function substr($str, $start, $length = NULL)
+ {
+ if (self::$func_overload)
+ {
+ // mb_substr($str, $start, null, '8bit') returns an empty
+ // string on PHP 5.3
+ isset($length) OR $length = ($start >= 0 ? self::strlen($str) - $start : -$start);
+ return mb_substr($str, $start, $length, '8bit');
+ }
+
+ return isset($length)
+ ? substr($str, $start, $length)
+ : substr($str, $start);
+ }
+}
diff --git a/www-api/system/core/Model.php b/www-api/system/core/Model.php
new file mode 100644
index 00000000..b2bbbd4d
--- /dev/null
+++ b/www-api/system/core/Model.php
@@ -0,0 +1,77 @@
+$key;
+ }
+
+}
diff --git a/www-api/system/core/Output.php b/www-api/system/core/Output.php
new file mode 100644
index 00000000..a629a09d
--- /dev/null
+++ b/www-api/system/core/Output.php
@@ -0,0 +1,847 @@
+_zlib_oc = (bool) ini_get('zlib.output_compression');
+ $this->_compress_output = (
+ $this->_zlib_oc === FALSE
+ && config_item('compress_output') === TRUE
+ && extension_loaded('zlib')
+ );
+
+ isset(self::$func_overload) OR self::$func_overload = ( ! is_php('8.0') && extension_loaded('mbstring') && @ini_get('mbstring.func_overload'));
+
+ // Get mime types for later
+ $this->mimes =& get_mimes();
+
+ log_message('info', 'Output Class Initialized');
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Output
+ *
+ * Returns the current output string.
+ *
+ * @return string
+ */
+ public function get_output()
+ {
+ return $this->final_output;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Output
+ *
+ * Sets the output string.
+ *
+ * @param string $output Output data
+ * @return CI_Output
+ */
+ public function set_output($output)
+ {
+ $this->final_output = $output;
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Append Output
+ *
+ * Appends data onto the output string.
+ *
+ * @param string $output Data to append
+ * @return CI_Output
+ */
+ public function append_output($output)
+ {
+ $this->final_output .= $output;
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Header
+ *
+ * Lets you set a server header which will be sent with the final output.
+ *
+ * Note: If a file is cached, headers will not be sent.
+ * @todo We need to figure out how to permit headers to be cached.
+ *
+ * @param string $header Header
+ * @param bool $replace Whether to replace the old header value, if already set
+ * @return CI_Output
+ */
+ public 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;
+ }
+
+ $this->headers[] = array($header, $replace);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Content-Type Header
+ *
+ * @param string $mime_type Extension of the file we're outputting
+ * @param string $charset Character set (default: NULL)
+ * @return CI_Output
+ */
+ public function set_content_type($mime_type, $charset = NULL)
+ {
+ if (strpos($mime_type, '/') === FALSE)
+ {
+ $extension = ltrim($mime_type, '.');
+
+ // Is this extension supported?
+ if (isset($this->mimes[$extension]))
+ {
+ $mime_type =& $this->mimes[$extension];
+
+ if (is_array($mime_type))
+ {
+ $mime_type = current($mime_type);
+ }
+ }
+ }
+
+ $this->mime_type = $mime_type;
+
+ if (empty($charset))
+ {
+ $charset = config_item('charset');
+ }
+
+ $header = 'Content-Type: '.$mime_type
+ .(empty($charset) ? '' : '; charset='.$charset);
+
+ $this->headers[] = array($header, TRUE);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Current Content-Type Header
+ *
+ * @return string 'text/html', if not already set
+ */
+ public function get_content_type()
+ {
+ for ($i = 0, $c = count($this->headers); $i < $c; $i++)
+ {
+ if (sscanf($this->headers[$i][0], 'Content-Type: %[^;]', $content_type) === 1)
+ {
+ return $content_type;
+ }
+ }
+
+ return 'text/html';
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Get Header
+ *
+ * @param string $header
+ * @return string
+ */
+ public function get_header($header)
+ {
+ // We only need [x][0] from our multi-dimensional array
+ $header_lines = array_map(function ($headers)
+ {
+ return array_shift($headers);
+ }, $this->headers);
+
+ $headers = array_merge(
+ $header_lines,
+ headers_list()
+ );
+
+ if (empty($headers) OR empty($header))
+ {
+ return NULL;
+ }
+
+ // Count backwards, in order to get the last matching header
+ for ($c = count($headers) - 1; $c > -1; $c--)
+ {
+ if (strncasecmp($header, $headers[$c], $l = self::strlen($header)) === 0)
+ {
+ return trim(self::substr($headers[$c], $l+1));
+ }
+ }
+
+ return NULL;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set HTTP Status Header
+ *
+ * As of version 1.7.2, this is an alias for common function
+ * set_status_header().
+ *
+ * @param int $code Status code (default: 200)
+ * @param string $text Optional message
+ * @return CI_Output
+ */
+ public function set_status_header($code = 200, $text = '')
+ {
+ set_status_header($code, $text);
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Enable/disable Profiler
+ *
+ * @param bool $val TRUE to enable or FALSE to disable
+ * @return CI_Output
+ */
+ public 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.
+ *
+ * @param array $sections Profiler sections
+ * @return CI_Output
+ */
+ public function set_profiler_sections($sections)
+ {
+ if (isset($sections['query_toggle_count']))
+ {
+ $this->_profiler_sections['query_toggle_count'] = (int) $sections['query_toggle_count'];
+ unset($sections['query_toggle_count']);
+ }
+
+ foreach ($sections as $section => $enable)
+ {
+ $this->_profiler_sections[$section] = ($enable !== FALSE);
+ }
+
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Set Cache
+ *
+ * @param int $time Cache expiration time in minutes
+ * @return CI_Output
+ */
+ public function cache($time)
+ {
+ $this->cache_expiration = is_numeric($time) ? $time : 0;
+ return $this;
+ }
+
+ // --------------------------------------------------------------------
+
+ /**
+ * Display Output
+ *
+ * Processes and sends finalized output data to the browser along
+ * with any server headers and profile data. It also stops benchmark
+ * timers so the page rendering speed and memory usage can be shown.
+ *
+ * Note: All "view" data is automatically put into $this->final_output
+ * by controller class.
+ *
+ * @uses CI_Output::$final_output
+ * @param string $output Output data override
+ * @return void
+ */
+ public function _display($output = '')
+ {
+ // Note: We use load_class() 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.
+ $BM =& load_class('Benchmark', 'core');
+ $CFG =& load_class('Config', 'core');
+
+ // Grab the super object if we can.
+ if (class_exists('CI_Controller', FALSE))
+ {
+ $CI =& get_instance();
+ }
+
+ // --------------------------------------------------------------------
+
+ // Set the output data
+ if ($output === '')
+ {
+ $output =& $this->final_output;
+ }
+
+ // --------------------------------------------------------------------
+
+ // 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');
+
+ if ($this->parse_exec_vars === TRUE)
+ {
+ $memory = round(memory_get_usage() / 1024 / 1024, 2).'MB';
+ $output = str_replace(array('{elapsed_time}', '{memory_usage}'), array($elapsed, $memory), $output);
+ }
+
+ // --------------------------------------------------------------------
+
+ // Is compression requested?
+ if (isset($CI) // This means that we're not serving a cache file, if we were, it would already be compressed
+ && $this->_compress_output === TRUE
+ && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
+ {
+ ob_start('ob_gzhandler');
+ }
+
+ // --------------------------------------------------------------------
+
+ // Are there any server headers to send?
+ if (count($this->headers) > 0)
+ {
+ foreach ($this->headers as $header)
+ {
+ @header($header[0], $header[1]);
+ }
+ }
+
+ // --------------------------------------------------------------------
+
+ // Does the $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 ( ! isset($CI))
+ {
+ if ($this->_compress_output === TRUE)
+ {
+ if (isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE)
+ {
+ header('Content-Encoding: gzip');
+ header('Content-Length: '.self::strlen($output));
+ }
+ else
+ {
+ // User agent doesn't support gzip compression,
+ // so we'll have to decompress our cache
+ $output = gzinflate(self::substr($output, 10, -8));
+ }
+ }
+
+ echo $output;
+ log_message('info', 'Final output sent to browser');
+ log_message('debug', 'Total execution time: '.$elapsed);
+ return;
+ }
+
+ // --------------------------------------------------------------------
+
+ // Do we need to generate profile data?
+ // If so, load the Profile class and run it.
+ if ($this->enable_profiler === TRUE)
+ {
+ $CI->load->library('profiler');
+ if ( ! empty($this->_profiler_sections))
+ {
+ $CI->profiler->set_sections($this->_profiler_sections);
+ }
+
+ // If the output data contains closing