diff --git a/.codeclimate.yml b/.codeclimate.yml
deleted file mode 100644
index b1059fca..00000000
--- a/.codeclimate.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-exclude_paths:
-- "documentation/"
-- "application/language/"
\ No newline at end of file
diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
new file mode 100644
index 00000000..5d609ac7
--- /dev/null
+++ b/.github/CODEOWNERS
@@ -0,0 +1 @@
+* @chriskacerguis
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..34ee3d3c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,35 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: ''
+assignees: ''
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Please provide either a cleanly formatted code snippet or a link to repo / gist with code that I can use to reproduce:
+
+```php
+ public function set_response($data = null, $http_code = null)
+ {
+ $this->response($data, $http_code, true);
+ }
+```
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots / Error Messages**
+If applicable, add screenshots and/or error messages to help explain your problem.
+
+**Environment (please complete the following information):**
+ - PHP Version: [e.g. 7.2.1]
+ - CodeIgniter Version [e.g. 4.0.1]
+ - Version [e.g. 22]
+
+**Additional context**
+Add any other context about the problem here.
diff --git a/AUTHORS.md b/AUTHORS.md
deleted file mode 100644
index ee3551f6..00000000
--- a/AUTHORS.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# The Core Team
-
-* [Chris Kacerguis](//github.com/chriskacerguis)
-* [Phil Sturgeon](//github.com/philsturgeon)
-
-### Special Thanks To
-
-* [Fabian Hanisch](//github.com/Hanisch-IT)
-
-*For a list of people who have contributed to the codebase, see [GitHub's list of contributors](https://github.com/chriskacerguis/codeigniter-restserver/graphs/contributors). Anyone who has contributed please do a PR and add to this file.*
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index ce83aeda..00000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,66 +0,0 @@
-Changelog:
-===========
-
-### UNRELEASED
-* Added support for CodeIgniter controller's index methods (index_GET, index_POST...)
-* Added exceptions handling when the method could not be found
-
-### 2.7.2
-
-* Added $this->query() in which query parameters can now be obtained regardless of whether a GET request is sent or not
-* Added doc comments added to functions
-* Added HTTP status constants e.g. REST_Controller::HTTP_OK
-* Added new CSV formatting function
-* Fixed numerous bug fixes
-* Updated API calls limit can be based on API key, routed url or method name
-* Updated documentation
-* Updated examples (thanks @ivantcholakov and @lagaisse)
-* Updated many functions by re-writing (thanks @softwarespot)
-* Updated performance increase
-
-### 2.7.0
-
-* Added Blacklist IP option
-* Added controller based access controls
-* Added support for OPTIONS, PATCH, and HEAD (from boh1996)
-* Added logging of the time it takes for a request (rtime column in DB)
-* Changed DB schemas to use InnoDB, not MyISAM
-* Updated Readme to reflect new developer (Chris Kacerguis)
-
-### 2.6.2
-
-* Update CodeIgniter files to 2.1.3
-* Fixed issue #165
-
-### 2.6.1
-
-* Update CodeIgniter files to 2.1.2
-* Log Table support for IPv6 & NULL parameters
-* Abstract out the processes of firing a controller method within _remap() to an separate method
-* Moved GET, POST, PUT, and DELETE parsing to separate methods, allowing them to be overridden as needed
-* Small bug-fix for a PHP 5.3 strlen error
-* Fixed some PHP 5.4 warnings
-* Fix for bug in Format.php's to_html() which failed to detect if $data was really a multidimensional array.
-* Fix for empty node on XML output format, for false = 0, true = 1.
-
-### 2.6.0
-
-* Added loads of PHPDoc comments.
-* Response where method doesn't exist is now "HTTP 405 Method Not Allowed", not "HTTP 404 Not Found".
-* Compatible with PHP 5.4.
-* Added support for gzip compression.
-* Fix the apache\_request\_header function with CGI.
-* Fixed up correctly .foo extensions to work when get arguments provided.
-* Allows method emulation via X-HTTP-Method-Override
-* Support for Backbone.emulateHTTP improved.
-* Combine both URI segment and GET params instead of using one or the other
-* Separate each piece of the WWW-Authenticate header for digest requests with a comma.
-* Added IP white-list option.
-
-### 2.5
-
-* Instead of just seeing item, item, item, the singular version of the base-node will be used if possible. [Example](http://d.pr/RS46).
-* Re-factored to use the Format library, which will soon be merged with CodeIgniter.
-* Fixed Limit bug (limit of 5 would allow 6 requests).
-* Added logging for invalid API key requests.
-* Changed serialize to serialized.
diff --git a/README.md b/README.md
index 5eb82281..59776fe9 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,27 @@
-# CodeIgniter Rest Server
+# CodeIgniter RestServer
-[](https://gitter.im/codeigniter-restserver/Lobby)
+A fully RESTful server implementation for CodeIgniter 3 using one library, one config file and one controller.
-A fully RESTful server implementation for CodeIgniter using one library, one
-config file and one controller.
+> [!IMPORTANT]
+> I have published the first "beta" of codeigniter-restserver 4. See the "development" branch. Please be sure to note the system requirments.
## Requirements
-1. PHP 5.4 or greater
-2. CodeIgniter 3.0+
+- PHP 7.2 or greater
+- CodeIgniter 3.1.11+
-_Note: for 1.7.x support download v2.2 from Downloads tab_
+## Installation
-## Important Update on 4.0.0
-
-Please note that version 4.0.0 is in the works, and is considered a breaking change (per SemVer). As CI 3.1.0 now has native support for Composer, this library will be moving to be composer based.
-
-Take a look at the "development" branch to see what's up.
+```sh
+composer require chriskacerguis/codeigniter-restserver
+```
-## Installation & loading
+## Usage
CodeIgniter Rest Server is available on [Packagist](https://packagist.org/packages/chriskacerguis/codeigniter-restserver) (using semantic versioning), and installation via composer is the recommended way to install Codeigniter Rest Server. Just add this line to your `composer.json` file:
```json
-"chriskacerguis/codeigniter-restserver": "^3.0"
+"chriskacerguis/codeigniter-restserver": "^3.1"
```
or run
@@ -32,208 +30,135 @@ or run
composer require chriskacerguis/codeigniter-restserver
```
-## Handling Requests
+Note that you will need to copy `rest.php` to your `config` directory (e.g. `application/config`)
-When your controller extends from `REST_Controller`, the method names will be appended with the HTTP method used to access the request. If you're making an HTTP `GET` call to `/books`, for instance, it would call a `Books#index_get()` method.
-
-This allows you to implement a RESTful interface easily:
+Step 1: Add this to your controller (should be before any of your code)
```php
-class Books extends REST_Controller
-{
- public function index_get()
- {
- // Display all books
- }
-
- public function index_post()
- {
- // Create a new book
- }
-}
+use chriskacerguis\RestServer\RestController;
```
-`REST_Controller` also supports `PUT` and `DELETE` methods, allowing you to support a truly RESTful interface.
-
-
-Accessing parameters is also easy. Simply use the name of the HTTP verb as a method:
+Step 2: Extend your controller
```php
-$this->get('blah'); // GET param
-$this->post('blah'); // POST param
-$this->put('blah'); // PUT param
+class Example extends RestController
```
-The HTTP spec for DELETE requests precludes the use of parameters. For delete requests, you can add items to the URL
+## Basic GET example
-```php
-public function index_delete($id)
-{
- $this->response([
- 'returned from delete:' => $id,
- ]);
-}
-```
+Here is a basic example. This controller, which should be saved as `Api.php`, can be called in two ways:
-If query parameters are passed via the URL, regardless of whether it's a GET request, can be obtained by the query method:
+* `http://domain/api/users/` will return the list of all users
+* `http://domain/api/users/id/1` will only return information about the user with id = 1
```php
-$this->query('blah'); // Query param
-```
-
-## Content Types
-
-`REST_Controller` supports a bunch of different request/response formats, including XML, JSON and serialised PHP. By default, the class will check the URL and look for a format either as an extension or as a separate segment.
-
-This means your URLs can look like this:
-```
-http://example.com/books.json
-http://example.com/books?format=json
-```
-
-This can be flaky with URI segments, so the recommend approach is using the HTTP `Accept` header:
-
-```bash
-$ curl -H "Accept: application/json" http://example.com
-```
-
-Any responses you make from the class (see [responses](#responses) for more on this) will be serialised in the designated format.
-
-## Responses
-
-The class provides a `response()` method that allows you to return data in the user's requested response format.
-
-Returning any object / array / string / whatever is easy:
-
-```php
-public function index_get()
-{
- $this->response($this->db->get('books')->result());
+ 0, 'name' => 'John', 'email' => 'john@example.com'],
+ ['id' => 1, 'name' => 'Jim', 'email' => 'jim@example.com'],
+ ];
+
+ $id = $this->get( 'id' );
+
+ if ( $id === null )
+ {
+ // Check if the users data store contains users
+ if ( $users )
+ {
+ // Set the response and exit
+ $this->response( $users, 200 );
+ }
+ else
+ {
+ // Set the response and exit
+ $this->response( [
+ 'status' => false,
+ 'message' => 'No users were found'
+ ], 404 );
+ }
+ }
+ else
+ {
+ if ( array_key_exists( $id, $users ) )
+ {
+ $this->response( $users[$id], 200 );
+ }
+ else
+ {
+ $this->response( [
+ 'status' => false,
+ 'message' => 'No such user found'
+ ], 404 );
+ }
+ }
+ }
}
```
-This will automatically return an `HTTP 200 OK` response. You can specify the status code in the second parameter:
-
-```php
-public function index_post()
- {
- // ...create new book
- $this->response($book, 201); // Send an HTTP 201 Created
- }
-```
+## Extending supported formats
-If you don't specify a response code, and the data you respond with `== FALSE` (an empty array or string, for instance), the response code will automatically be set to `404 Not Found`:
+If you need to be able to support more formats for replies, you can extend the
+`Format` class to add the required `to_...` methods
+1. Extend the `RestController` class (in `libraries/MY_REST_Controller.php`)
```php
-$this->response([]); // HTTP 404 Not Found
-```
-
-## Configuration
-
-You can overwrite all default configurations by creating a rest.php file in your config folder with your configs.
-All given configurations will overwrite the default ones.
-
-## Language
+response->lang` object:
-
-```php
-public function __construct()
+class MY_REST_Controller extends RestController
{
- parent::__construct();
-
- if (is_array($this->response->lang))
- {
- $this->load->language('application', $this->response->lang[0]);
- }
- else
- {
- $this->load->language('application', $this->response->lang);
- }
+ public function __construct()
+ {
+ parent::__construct();
+ // This can be the library's chriskacerguis\RestServer\Format
+ // or your own custom overloaded Format class (see bellow)
+ $this->format = new Format();
+ }
}
```
-## Authentication
-
-This class also provides rudimentary support for HTTP basic authentication and/or the securer HTTP digest access authentication.
-
-You can enable basic authentication by setting the `$config['rest_auth']` to `'basic'`. The `$config['rest_valid_logins']` directive can then be used to set the usernames and passwords able to log in to your system. The class will automatically send all the correct headers to trigger the authentication dialogue:
-
-```php
-$config['rest_valid_logins'] = ['username' => 'password', 'other_person' => 'secure123'];
-```
-
-Enabling digest auth is similarly easy. Configure your desired logins in the config file like above, and set `$config['rest_auth']` to `'digest'`. The class will automatically send out the headers to enable digest auth.
-
-If you're tying this library into an AJAX endpoint where clients authenticate using PHP sessions then you may not like either of the digest nor basic authentication methods. In that case, you can tell the REST Library what PHP session variable to check for. If the variable exists, then the user is authorized. It will be up to your application to set that variable. You can define the variable in ``$config['auth_source']``. Then tell the library to use a php session variable by setting ``$config['rest_auth']`` to ``session``.
-
-All three methods of authentication can be secured further by using an IP white-list. If you enable `$config['rest_ip_whitelist_enabled']` in your config file, you can then set a list of allowed IPs.
-
-Any client connecting to your API will be checked against the white-listed IP array. If they're on the list, they'll be allowed access. If not, sorry, no can do hombre. The whitelist is a comma-separated string:
-
-```php
-$config['rest_ip_whitelist'] = '123.456.789.0, 987.654.32.1';
-```
-
-Your localhost IPs (`127.0.0.1` and `0.0.0.0`) are allowed by default.
-
-## API Keys
-
-In addition to the authentication methods above, the `REST_Controller` class also supports the use of API keys. Enabling API keys is easy. Turn it on in your **config/rest.php** file:
+2. Extend the `Format` class (can be created as a CodeIgniter library in `libraries/Format.php`).
+Following is an example to add support for PDF output
```php
-$config['rest_enable_keys'] = TRUE;
-```
-
-You'll need to create a new database table to store and access the keys. `REST_Controller` will automatically assume you have a table that looks like this:
-
-```sql
-CREATE TABLE `keys` (
- `id` INT(11) NOT NULL AUTO_INCREMENT,
- `key` VARCHAR(40) NOT NULL,
- `level` INT(2) NOT NULL,
- `ignore_limits` TINYINT(1) NOT NULL DEFAULT '0',
- `date_created` INT(11) NOT NULL,
- PRIMARY KEY (`id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-```
-
-The class will look for an HTTP header with the API key on each request. An invalid or missing API key will result in an `HTTP 403 Forbidden`.
+_data;
+ }
+
+ if (is_array($data) || substr($data, 0, 4) != '%PDF') {
+ $html = $this->to_html($data);
+
+ // Use your PDF lib of choice. For example mpdf
+ $mpdf = new \Mpdf\Mpdf();
+ $mpdf->WriteHTML($html);
+ return $mpdf->Output('', 'S');
+ }
+
+ return $data;
+ }
+}
```
-Also you can refer to **config/config.php.sample**
-
-## Other Documentation / Tutorials
-
-* [NetTuts: Working with RESTful Services in CodeIgniter](http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/)
-
-## Contributions
-
-This project was originally written by Phil Sturgeon, however his involvement has shifted
-as he is no longer using it. As of 2013/11/20 further development and support will be done by Chris Kacerguis.
-
-Pull Requests are the best way to fix bugs or add features. I know loads of you use this, so please
-contribute if you have improvements to be made and I'll keep releasing versions over time.
-
-[](https://raw.githubusercontent.com/chriskacerguis/codeigniter-restserver/master/LICENSE)
diff --git a/application/config/config.php.sample b/application/config/config.php.sample
deleted file mode 100644
index 77411ce1..00000000
--- a/application/config/config.php.sample
+++ /dev/null
@@ -1,482 +0,0 @@
-]+$/i
-|
-| DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!!
-|
-| Note: This option is ignored for CLI requests.
-|
-*/
-$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';
-
-/*
-|--------------------------------------------------------------------------
-| 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.
-|
-*/
-$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.
-|
-*/
-$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.
-|
-*/
-$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/user_guide/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_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_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)
-|
-| 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;
-
-/*
-|--------------------------------------------------------------------------
-| 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';
-
-/*
-|--------------------------------------------------------------------------
-| 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/application/config/hooks.php b/application/config/hooks.php
deleted file mode 100644
index 7268904b..00000000
--- a/application/config/hooks.php
+++ /dev/null
@@ -1,21 +0,0 @@
- 'ProfilerEnabler',
- 'function' => 'enableProfiler',
- 'filename' => 'hooks.profiler.php',
- 'filepath' => 'hooks',
- 'params' => array()
-);
\ No newline at end of file
diff --git a/application/config/ldap.php b/application/config/ldap.php
deleted file mode 100644
index e4165550..00000000
--- a/application/config/ldap.php
+++ /dev/null
@@ -1,15 +0,0 @@
- my_controller/index
-| my-controller/my-method -> my_controller/my_method
-*/
-$route['default_controller'] = 'welcome';
-$route['404_override'] = '';
-$route['translate_uri_dashes'] = TRUE;
-
-/*
-| -------------------------------------------------------------------------
-| Sample REST API Routes
-| -------------------------------------------------------------------------
-*/
-$route['api/example/users/(:num)'] = 'api/example/users/id/$1'; // Example 4
-$route['api/example/users/(:num)(\.)([a-zA-Z0-9_-]+)(.*)'] = 'api/example/users/id/$1/format/$3$4'; // Example 8
diff --git a/application/controllers/Rest_server.php b/application/controllers/Rest_server.php
deleted file mode 100644
index 5d44f921..00000000
--- a/application/controllers/Rest_server.php
+++ /dev/null
@@ -1,13 +0,0 @@
-load->helper('url');
-
- $this->load->view('rest_server');
- }
-}
diff --git a/application/controllers/Welcome.php b/application/controllers/Welcome.php
deleted file mode 100644
index 59818c7f..00000000
--- a/application/controllers/Welcome.php
+++ /dev/null
@@ -1,27 +0,0 @@
-
- * @see https://codeigniter.com/user_guide/general/urls.html
- */
- public function index()
- {
- $this->load->helper('url');
-
- $this->load->view('welcome_message');
- }
-}
diff --git a/application/controllers/api/Example.php b/application/controllers/api/Example.php
deleted file mode 100644
index eb2f9069..00000000
--- a/application/controllers/api/Example.php
+++ /dev/null
@@ -1,138 +0,0 @@
-methods['users_get']['limit'] = 500; // 500 requests per hour per user/key
- $this->methods['users_post']['limit'] = 100; // 100 requests per hour per user/key
- $this->methods['users_delete']['limit'] = 50; // 50 requests per hour per user/key
- }
-
- public function users_get()
- {
- // Users from a data store e.g. database
- $users = [
- ['id' => 1, 'name' => 'John', 'email' => 'john@example.com', 'fact' => 'Loves coding'],
- ['id' => 2, 'name' => 'Jim', 'email' => 'jim@example.com', 'fact' => 'Developed on CodeIgniter'],
- ['id' => 3, 'name' => 'Jane', 'email' => 'jane@example.com', 'fact' => 'Lives in the USA', ['hobbies' => ['guitar', 'cycling']]],
- ];
-
- $id = $this->get('id');
-
- // If the id parameter doesn't exist return all the users
-
- if ($id === NULL)
- {
- // Check if the users data store contains users (in case the database result returns NULL)
- if ($users)
- {
- // Set the response and exit
- $this->response($users, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
- }
- else
- {
- // Set the response and exit
- $this->response([
- 'status' => FALSE,
- 'message' => 'No users were found'
- ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code
- }
- }
-
- // Find and return a single record for a particular user.
-
- $id = (int) $id;
-
- // Validate the id.
- if ($id <= 0)
- {
- // Invalid id, set the response and exit.
- $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
- }
-
- // Get the user from the array, using the id as key for retrieval.
- // Usually a model is to be used for this.
-
- $user = NULL;
-
- if (!empty($users))
- {
- foreach ($users as $key => $value)
- {
- if (isset($value['id']) && $value['id'] === $id)
- {
- $user = $value;
- }
- }
- }
-
- if (!empty($user))
- {
- $this->set_response($user, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
- }
- else
- {
- $this->set_response([
- 'status' => FALSE,
- 'message' => 'User could not be found'
- ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code
- }
- }
-
- public function users_post()
- {
- // $this->some_model->update_user( ... );
- $message = [
- 'id' => 100, // Automatically generated by the model
- 'name' => $this->post('name'),
- 'email' => $this->post('email'),
- 'message' => 'Added a resource'
- ];
-
- $this->set_response($message, REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
- }
-
- public function users_delete()
- {
- $id = (int) $this->get('id');
-
- // Validate the id.
- if ($id <= 0)
- {
- // Set the response and exit
- $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
- }
-
- // $this->some_model->delete_something($id);
- $message = [
- 'id' => $id,
- 'message' => 'Deleted the resource'
- ];
-
- $this->set_response($message, REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code
- }
-
-}
diff --git a/application/controllers/api/Key.php b/application/controllers/api/Key.php
deleted file mode 100644
index 547334b6..00000000
--- a/application/controllers/api/Key.php
+++ /dev/null
@@ -1,273 +0,0 @@
- ['level' => 10, 'limit' => 10],
- 'index_delete' => ['level' => 10],
- 'level_post' => ['level' => 10],
- 'regenerate_post' => ['level' => 10],
- ];
-
- /**
- * Insert a key into the database
- *
- * @access public
- * @return void
- */
- public function index_put()
- {
- // Build a new key
- $key = $this->_generate_key();
-
- // If no key level provided, provide a generic key
- $level = $this->put('level') ? $this->put('level') : 1;
- $ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1;
-
- // Insert the new key
- if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits]))
- {
- $this->response([
- 'status' => TRUE,
- 'key' => $key
- ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
- }
- else
- {
- $this->response([
- 'status' => FALSE,
- 'message' => 'Could not save the key'
- ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
- }
- }
-
- /**
- * Remove a key from the database to stop it working
- *
- * @access public
- * @return void
- */
- public function index_delete()
- {
- $key = $this->delete('key');
-
- // Does this key exist?
- if (!$this->_key_exists($key))
- {
- // It doesn't appear the key exists
- $this->response([
- 'status' => FALSE,
- 'message' => 'Invalid API key'
- ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
- }
-
- // Destroy it
- $this->_delete_key($key);
-
- // Respond that the key was destroyed
- $this->response([
- 'status' => TRUE,
- 'message' => 'API key was deleted'
- ], REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code
- }
-
- /**
- * Change the level
- *
- * @access public
- * @return void
- */
- public function level_post()
- {
- $key = $this->post('key');
- $new_level = $this->post('level');
-
- // Does this key exist?
- if (!$this->_key_exists($key))
- {
- // It doesn't appear the key exists
- $this->response([
- 'status' => FALSE,
- 'message' => 'Invalid API key'
- ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
- }
-
- // Update the key level
- if ($this->_update_key($key, ['level' => $new_level]))
- {
- $this->response([
- 'status' => TRUE,
- 'message' => 'API key was updated'
- ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
- }
- else
- {
- $this->response([
- 'status' => FALSE,
- 'message' => 'Could not update the key level'
- ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
- }
- }
-
- /**
- * Suspend a key
- *
- * @access public
- * @return void
- */
- public function suspend_post()
- {
- $key = $this->post('key');
-
- // Does this key exist?
- if (!$this->_key_exists($key))
- {
- // It doesn't appear the key exists
- $this->response([
- 'status' => FALSE,
- 'message' => 'Invalid API key'
- ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
- }
-
- // Update the key level
- if ($this->_update_key($key, ['level' => 0]))
- {
- $this->response([
- 'status' => TRUE,
- 'message' => 'Key was suspended'
- ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
- }
- else
- {
- $this->response([
- 'status' => FALSE,
- 'message' => 'Could not suspend the user'
- ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
- }
- }
-
- /**
- * Regenerate a key
- *
- * @access public
- * @return void
- */
- public function regenerate_post()
- {
- $old_key = $this->post('key');
- $key_details = $this->_get_key($old_key);
-
- // Does this key exist?
- if (!$key_details)
- {
- // It doesn't appear the key exists
- $this->response([
- 'status' => FALSE,
- 'message' => 'Invalid API key'
- ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
- }
-
- // Build a new key
- $new_key = $this->_generate_key();
-
- // Insert the new key
- if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits]))
- {
- // Suspend old key
- $this->_update_key($old_key, ['level' => 0]);
-
- $this->response([
- 'status' => TRUE,
- 'key' => $new_key
- ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
- }
- else
- {
- $this->response([
- 'status' => FALSE,
- 'message' => 'Could not save the key'
- ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
- }
- }
-
- /* Helper Methods */
-
- private function _generate_key()
- {
- do
- {
- // Generate a random salt
- $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
-
- // If an error occurred, then fall back to the previous method
- if ($salt === FALSE)
- {
- $salt = hash('sha256', time() . mt_rand());
- }
-
- $new_key = substr($salt, 0, config_item('rest_key_length'));
- }
- while ($this->_key_exists($new_key));
-
- return $new_key;
- }
-
- /* Private Data Methods */
-
- private function _get_key($key)
- {
- return $this->rest->db
- ->where(config_item('rest_key_column'), $key)
- ->get(config_item('rest_keys_table'))
- ->row();
- }
-
- private function _key_exists($key)
- {
- return $this->rest->db
- ->where(config_item('rest_key_column'), $key)
- ->count_all_results(config_item('rest_keys_table')) > 0;
- }
-
- private function _insert_key($key, $data)
- {
- $data[config_item('rest_key_column')] = $key;
- $data['date_created'] = function_exists('now') ? now() : time();
-
- return $this->rest->db
- ->set($data)
- ->insert(config_item('rest_keys_table'));
- }
-
- private function _update_key($key, $data)
- {
- return $this->rest->db
- ->where(config_item('rest_key_column'), $key)
- ->update(config_item('rest_keys_table'), $data);
- }
-
- private function _delete_key($key)
- {
- return $this->rest->db
- ->where(config_item('rest_key_column'), $key)
- ->delete(config_item('rest_keys_table'));
- }
-
-}
diff --git a/application/helpers/db_helper.php b/application/helpers/db_helper.php
deleted file mode 100755
index 9a007a46..00000000
--- a/application/helpers/db_helper.php
+++ /dev/null
@@ -1,69 +0,0 @@
-
- */
-defined('BASEPATH') OR exit('No direct script access allowed');
-
-if ( ! function_exists('add_foreign_key'))
-{
- /**
- * @param string $table Table name
- * @param string $foreign_key Collumn name having the Foreign Key
- * @param string $references Table and column reference. Ex: users(id)
- * @param string $on_delete RESTRICT, NO ACTION, CASCADE, SET NULL, SET DEFAULT
- * @param string $on_update RESTRICT, NO ACTION, CASCADE, SET NULL, SET DEFAULT
- *
- * @return string SQL command
- */
- function add_foreign_key($table, $foreign_key, $references, $on_delete = 'RESTRICT', $on_update = 'RESTRICT')
- {
- $references = explode('(', str_replace(')', '', str_replace('`', '', $references)));
-
- return "ALTER TABLE `{$table}` ADD CONSTRAINT `{$table}_{$foreign_key}_fk` FOREIGN KEY (`{$foreign_key}`) REFERENCES `{$references[0]}`(`{$references[1]}`) ON DELETE {$on_delete} ON UPDATE {$on_update}";
- }
-}
-
-if ( ! function_exists('drop_foreign_key'))
-{
- /**
- * @param string $table Table name
- * @param string $foreign_key Collumn name having the Foreign Key
- *
- * @return string SQL command
- */
- function drop_foreign_key($table, $foreign_key)
- {
- return "ALTER TABLE `{$table}` DROP FOREIGN KEY `{$table}_{$foreign_key}_fk`";
- }
-}
-
-if ( ! function_exists('add_trigger'))
-{
- /**
- * @param string $trigger_name Trigger name
- * @param string $table Table name
- * @param string $statement Command to run
- * @param string $time BEFORE or AFTER
- * @param string $event INSERT, UPDATE or DELETE
- * @param string $type FOR EACH ROW [FOLLOWS|PRECEDES]
- *
- * @return string SQL Command
- */
- function add_trigger($trigger_name, $table, $statement, $time = 'BEFORE', $event = 'INSERT', $type = 'FOR EACH ROW')
- {
- return 'DELIMITER ;;' . PHP_EOL . "CREATE TRIGGER `{$trigger_name}` {$time} {$event} ON `{$table}` {$type}" . PHP_EOL . 'BEGIN' . PHP_EOL . $statement . PHP_EOL . 'END;' . PHP_EOL . 'DELIMITER ;;';
- }
-}
-
-if ( ! function_exists('drop_trigger'))
-{
- /**
- * @param string $trigger_name Trigger name
- *
- * @return string SQL Command
- */
- function drop_trigger($trigger_name)
- {
- return "DROP TRIGGER {$trigger_name};";
- }
-}
diff --git a/application/hooks/hooks.profiler.php b/application/hooks/hooks.profiler.php
deleted file mode 100644
index c376fdb8..00000000
--- a/application/hooks/hooks.profiler.php
+++ /dev/null
@@ -1,18 +0,0 @@
-output->enable_profiler( config_item('enable_profiling') );
- }
-}
-?>
diff --git a/application/language/dutch/rest_controller_lang.php b/application/language/dutch/rest_controller_lang.php
deleted file mode 100644
index 182ca61c..00000000
--- a/application/language/dutch/rest_controller_lang.php
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
You have probably clicked on a link that is outdated and points to a page that does not exist any more or you have made an typing error in the address.
-
To continue please try to find requested page in the menu, or use search field on the top.
Requests are not made to methods directly, the request will be for
-an "object". This simply maps the object and method to the correct
-Controller method
-
-
-
-
Requests are not made to methods directly, the request will be for
-an "object". This simply maps the object and method to the correct
-Controller method
Takes mixed data and optionally a status code, then creates the response
-within the buffers of the Output class. The response is sent to the client
-lately by the framework, after the current controller's method termination.
-All the hooks after the controller's method termination are executable
-
-
-
-
Takes mixed data and optionally a status code, then creates the response
-within the buffers of the Output class. The response is sent to the client
-lately by the framework, after the current controller's method termination.
-All the hooks after the controller's method termination are executable
Gets the default format from the configuration. Fallbacks to 'json'
-if the corresponding configuration option $config['rest_default_format']
-is missing or is empty
-
-
-
-
Gets the default format from the configuration. Fallbacks to 'json'
-if the corresponding configuration option $config['rest_default_format']
-is missing or is empty
Enable XSS flag
-Determines whether the XSS filter is always active when
-GET, OPTIONS, HEAD, POST, PUT, DELETE and PATCH data is encountered
-Set automatically based on config setting
-
-
-
-
Enable XSS flag
-Determines whether the XSS filter is always active when
-GET, OPTIONS, HEAD, POST, PUT, DELETE and PATCH data is encountered
-Set automatically based on config setting
Maps to the following URL http://example.com/index.php/welcome
-- or - http://example.com/index.php/welcome/index
-- or -
-Since this controller is set as the default controller in
-config/routes.php, it's displayed at http://example.com/
-
-
So any other public methods not prefixed with an underscore will
-map to /index.php/welcome/
a",n=d.getElementsByTagName("*")||[],r=d.getElementsByTagName("a")[0],!r||!r.style||!n.length)return t;s=a.createElement("select"),u=s.appendChild(a.createElement("option")),o=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t.getSetAttribute="t"!==d.className,t.leadingWhitespace=3===d.firstChild.nodeType,t.tbody=!d.getElementsByTagName("tbody").length,t.htmlSerialize=!!d.getElementsByTagName("link").length,t.style=/top/.test(r.getAttribute("style")),t.hrefNormalized="/a"===r.getAttribute("href"),t.opacity=/^0.5/.test(r.style.opacity),t.cssFloat=!!r.style.cssFloat,t.checkOn=!!o.value,t.optSelected=u.selected,t.enctype=!!a.createElement("form").enctype,t.html5Clone="<:nav>"!==a.createElement("nav").cloneNode(!0).outerHTML,t.inlineBlockNeedsLayout=!1,t.shrinkWrapBlocks=!1,t.pixelPosition=!1,t.deleteExpando=!0,t.noCloneEvent=!0,t.reliableMarginRight=!0,t.boxSizingReliable=!0,o.checked=!0,t.noCloneChecked=o.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!u.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}o=a.createElement("input"),o.setAttribute("value",""),t.input=""===o.getAttribute("value"),o.value="t",o.setAttribute("type","radio"),t.radioValue="t"===o.value,o.setAttribute("checked","t"),o.setAttribute("name","t"),l=a.createDocumentFragment(),l.appendChild(o),t.appendChecked=o.checked,t.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip;for(f in x(t))break;return t.ownLast="0"!==f,x(function(){var n,r,o,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",l=a.getElementsByTagName("body")[0];l&&(n=a.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",l.appendChild(n).appendChild(d),d.innerHTML="
1: <?php
- 2: defined('BASEPATH') ORexit('No direct script access allowed');
- 3:
- 4: class Welcome extends CI_Controller {
- 5:
- 6: /**
- 7: * Index Page for this controller.
- 8: *
- 9: * Maps to the following URL
-10: * http://example.com/index.php/welcome
-11: * - or -
-12: * http://example.com/index.php/welcome/index
-13: * - or -
-14: * Since this controller is set as the default controller in
-15: * config/routes.php, it's displayed at http://example.com/
-16: *
-17: * So any other public methods not prefixed with an underscore will
-18: * map to /index.php/welcome/<method_name>
-19: * @see https://codeigniter.com/user_guide/general/urls.html
-20: */
-21: publicfunction index()
-22: {
-23: $this->load->helper('url');
-24:
-25: $this->load->view('welcome_message');
-26: }
-27: }
-28:
-
-
-
-
-
-
-
-
diff --git a/application/config/index.html b/language/bulgarian/index.html
similarity index 100%
rename from application/config/index.html
rename to language/bulgarian/index.html
diff --git a/application/language/bulgarian/rest_controller_lang.php b/language/bulgarian/rest_controller_lang.php
similarity index 100%
rename from application/language/bulgarian/rest_controller_lang.php
rename to language/bulgarian/rest_controller_lang.php
diff --git a/application/controllers/api/index.html b/language/dutch/index.html
similarity index 100%
rename from application/controllers/api/index.html
rename to language/dutch/index.html
diff --git a/language/dutch/rest_controller_lang.php b/language/dutch/rest_controller_lang.php
new file mode 100644
index 00000000..45fd9c25
--- /dev/null
+++ b/language/dutch/rest_controller_lang.php
@@ -0,0 +1,16 @@
+_CI = &get_instance();
@@ -89,14 +93,10 @@ public function __construct($data = NULL, $from_type = NULL)
$this->_CI->load->helper('inflector');
// If the provided data is already formatted we should probably convert it to an array
- if ($from_type !== NULL)
- {
- if (method_exists($this, '_from_'.$from_type))
- {
+ if ($from_type !== null) {
+ if (method_exists($this, '_from_'.$from_type)) {
$data = call_user_func([$this, '_from_'.$from_type], $data);
- }
- else
- {
+ } else {
throw new Exception('Format class does not support conversion from "'.$from_type.'".');
}
}
@@ -107,14 +107,14 @@ public function __construct($data = NULL, $from_type = NULL)
/**
* Create an instance of the format class
- * e.g: echo $this->format->factory(['foo' => 'bar'])->to_csv();
+ * e.g: echo $this->format->factory(['foo' => 'bar'])->to_csv();.
*
- * @param mixed $data Data to convert/parse
+ * @param mixed $data Data to convert/parse
* @param string $from_type Type to convert from e.g. json, csv, html
*
* @return object Instance of the format class
*/
- public function factory($data, $from_type = NULL)
+ public static function factory($data, $from_type = null)
{
// $class = __CLASS__;
// return new $class();
@@ -125,36 +125,31 @@ public function factory($data, $from_type = NULL)
// FORMATTING OUTPUT ---------------------------------------------------------
/**
- * Format data as an array
+ * Format data as an array.
+ *
+ * @param mixed|null $data Optional data to pass, so as to override the data passed
+ * to the constructor
*
- * @param mixed|NULL $data Optional data to pass, so as to override the data passed
- * to the constructor
* @return array Data parsed as an array; otherwise, an empty array
*/
- public function to_array($data = NULL)
+ public function to_array($data = null)
{
// If no data is passed as a parameter, then use the data passed
// via the constructor
- if ($data === NULL && func_num_args() === 0)
- {
+ if ($data === null && func_num_args() === 0) {
$data = $this->_data;
}
// Cast as an array if not already
- if (is_array($data) === FALSE)
- {
+ if (is_array($data) === false) {
$data = (array) $data;
}
$array = [];
- foreach ((array) $data as $key => $value)
- {
- if (is_object($value) === TRUE || is_array($value) === TRUE)
- {
+ foreach ((array) $data as $key => $value) {
+ if (is_object($value) === true || is_array($value) === true) {
$array[$key] = $this->to_array($value);
- }
- else
- {
+ } else {
$array[$key] = $value;
}
}
@@ -163,44 +158,38 @@ public function to_array($data = NULL)
}
/**
- * Format data as XML
+ * Format data as XML.
+ *
+ * @param mixed|null $data Optional data to pass, so as to override the data passed
+ * to the constructor
+ * @param null $structure
+ * @param string $basenode
*
- * @param mixed|NULL $data Optional data to pass, so as to override the data passed
- * to the constructor
- * @param NULL $structure
- * @param string $basenode
* @return mixed
*/
- public function to_xml($data = NULL, $structure = NULL, $basenode = 'xml')
+ public function to_xml($data = null, $structure = null, $basenode = 'xml')
{
- if ($data === NULL && func_num_args() === 0)
- {
+ if ($data === null && func_num_args() === 0) {
$data = $this->_data;
}
- if ($structure === NULL)
- {
+ if ($structure === null) {
$structure = simplexml_load_string("<$basenode />");
}
// Force it to be something useful
- if (is_array($data) === FALSE && is_object($data) === FALSE)
- {
+ if (is_array($data) === false && is_object($data) === false) {
$data = (array) $data;
}
- foreach ($data as $key => $value)
- {
-
+ foreach ($data as $key => $value) {
//change false/true to 0/1
- if (is_bool($value))
- {
+ if (is_bool($value)) {
$value = (int) $value;
}
// no numeric keys in our xml please!
- if (is_numeric($key))
- {
+ if (is_numeric($key)) {
// make string key...
$key = (singular($basenode) != $basenode) ? singular($basenode) : 'item';
}
@@ -208,31 +197,25 @@ public function to_xml($data = NULL, $structure = NULL, $basenode = 'xml')
// replace anything not alpha numeric
$key = preg_replace('/[^a-z_\-0-9]/i', '', $key);
- if ($key === '_attributes' && (is_array($value) || is_object($value)))
- {
+ if ($key === '_attributes' && (is_array($value) || is_object($value))) {
$attributes = $value;
- if (is_object($attributes))
- {
+ if (is_object($attributes)) {
$attributes = get_object_vars($attributes);
}
- foreach ($attributes as $attribute_name => $attribute_value)
- {
+ foreach ($attributes as $attribute_name => $attribute_value) {
$structure->addAttribute($attribute_name, $attribute_value);
}
}
// if there is another array found recursively call this function
- elseif (is_array($value) || is_object($value))
- {
+ elseif (is_array($value) || is_object($value)) {
$node = $structure->addChild($key);
// recursive call.
$this->to_xml($value, $node, $key);
- }
- else
- {
+ } else {
// add single node.
- $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
+ $value = htmlspecialchars(html_entity_decode($value ?? '', ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
$structure->addChild($key, $value);
}
@@ -242,35 +225,31 @@ public function to_xml($data = NULL, $structure = NULL, $basenode = 'xml')
}
/**
- * Format data as HTML
+ * Format data as HTML.
+ *
+ * @param mixed|null $data Optional data to pass, so as to override the data passed
+ * to the constructor
*
- * @param mixed|NULL $data Optional data to pass, so as to override the data passed
- * to the constructor
* @return mixed
*/
- public function to_html($data = NULL)
+ public function to_html($data = null)
{
// If no data is passed as a parameter, then use the data passed
// via the constructor
- if ($data === NULL && func_num_args() === 0)
- {
+ if ($data === null && func_num_args() === 0) {
$data = $this->_data;
}
// Cast as an array if not already
- if (is_array($data) === FALSE)
- {
+ if (is_array($data) === false) {
$data = (array) $data;
}
// Check if it's a multi-dimensional array
- if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE))
- {
+ if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) {
// Multi-dimensional array
$headings = array_keys($data[0]);
- }
- else
- {
+ } else {
// Single array
$headings = array_keys($data);
$data = [$data];
@@ -281,8 +260,7 @@ public function to_html($data = NULL)
$this->_CI->table->set_heading($headings);
- foreach ($data as $row)
- {
+ foreach ($data as $row) {
// Suppressing the "array to string conversion" notice
// Keep the "evil" @ here
$row = @array_map('strval', $row);
@@ -295,56 +273,50 @@ public function to_html($data = NULL)
/**
* @link http://www.metashock.de/2014/02/create-csv-file-in-memory-php/
- * @param mixed|NULL $data Optional data to pass, so as to override the data passed
- * to the constructor
- * @param string $delimiter The optional delimiter parameter sets the field
- * delimiter (one character only). NULL will use the default value (,)
- * @param string $enclosure The optional enclosure parameter sets the field
- * enclosure (one character only). NULL will use the default value (")
+ *
+ * @param mixed|null $data Optional data to pass, so as to override the data passed
+ * to the constructor
+ * @param string $delimiter The optional delimiter parameter sets the field
+ * delimiter (one character only). NULL will use the default value (,)
+ * @param string $enclosure The optional enclosure parameter sets the field
+ * enclosure (one character only). NULL will use the default value (")
+ *
* @return string A csv string
*/
- public function to_csv($data = NULL, $delimiter = ',', $enclosure = '"')
+ public function to_csv($data = null, $delimiter = ',', $enclosure = '"')
{
// Use a threshold of 1 MB (1024 * 1024)
$handle = fopen('php://temp/maxmemory:1048576', 'w');
- if ($handle === FALSE)
- {
- return NULL;
+ if ($handle === false) {
+ return;
}
// If no data is passed as a parameter, then use the data passed
// via the constructor
- if ($data === NULL && func_num_args() === 0)
- {
+ if ($data === null && func_num_args() === 0) {
$data = $this->_data;
}
// If NULL, then set as the default delimiter
- if ($delimiter === NULL)
- {
+ if ($delimiter === null) {
$delimiter = ',';
}
// If NULL, then set as the default enclosure
- if ($enclosure === NULL)
- {
+ if ($enclosure === null) {
$enclosure = '"';
}
// Cast as an array if not already
- if (is_array($data) === FALSE)
- {
+ if (is_array($data) === false) {
$data = (array) $data;
}
// Check if it's a multi-dimensional array
- if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE))
- {
+ if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) {
// Multi-dimensional array
$headings = array_keys($data[0]);
- }
- else
- {
+ } else {
// Single array
$headings = array_keys($data);
$data = [$data];
@@ -353,18 +325,16 @@ public function to_csv($data = NULL, $delimiter = ',', $enclosure = '"')
// Apply the headings
fputcsv($handle, $headings, $delimiter, $enclosure);
- foreach ($data as $record)
- {
+ foreach ($data as $record) {
// If the record is not an array, then break. This is because the 2nd param of
// fputcsv() should be an array
- if (is_array($record) === FALSE)
- {
+ if (is_array($record) === false) {
break;
}
// Suppressing the "array to string conversion" notice.
// Keep the "evil" @ here.
- $record = @ array_map('strval', $record);
+ $record = @array_map('strval', $record);
// Returns the length of the string written or FALSE
fputcsv($handle, $record, $delimiter, $enclosure);
@@ -386,32 +356,30 @@ public function to_csv($data = NULL, $delimiter = ',', $enclosure = '"')
}
/**
- * Encode data as json
+ * Encode data as json.
+ *
+ * @param mixed|null $data Optional data to pass, so as to override the data passed
+ * to the constructor
*
- * @param mixed|NULL $data Optional data to pass, so as to override the data passed
- * to the constructor
* @return string Json representation of a value
*/
- public function to_json($data = NULL)
+ public function to_json($data = null)
{
// If no data is passed as a parameter, then use the data passed
// via the constructor
- if ($data === NULL && func_num_args() === 0)
- {
+ if ($data === null && func_num_args() === 0) {
$data = $this->_data;
}
// Get the callback parameter (if set)
$callback = $this->_CI->input->get('callback');
- if (empty($callback) === TRUE)
- {
+ if (empty($callback) === true) {
return json_encode($data, JSON_UNESCAPED_UNICODE);
}
// We only honour a jsonp callback which are valid javascript identifiers
- elseif (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback))
- {
+ elseif (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback)) {
// Return the data as encoded json with a callback
return $callback.'('.json_encode($data, JSON_UNESCAPED_UNICODE).');';
}
@@ -424,18 +392,18 @@ public function to_json($data = NULL)
}
/**
- * Encode data as a serialized array
+ * Encode data as a serialized array.
+ *
+ * @param mixed|null $data Optional data to pass, so as to override the data passed
+ * to the constructor
*
- * @param mixed|NULL $data Optional data to pass, so as to override the data passed
- * to the constructor
* @return string Serialized data
*/
- public function to_serialized($data = NULL)
+ public function to_serialized($data = null)
{
// If no data is passed as a parameter, then use the data passed
// via the constructor
- if ($data === NULL && func_num_args() === 0)
- {
+ if ($data === null && func_num_args() === 0) {
$data = $this->_data;
}
@@ -443,28 +411,29 @@ public function to_serialized($data = NULL)
}
/**
- * Format data using a PHP structure
+ * Format data using a PHP structure.
+ *
+ * @param mixed|null $data Optional data to pass, so as to override the data passed
+ * to the constructor
*
- * @param mixed|NULL $data Optional data to pass, so as to override the data passed
- * to the constructor
* @return mixed String representation of a variable
*/
- public function to_php($data = NULL)
+ public function to_php($data = null)
{
// If no data is passed as a parameter, then use the data passed
// via the constructor
- if ($data === NULL && func_num_args() === 0)
- {
+ if ($data === null && func_num_args() === 0) {
$data = $this->_data;
}
- return var_export($data, TRUE);
+ return var_export($data, true);
}
// INTERNAL FUNCTIONS
/**
* @param string $data XML string
+ *
* @return array XML element object; otherwise, empty array
*/
protected function _from_xml($data)
@@ -473,25 +442,24 @@ protected function _from_xml($data)
}
/**
- * @param string $data CSV string
+ * @param string $data CSV string
* @param string $delimiter The optional delimiter parameter sets the field
- * delimiter (one character only). NULL will use the default value (,)
+ * delimiter (one character only). NULL will use the default value (,)
* @param string $enclosure The optional enclosure parameter sets the field
- * enclosure (one character only). NULL will use the default value (")
+ * enclosure (one character only). NULL will use the default value (")
+ *
* @return array A multi-dimensional array with the outer array being the number of rows
- * and the inner arrays the individual fields
+ * and the inner arrays the individual fields
*/
protected function _from_csv($data, $delimiter = ',', $enclosure = '"')
{
// If NULL, then set as the default delimiter
- if ($delimiter === NULL)
- {
+ if ($delimiter === null) {
$delimiter = ',';
}
// If NULL, then set as the default enclosure
- if ($enclosure === NULL)
- {
+ if ($enclosure === null) {
$enclosure = '"';
}
@@ -500,6 +468,7 @@ protected function _from_csv($data, $delimiter = ',', $enclosure = '"')
/**
* @param string $data Encoded json string
+ *
* @return mixed Decoded json string with leading and trailing whitespace removed
*/
protected function _from_json($data)
@@ -509,6 +478,7 @@ protected function _from_json($data)
/**
* @param string $data Data to unserialize
+ *
* @return mixed Unserialized data
*/
protected function _from_serialize($data)
@@ -518,6 +488,7 @@ protected function _from_serialize($data)
/**
* @param string $data Data to trim leading and trailing whitespace
+ *
* @return string Data with leading and trailing whitespace removed
*/
protected function _from_php($data)
diff --git a/application/libraries/REST_Controller.php b/src/RestController.php
similarity index 57%
rename from application/libraries/REST_Controller.php
rename to src/RestController.php
index b6055c6b..7f292a98 100644
--- a/application/libraries/REST_Controller.php
+++ b/src/RestController.php
@@ -1,171 +1,46 @@
'application/json',
- 'array' => 'application/json',
- 'csv' => 'application/csv',
- 'html' => 'text/html',
- 'jsonp' => 'application/javascript',
- 'php' => 'text/plain',
+ 'json' => 'application/json',
+ 'array' => 'application/json',
+ 'csv' => 'application/csv',
+ 'html' => 'text/html',
+ 'jsonp' => 'application/javascript',
+ 'php' => 'text/plain',
'serialized' => 'application/vnd.php.serialized',
- 'xml' => 'application/xml'
+ 'xml' => 'application/xml',
];
/**
- * Information about the current API user
+ * Information about the current API user.
*
* @var object
*/
protected $_apiuser;
/**
- * Whether or not to perform a CORS check and apply CORS headers to the request
+ * Whether or not to perform a CORS check and apply CORS headers to the request.
*
* @var bool
*/
- protected $check_cors = NULL;
+ protected $check_cors = null;
/**
* Enable XSS flag
* Determines whether the XSS filter is always active when
* GET, OPTIONS, HEAD, POST, PUT, DELETE and PATCH data is encountered
- * Set automatically based on config setting
+ * Set automatically based on config setting.
*
* @var bool
*/
- protected $_enable_xss = FALSE;
+ protected $_enable_xss = false;
- private $is_valid_request = TRUE;
+ private $is_valid_request = true;
/**
- * HTTP status codes and their respective description
- * Note: Only the widely used HTTP status codes are used
+ * Common HTTP status codes and their respective description.
*
- * @var array
* @link http://www.restapitutorial.com/httpstatuscodes.html
*/
- protected $http_status_codes = [
- self::HTTP_OK => 'OK',
- self::HTTP_CREATED => 'CREATED',
- self::HTTP_NO_CONTENT => 'NO CONTENT',
- self::HTTP_NOT_MODIFIED => 'NOT MODIFIED',
- self::HTTP_BAD_REQUEST => 'BAD REQUEST',
- self::HTTP_UNAUTHORIZED => 'UNAUTHORIZED',
- self::HTTP_FORBIDDEN => 'FORBIDDEN',
- self::HTTP_NOT_FOUND => 'NOT FOUND',
- self::HTTP_METHOD_NOT_ALLOWED => 'METHOD NOT ALLOWED',
- self::HTTP_NOT_ACCEPTABLE => 'NOT ACCEPTABLE',
- self::HTTP_CONFLICT => 'CONFLICT',
- self::HTTP_INTERNAL_SERVER_ERROR => 'INTERNAL SERVER ERROR',
- self::HTTP_NOT_IMPLEMENTED => 'NOT IMPLEMENTED'
- ];
+ const HTTP_OK = 200;
+ const HTTP_CREATED = 201;
+ const HTTP_NOT_MODIFIED = 304;
+ const HTTP_BAD_REQUEST = 400;
+ const HTTP_UNAUTHORIZED = 401;
+ const HTTP_FORBIDDEN = 403;
+ const HTTP_NOT_FOUND = 404;
+ const HTTP_METHOD_NOT_ALLOWED = 405;
+ const HTTP_NOT_ACCEPTABLE = 406;
+ const HTTP_INTERNAL_ERROR = 500;
/**
* @var Format
*/
- private $format;
+ protected $format;
+
/**
* @var bool
*/
- private $auth_override;
+ protected $auth_override;
/**
- * Extend this function to apply additional checking early on in the process
+ * Extend this function to apply additional checking early on in the process.
*
- * @access protected
* @return void
*/
protected function early_checks()
@@ -381,61 +249,46 @@ protected function early_checks()
}
/**
- * Constructor for the REST API
+ * Constructor for the REST API.
*
- * @access public
* @param string $config Configuration filename minus the file extension
- * e.g: my_rest.php is passed as 'my_rest'
+ * e.g: my_rest.php is passed as 'my_rest'
*/
public function __construct($config = 'rest')
{
parent::__construct();
- $this->preflight_checks();
-
// Set the default value of global xss filtering. Same approach as CodeIgniter 3
- $this->_enable_xss = ($this->config->item('global_xss_filtering') === TRUE);
+ $this->_enable_xss = ($this->config->item('global_xss_filtering') === true);
// Don't try to parse template variables like {elapsed_time} and {memory_usage}
// when output is displayed for not damaging data accidentally
- $this->output->parse_exec_vars = FALSE;
-
- // Start the timer for how long the request takes
- $this->_start_rtime = microtime(TRUE);
+ $this->output->parse_exec_vars = false;
// Load the rest.php configuration file
$this->get_local_config($config);
- // At present the library is bundled with REST_Controller 2.5+, but will eventually be part of CodeIgniter (no citation)
- if(class_exists('Format'))
- {
- $this->format = new Format();
- }
- else
- {
- $this->load->library('Format', NULL, 'libraryFormat');
- $this->format = $this->libraryFormat;
+ // Log the loading time to the log table
+ if ($this->config->item('rest_enable_logging') === true) {
+ // Start the timer for how long the request takes
+ $this->_start_rtime = microtime(true);
}
-
// Determine supported output formats from configuration
$supported_formats = $this->config->item('rest_supported_formats');
// Validate the configuration setting output formats
- if (empty($supported_formats))
- {
+ if (empty($supported_formats)) {
$supported_formats = [];
}
- if ( ! is_array($supported_formats))
- {
+ if (!is_array($supported_formats)) {
$supported_formats = [$supported_formats];
}
// Add silently the default output format if it is missing
$default_format = $this->_get_default_output_format();
- if (!in_array($default_format, $supported_formats))
- {
+ if (!in_array($default_format, $supported_formats)) {
$supported_formats[] = $default_format;
}
@@ -444,13 +297,12 @@ public function __construct($config = 'rest')
// Get the language
$language = $this->config->item('rest_language');
- if ($language === NULL)
- {
+ if ($language === null) {
$language = 'english';
}
// Load the language file
- $this->lang->load('rest_controller', $language, FALSE, TRUE, __DIR__.'/../');
+ $this->lang->load('rest_controller', $language, false, true, __DIR__.'/../');
// Initialise the response, request and rest objects
$this->request = new stdClass();
@@ -458,8 +310,7 @@ public function __construct($config = 'rest')
$this->rest = new stdClass();
// Check to see if the current IP address is blacklisted
- if ($this->config->item('rest_ip_blacklist_enabled') === TRUE)
- {
+ if ($this->config->item('rest_ip_blacklist_enabled') === true) {
$this->_check_blacklist_auth();
}
@@ -471,14 +322,12 @@ public function __construct($config = 'rest')
// Check for CORS access request
$check_cors = $this->config->item('check_cors');
- if ($check_cors === TRUE)
- {
+ if ($check_cors === true) {
$this->_check_cors();
}
// Create an argument container if it doesn't exist e.g. _get_args
- if (isset($this->{'_'.$this->request->method.'_args'}) === FALSE)
- {
+ if (isset($this->{'_'.$this->request->method.'_args'}) === false) {
$this->{'_'.$this->request->method.'_args'} = [];
}
@@ -492,20 +341,25 @@ public function __construct($config = 'rest')
$this->request->format = $this->_detect_input_format();
// Not all methods have a body attached with them
- $this->request->body = NULL;
+ $this->request->body = null;
- $this->{'_parse_' . $this->request->method}();
+ $this->{'_parse_'.$this->request->method}();
// Fix parse method return arguments null
- if($this->{'_'.$this->request->method.'_args'} === null)
- {
+ if ($this->{'_'.$this->request->method.'_args'} === null) {
$this->{'_'.$this->request->method.'_args'} = [];
}
+ // Which format should the data be returned in?
+ $this->response->format = $this->_detect_output_format();
+
+ // Which language should the data be returned in?
+ $this->response->lang = $this->_detect_lang();
+
// Now we know all about our request, let's try and parse the body if it exists
- if ($this->request->format && $this->request->body)
- {
- $this->request->body = $this->format->factory($this->request->body, $this->request->format)->to_array();
+ if ($this->request->format && $this->request->body) {
+ $this->request->body = Format::factory($this->request->body, $this->request->format)->to_array();
+
// Assign payload arguments to proper method container
$this->{'_'.$this->request->method.'_args'} = $this->request->body;
}
@@ -525,24 +379,16 @@ public function __construct($config = 'rest')
$this->{'_'.$this->request->method.'_args'}
);
- // Which format should the data be returned in?
- $this->response->format = $this->_detect_output_format();
-
- // Which language should the data be returned in?
- $this->response->lang = $this->_detect_lang();
-
// Extend this function to apply additional checking early on in the process
$this->early_checks();
// Load DB if its enabled
- if ($this->config->item('rest_database_group') && ($this->config->item('rest_enable_keys') || $this->config->item('rest_enable_logging')))
- {
- $this->rest->db = $this->load->database($this->config->item('rest_database_group'), TRUE);
+ if ($this->config->item('rest_database_group') && ($this->config->item('rest_enable_keys') || $this->config->item('rest_enable_logging'))) {
+ $this->rest->db = $this->load->database($this->config->item('rest_database_group'), true);
}
// Use whatever database is in use (isset returns FALSE)
- elseif (property_exists($this, 'db'))
- {
+ elseif (property_exists($this, 'db')) {
$this->rest->db = $this->db;
}
@@ -552,29 +398,25 @@ public function __construct($config = 'rest')
// Checking for keys? GET TO WorK!
// Skip keys test for $config['auth_override_class_method']['class'['method'] = 'none'
- if ($this->config->item('rest_enable_keys') && $this->auth_override !== TRUE)
- {
+ if ($this->config->item('rest_enable_keys') && $this->auth_override !== true) {
$this->_allow = $this->_detect_api_key();
}
// Only allow ajax requests
- if ($this->input->is_ajax_request() === FALSE && $this->config->item('rest_ajax_only'))
- {
+ if ($this->input->is_ajax_request() === false && $this->config->item('rest_ajax_only')) {
// Display an error response
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ajax_only')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ajax_only'),
], self::HTTP_NOT_ACCEPTABLE);
}
// When there is no specific override for the current class/method, use the default auth value set in the config
- if ($this->auth_override === FALSE &&
- (! ($this->config->item('rest_enable_keys') && $this->_allow === TRUE) ||
- ($this->config->item('allow_auth_and_keys') === TRUE && $this->_allow === TRUE)))
- {
+ if ($this->auth_override === false &&
+ (!($this->config->item('rest_enable_keys') && $this->_allow === true) ||
+ ($this->config->item('allow_auth_and_keys') === true && $this->_allow === true))) {
$rest_auth = strtolower($this->config->item('rest_auth'));
- switch ($rest_auth)
- {
+ switch ($rest_auth) {
case 'basic':
$this->_prepare_basic_auth();
break;
@@ -585,94 +427,78 @@ public function __construct($config = 'rest')
$this->_check_php_session();
break;
}
- if ($this->config->item('rest_ip_whitelist_enabled') === TRUE)
- {
- $this->_check_whitelist_auth();
- }
}
}
/**
- * @param $config_file
+ * Does the auth stuff.
*/
- private function get_local_config($config_file)
+ private function do_auth($method = false)
{
- if(file_exists(__DIR__."/../config/".$config_file.".php"))
- {
- $config = array();
- include(__DIR__ . "/../config/" . $config_file . ".php");
-
- foreach($config AS $key => $value)
- {
- $this->config->set_item($key, $value);
- }
+ // If we don't want to do auth, then just return true
+ if ($method === false) {
+ return true;
}
- $this->load->config($config_file, FALSE, TRUE);
+ if (file_exists(__DIR__.'/auth/'.$method.'.php')) {
+ include __DIR__.'/auth/'.$method.'.php';
+ }
}
/**
- * De-constructor
- *
- * @author Chris Kacerguis
- * @access public
- * @return void
+ * @param $config_file
*/
- public function __destruct()
+ private function get_local_config($config_file)
{
- // Get the current timestamp
- $this->_end_rtime = microtime(TRUE);
-
- // Log the loading time to the log table
- if ($this->config->item('rest_enable_logging') === TRUE)
- {
- $this->_log_access_time();
+ if (file_exists(APPPATH.'config/'.$config_file.'.php')) {
+ $this->load->config($config_file, false);
+ } else {
+ if (file_exists(__DIR__.'/'.$config_file.'.php')) {
+ $config = [];
+ include __DIR__.'/'.$config_file.'.php';
+ foreach ($config as $key => $value) {
+ $this->config->set_item($key, $value);
+ }
+ }
}
}
/**
- * Checks to see if we have everything we need to run this library.
+ * De-constructor.
*
- * @access protected
- * @throws Exception
+ * @author Chris Kacerguis
+ *
+ * @return void
*/
- protected function preflight_checks()
+ public function __destruct()
{
- // Check to see if PHP is equal to or greater than 5.4.x
- if (is_php('5.4') === FALSE)
- {
- // CodeIgniter 3 is recommended for v5.4 or above
- throw new Exception('Using PHP v'.PHP_VERSION.', though PHP v5.4 or greater is required');
- }
+ // Log the loading time to the log table
+ if ($this->config->item('rest_enable_logging') === true) {
+ // Get the current timestamp
+ $this->_end_rtime = microtime(true);
- // Check to see if this is CI 3.x
- if (explode('.', CI_VERSION, 2)[0] < 3)
- {
- throw new Exception('REST Server requires CodeIgniter 3.x');
+ $this->_log_access_time();
}
}
/**
* Requests are not made to methods directly, the request will be for
* an "object". This simply maps the object and method to the correct
- * Controller method
+ * Controller method.
*
- * @access public
* @param string $object_called
- * @param array $arguments The arguments passed to the controller method
+ * @param array $arguments The arguments passed to the controller method
+ *
* @throws Exception
*/
public function _remap($object_called, $arguments = [])
{
// Should we answer if not over SSL?
- if ($this->config->item('force_https') && $this->request->ssl === FALSE)
- {
+ if ($this->config->item('force_https') && $this->request->ssl === false) {
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unsupported')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unsupported'),
], self::HTTP_FORBIDDEN);
-
- $this->is_valid_request = false;
}
// Remove the supported format from the function name e.g. index.json => index
@@ -681,74 +507,59 @@ public function _remap($object_called, $arguments = [])
$controller_method = $object_called.'_'.$this->request->method;
// Does this method exist? If not, try executing an index method
if (!method_exists($this, $controller_method)) {
- $controller_method = "index_" . $this->request->method;
+ $controller_method = 'index_'.$this->request->method;
array_unshift($arguments, $object_called);
}
// Do we want to log this method (if allowed by config)?
- $log_method = ! (isset($this->methods[$controller_method]['log']) && $this->methods[$controller_method]['log'] === FALSE);
+ $log_method = !(isset($this->methods[$controller_method]['log']) && $this->methods[$controller_method]['log'] === false);
// Use keys for this method?
- $use_key = ! (isset($this->methods[$controller_method]['key']) && $this->methods[$controller_method]['key'] === FALSE);
+ $use_key = !(isset($this->methods[$controller_method]['key']) && $this->methods[$controller_method]['key'] === false);
// They provided a key, but it wasn't valid, so get them out of here
- if ($this->config->item('rest_enable_keys') && $use_key && $this->_allow === FALSE)
- {
- if ($this->config->item('rest_enable_logging') && $log_method)
- {
+ if ($this->config->item('rest_enable_keys') && $use_key && $this->_allow === false) {
+ if ($this->config->item('rest_enable_logging') && $log_method) {
$this->_log_request();
}
// fix cross site to option request error
- if($this->request->method == 'options') {
+ if ($this->request->method == 'options') {
exit;
}
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => sprintf($this->lang->line('text_rest_invalid_api_key'), $this->rest->key)
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => sprintf($this->lang->line('text_rest_invalid_api_key'), $this->rest->key),
], self::HTTP_FORBIDDEN);
-
- $this->is_valid_request = false;
}
// Check to see if this key has access to the requested controller
- if ($this->config->item('rest_enable_keys') && $use_key && empty($this->rest->key) === FALSE && $this->_check_access() === FALSE)
- {
- if ($this->config->item('rest_enable_logging') && $log_method)
- {
+ if ($this->config->item('rest_enable_keys') && $use_key && empty($this->rest->key) === false && $this->_check_access() === false) {
+ if ($this->config->item('rest_enable_logging') && $log_method) {
$this->_log_request();
}
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_unauthorized')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_unauthorized'),
], self::HTTP_UNAUTHORIZED);
-
- $this->is_valid_request = false;
}
// Sure it exists, but can they do anything with it?
- if (! method_exists($this, $controller_method))
- {
+ if (!method_exists($this, $controller_method)) {
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unknown_method')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unknown_method'),
], self::HTTP_METHOD_NOT_ALLOWED);
-
- $this->is_valid_request = false;
}
// Doing key related stuff? Can only do it if they have a key right?
- if ($this->config->item('rest_enable_keys') && empty($this->rest->key) === FALSE)
- {
+ if ($this->config->item('rest_enable_keys') && empty($this->rest->key) === false) {
// Check the limit
- if ($this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === FALSE)
- {
- $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_time_limit')];
+ if ($this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === false) {
+ $response = [$this->config->item('rest_status_field_name') => false, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_time_limit')];
$this->response($response, self::HTTP_UNAUTHORIZED);
-
- $this->is_valid_request = false;
}
// If no level is set use 0, they probably aren't using permissions
@@ -757,45 +568,34 @@ public function _remap($object_called, $arguments = [])
// If no level is set, or it is lower than/equal to the key's level
$authorized = $level <= $this->rest->level;
// IM TELLIN!
- if ($this->config->item('rest_enable_logging') && $log_method)
- {
+ if ($this->config->item('rest_enable_logging') && $log_method) {
$this->_log_request($authorized);
}
- if($authorized === FALSE)
- {
+ if ($authorized === false) {
// They don't have good enough perms
- $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_permissions')];
+ $response = [$this->config->item('rest_status_field_name') => false, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_api_key_permissions')];
$this->response($response, self::HTTP_UNAUTHORIZED);
-
- $this->is_valid_request = false;
}
}
//check request limit by ip without login
- elseif ($this->config->item('rest_limits_method') == "IP_ADDRESS" && $this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === FALSE)
- {
- $response = [$this->config->item('rest_status_field_name') => FALSE, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_address_time_limit')];
+ elseif ($this->config->item('rest_limits_method') == 'IP_ADDRESS' && $this->config->item('rest_enable_limits') && $this->_check_limit($controller_method) === false) {
+ $response = [$this->config->item('rest_status_field_name') => false, $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_address_time_limit')];
$this->response($response, self::HTTP_UNAUTHORIZED);
-
- $this->is_valid_request = false;
}
// No key stuff, but record that stuff is happening
- elseif ($this->config->item('rest_enable_logging') && $log_method)
- {
- $this->_log_request($authorized = TRUE);
+ elseif ($this->config->item('rest_enable_logging') && $log_method) {
+ $this->_log_request($authorized = true);
}
// Call the controller method and passed arguments
- try
- {
+ try {
if ($this->is_valid_request) {
call_user_func_array([$this, $controller_method], $arguments);
}
- }
- catch (Exception $ex)
- {
- if ($this->config->item('rest_handle_exceptions') === FALSE) {
+ } catch (Exception $ex) {
+ if ($this->config->item('rest_handle_exceptions') === false) {
throw $ex;
}
@@ -806,168 +606,170 @@ public function _remap($object_called, $arguments = [])
}
/**
- * Takes mixed data and optionally a status code, then creates the response
+ * Takes mixed data and optionally a status code, then creates the response.
*
- * @access public
- * @param array|NULL $data Data to output to the user
- * @param int|NULL $http_code HTTP status code
- * @param bool $continue TRUE to flush the response to the client and continue
- * running the script; otherwise, exit
+ * @param array|null $data Data to output to the user
+ * @param int|null $http_code HTTP status code
+ * @param bool $continue TRUE to flush the response to the client and continue
+ * running the script; otherwise, exit
*/
- public function response($data = NULL, $http_code = NULL, $continue = FALSE)
+ public function response($data = null, $http_code = null, $continue = false)
{
//if profiling enabled then print profiling data
- $isProfilingEnabled = $this->config->item('enable_profiling');
- if(!$isProfilingEnabled){
- ob_start();
- // If the HTTP status is not NULL, then cast as an integer
- if ($http_code !== NULL)
- {
- // So as to be safe later on in the process
- $http_code = (int) $http_code;
- }
-
- // Set the output as NULL by default
- $output = NULL;
-
- // If data is NULL and no HTTP status code provided, then display, error and exit
- if ($data === NULL && $http_code === NULL)
- {
- $http_code = self::HTTP_NOT_FOUND;
- }
-
- // If data is not NULL and a HTTP status code provided, then continue
- elseif ($data !== NULL)
- {
- // If the format method exists, call and return the output in that format
- if (method_exists($this->format, 'to_' . $this->response->format))
- {
- // Set the format header
- $this->output->set_content_type($this->_supported_formats[$this->response->format], strtolower($this->config->item('charset')));
- $output = $this->format->factory($data)->{'to_' . $this->response->format}();
-
- // An array must be parsed as a string, so as not to cause an array to string error
- // Json is the most appropriate form for such a data type
- if ($this->response->format === 'array')
- {
- $output = $this->format->factory($output)->{'to_json'}();
- }
- }
- else
- {
- // If an array or object, then parse as a json, so as to be a 'string'
- if (is_array($data) || is_object($data))
- {
- $data = $this->format->factory($data)->{'to_json'}();
- }
-
- // Format is not supported, so output the raw data as a string
- $output = $data;
- }
- }
-
- // If not greater than zero, then set the HTTP status code as 200 by default
- // Though perhaps 500 should be set instead, for the developer not passing a
- // correct HTTP status code
- $http_code > 0 || $http_code = self::HTTP_OK;
-
- $this->output->set_status_header($http_code);
-
- // JC: Log response code only if rest logging enabled
- if ($this->config->item('rest_enable_logging') === TRUE)
- {
- $this->_log_response_code($http_code);
- }
-
- // Output the data
- $this->output->set_output($output);
-
- if ($continue === FALSE)
- {
- // Display the data and exit execution
- $this->output->_display();
- exit;
- }
- else
- {
- ob_end_flush();
- }
-
- // Otherwise dump the output automatically
- }
- else{
- echo json_encode($data);
- }
+ $isProfilingEnabled = $this->config->item('enable_profiling');
+ if (!$isProfilingEnabled) {
+ ob_start();
+ // If the HTTP status is not NULL, then cast as an integer
+ if ($http_code !== null) {
+ // So as to be safe later on in the process
+ $http_code = (int) $http_code;
+ }
+
+ // Set the output as NULL by default
+ $output = null;
+
+ // If data is NULL and no HTTP status code provided, then display, error and exit
+ if ($data === null && $http_code === null) {
+ $http_code = self::HTTP_NOT_FOUND;
+ }
+
+ // If data is not NULL and a HTTP status code provided, then continue
+ elseif ($data !== null) {
+ // If the format method exists, call and return the output in that format
+ $formatter = null;
+ if ($this->format && method_exists($this->format, 'to_'.$this->response->format)) {
+ $formatter = $this->format::factory($data);
+ } elseif (method_exists(Format::class, 'to_'.$this->response->format)) {
+ $formatter = Format::factory($data);
+ }
+
+ if ($formatter !== null) {
+ // CORB protection
+ // First, get the output content.
+ $output = $formatter->{'to_'.$this->response->format}();
+
+ // Set the format header
+ // Then, check if the client asked for a callback, and if the output contains this callback :
+ if (isset($this->_get_args['callback']) && $this->response->format == 'json' && preg_match('/^'.$this->_get_args['callback'].'/', $output)) {
+ $this->output->set_content_type($this->_supported_formats['jsonp'], strtolower($this->config->item('charset')));
+ } else {
+ $this->output->set_content_type($this->_supported_formats[$this->response->format], strtolower($this->config->item('charset')));
+ }
+
+ // An array must be parsed as a string, so as not to cause an array to string error
+ // Json is the most appropriate form for such a data type
+ if ($this->response->format === 'array') {
+ $output = Format::factory($output)->{'to_json'}();
+ }
+ } else {
+ // If an array or object, then parse as a json, so as to be a 'string'
+ if (is_array($data) || is_object($data)) {
+ $data = Format::factory($data)->{'to_json'}();
+ }
+
+ // Format is not supported, so output the raw data as a string
+ $output = $data;
+ }
+ }
+
+ // If not greater than zero, then set the HTTP status code as 200 by default
+ // Though perhaps 500 should be set instead, for the developer not passing a
+ // correct HTTP status code
+ $http_code > 0 || $http_code = self::HTTP_OK;
+
+ $this->output->set_status_header($http_code);
+
+ // JC: Log response code only if rest logging enabled
+ if ($this->config->item('rest_enable_logging') === true) {
+ $this->_log_response_code($http_code);
+ }
+
+ // Output the data
+ $this->output->set_output($output);
+
+ if ($continue === false) {
+ // Display the data and exit execution
+ $this->output->_display();
+ exit;
+ } else {
+ if (is_callable('fastcgi_finish_request')) {
+ // Terminates connection and returns response to client on PHP-FPM.
+ $this->output->_display();
+ ob_end_flush();
+ fastcgi_finish_request();
+ ignore_user_abort(true);
+ } else {
+ // Legacy compatibility.
+ ob_end_flush();
+ }
+ }
+ ob_end_flush();
+ // Otherwise dump the output automatically
+ } else {
+ echo json_encode($data);
+ }
}
/**
* Takes mixed data and optionally a status code, then creates the response
* within the buffers of the Output class. The response is sent to the client
* lately by the framework, after the current controller's method termination.
- * All the hooks after the controller's method termination are executable
+ * All the hooks after the controller's method termination are executable.
*
- * @access public
- * @param array|NULL $data Data to output to the user
- * @param int|NULL $http_code HTTP status code
+ * @param array|null $data Data to output to the user
+ * @param int|null $http_code HTTP status code
*/
- public function set_response($data = NULL, $http_code = NULL)
+ public function set_response($data = null, $http_code = null)
{
- $this->response($data, $http_code, TRUE);
+ $this->response($data, $http_code, true);
}
/**
- * Get the input format e.g. json or xml
+ * Get the input format e.g. json or xml.
*
- * @access protected
- * @return string|NULL Supported input format; otherwise, NULL
+ * @return string|null Supported input format; otherwise, NULL
*/
protected function _detect_input_format()
{
// Get the CONTENT-TYPE value from the SERVER variable
$content_type = $this->input->server('CONTENT_TYPE');
- if (empty($content_type) === FALSE)
- {
+ if (empty($content_type) === false) {
// If a semi-colon exists in the string, then explode by ; and get the value of where
// the current array pointer resides. This will generally be the first element of the array
- $content_type = (strpos($content_type, ';') !== FALSE ? current(explode(';', $content_type)) : $content_type);
+ $content_type = (strpos($content_type, ';') !== false ? current(explode(';', $content_type)) : $content_type);
// Check all formats against the CONTENT-TYPE header
- foreach ($this->_supported_formats as $type => $mime)
- {
+ foreach ($this->_supported_formats as $type => $mime) {
// $type = format e.g. csv
// $mime = mime type e.g. application/csv
// If both the mime types match, then return the format
- if ($content_type === $mime)
- {
+ if ($content_type === $mime) {
return $type;
}
}
}
-
- return NULL;
}
/**
* Gets the default format from the configuration. Fallbacks to 'json'
* if the corresponding configuration option $config['rest_default_format']
- * is missing or is empty
+ * is missing or is empty.
*
- * @access protected
* @return string The default supported input format
*/
protected function _get_default_output_format()
{
$default_format = (string) $this->config->item('rest_default_format');
+
return $default_format === '' ? 'json' : $default_format;
}
/**
- * Detect which format should be used to output the data
+ * Detect which format should be used to output the data.
*
- * @access protected
- * @return mixed|NULL|string Output format
+ * @return mixed|null|string Output format
*/
protected function _detect_output_format()
{
@@ -976,18 +778,15 @@ protected function _detect_output_format()
$matches = [];
// Check if a file extension is used e.g. http://example.com/api/index.json?param1=param2
- if (preg_match($pattern, $this->uri->uri_string(), $matches))
- {
+ if (preg_match($pattern, $this->uri->uri_string(), $matches)) {
return $matches[1];
}
// Get the format parameter named as 'format'
- if (isset($this->_get_args['format']))
- {
+ if (isset($this->_get_args['format'])) {
$format = strtolower($this->_get_args['format']);
- if (isset($this->_supported_formats[$format]) === TRUE)
- {
+ if (isset($this->_supported_formats[$format]) === true) {
return $format;
}
}
@@ -996,27 +795,19 @@ protected function _detect_output_format()
$http_accept = $this->input->server('HTTP_ACCEPT');
// Otherwise, check the HTTP_ACCEPT server variable
- if ($this->config->item('rest_ignore_http_accept') === FALSE && $http_accept !== NULL)
- {
+ if ($this->config->item('rest_ignore_http_accept') === false && $http_accept !== null) {
// Check all formats against the HTTP_ACCEPT header
- foreach (array_keys($this->_supported_formats) as $format)
- {
+ foreach (array_keys($this->_supported_formats) as $format) {
// Has this format been requested?
- if (strpos($http_accept, $format) !== FALSE)
- {
- if ($format !== 'html' && $format !== 'xml')
- {
+ if (strpos($http_accept, $format) !== false) {
+ if ($format !== 'html' && $format !== 'xml') {
// If not HTML or XML assume it's correct
return $format;
- }
- elseif ($format === 'html' && strpos($http_accept, 'xml') === FALSE)
- {
+ } elseif ($format === 'html' && strpos($http_accept, 'xml') === false) {
// HTML or XML have shown up as a match
// If it is truly HTML, it wont want any XML
return $format;
- }
- else if ($format === 'xml' && strpos($http_accept, 'html') === FALSE)
- {
+ } elseif ($format === 'xml' && strpos($http_accept, 'html') === false) {
// If it is truly XML, it wont want any HTML
return $format;
}
@@ -1025,8 +816,7 @@ protected function _detect_output_format()
}
// Check if the controller has a default format
- if (empty($this->rest_format) === FALSE)
- {
+ if (empty($this->rest_format) === false) {
return $this->rest_format;
}
@@ -1035,41 +825,38 @@ protected function _detect_output_format()
}
/**
- * Get the HTTP request string e.g. get or post
+ * Get the HTTP request string e.g. get or post.
*
- * @access protected
- * @return string|NULL Supported request method as a lowercase string; otherwise, NULL if not supported
+ * @return string|null Supported request method as a lowercase string; otherwise, NULL if not supported
*/
protected function _detect_method()
{
// Declare a variable to store the method
- $method = NULL;
+ $method = null;
// Determine whether the 'enable_emulate_request' setting is enabled
- if ($this->config->item('enable_emulate_request') === TRUE)
- {
+ if ($this->config->item('enable_emulate_request') === true) {
$method = $this->input->post('_method');
- if ($method === NULL)
- {
+ if ($method === null) {
$method = $this->input->server('HTTP_X_HTTP_METHOD_OVERRIDE');
}
- $method = strtolower($method);
+ if ($method !== null) {
+ $method = strtolower($method);
+ }
}
- if (empty($method))
- {
+ if (empty($method)) {
// Get the request method as a lowercase string
$method = $this->input->method();
}
- return in_array($method, $this->allowed_http_methods) && method_exists($this, '_parse_' . $method) ? $method : 'get';
+ return in_array($method, $this->allowed_http_methods) && method_exists($this, '_parse_'.$method) ? $method : 'get';
}
/**
- * See if the user has provided an API key
+ * See if the user has provided an API key.
*
- * @access protected
* @return bool
*/
protected function _detect_api_key()
@@ -1078,22 +865,24 @@ protected function _detect_api_key()
$api_key_variable = $this->config->item('rest_key_name');
// Work out the name of the SERVER entry based on config
- $key_name = 'HTTP_' . strtoupper(str_replace('-', '_', $api_key_variable));
+ $key_name = 'HTTP_'.strtoupper(str_replace('-', '_', $api_key_variable));
- $this->rest->key = NULL;
- $this->rest->level = NULL;
- $this->rest->user_id = NULL;
- $this->rest->ignore_limits = FALSE;
+ $this->rest->key = null;
+ $this->rest->level = null;
+ $this->rest->user_id = null;
+ $this->rest->ignore_limits = false;
// Find the key from server or arguments
- if (($key = isset($this->_args[$api_key_variable]) ? $this->_args[$api_key_variable] : $this->input->server($key_name)))
- {
- if ( ! ($row = $this->rest->db->where($this->config->item('rest_key_column'), $key)->get($this->config->item('rest_keys_table'))->row()))
- {
- return FALSE;
+ if ($key = isset($this->_args[$api_key_variable]) ? $this->_args[$api_key_variable] : $this->input->server($key_name)) {
+ $this->rest->key = $key;
+
+ if (!($row = $this->rest->db->where($this->config->item('rest_key_column'), $key)->get($this->config->item('rest_keys_table'))->row())) {
+ return false;
}
- $this->rest->key = $row->{$this->config->item('rest_key_column')};
+ if ($this->config->item('rest_keys_expire') === true && $row->{$this->config->item('rest_keys_expiry_column')} < time()) {
+ return false;
+ }
isset($row->user_id) && $this->rest->user_id = $row->user_id;
isset($row->level) && $this->rest->level = $row->level;
@@ -1105,63 +894,54 @@ protected function _detect_api_key()
* If "is private key" is enabled, compare the ip address with the list
* of valid ip addresses stored in the database
*/
- if (empty($row->is_private_key) === FALSE)
- {
+ if (empty($row->is_private_key) === false) {
// Check for a list of valid ip addresses
- if (isset($row->ip_addresses))
- {
+ if (isset($row->ip_addresses)) {
// multiple ip addresses must be separated using a comma, explode and loop
$list_ip_addresses = explode(',', $row->ip_addresses);
- $found_address = FALSE;
+ $ip_address = $this->input->ip_address();
+ $found_address = false;
- foreach ($list_ip_addresses as $ip_address)
- {
- if ($this->input->ip_address() === trim($ip_address))
- {
+ foreach ($list_ip_addresses as $list_ip) {
+ if ($ip_address === trim($list_ip)) {
// there is a match, set the the value to TRUE and break out of the loop
- $found_address = TRUE;
+ $found_address = true;
break;
}
}
return $found_address;
- }
- else
- {
+ } else {
// There should be at least one IP address for this private key
- return FALSE;
+ return false;
}
}
- return TRUE;
+ return true;
}
// No key has been sent
- return FALSE;
+ return false;
}
/**
- * Preferred return language
+ * Preferred return language.
*
- * @access protected
- * @return string|NULL|array The language code
+ * @return string|null|array The language code
*/
protected function _detect_lang()
{
$lang = $this->input->server('HTTP_ACCEPT_LANGUAGE');
- if ($lang === NULL)
- {
- return NULL;
+ if ($lang === null) {
+ return;
}
// It appears more than one language has been sent using a comma delimiter
- if (strpos($lang, ',') !== FALSE)
- {
+ if (strpos($lang, ',') !== false) {
$langs = explode(',', $lang);
$return_langs = [];
- foreach ($langs as $lang)
- {
+ foreach ($langs as $lang) {
// Remove weight and trim leading and trailing whitespace
list($lang) = explode(';', $lang);
$return_langs[] = trim($lang);
@@ -1175,26 +955,28 @@ protected function _detect_lang()
}
/**
- * Add the request to the log table
+ * Add the request to the log table.
*
- * @access protected
* @param bool $authorized TRUE the user is authorized; otherwise, FALSE
+ *
* @return bool TRUE the data was inserted; otherwise, FALSE
*/
- protected function _log_request($authorized = FALSE)
+ protected function _log_request($authorized = false)
{
// Insert the request into the log table
$is_inserted = $this->rest->db
->insert(
- $this->config->item('rest_logs_table'), [
- 'uri' => $this->uri->uri_string(),
- 'method' => $this->request->method,
- 'params' => $this->_args ? ($this->config->item('rest_logs_json_params') === TRUE ? json_encode($this->_args) : serialize($this->_args)) : NULL,
- 'api_key' => isset($this->rest->key) ? $this->rest->key : '',
- 'ip_address' => $this->input->ip_address(),
- 'time' => time(),
- 'authorized' => $authorized
- ]);
+ $this->config->item('rest_logs_table'),
+ [
+ 'uri' => $this->uri->uri_string(),
+ 'method' => $this->request->method,
+ 'params' => $this->_args ? ($this->config->item('rest_logs_json_params') === true ? json_encode($this->_args) : serialize($this->_args)) : null,
+ 'api_key' => isset($this->rest->key) ? $this->rest->key : '',
+ 'ip_address' => $this->input->ip_address(),
+ 'time' => time(),
+ 'authorized' => $authorized,
+ ]
+ );
// Get the last insert id to update at a later stage of the request
$this->_insert_id = $this->rest->db->insert_id();
@@ -1203,53 +985,49 @@ protected function _log_request($authorized = FALSE)
}
/**
- * Check if the requests to a controller method exceed a limit
+ * Check if the requests to a controller method exceed a limit.
*
- * @access protected
* @param string $controller_method The method being called
+ *
* @return bool TRUE the call limit is below the threshold; otherwise, FALSE
*/
protected function _check_limit($controller_method)
{
// They are special, or it might not even have a limit
- if (empty($this->rest->ignore_limits) === FALSE)
- {
+ if (empty($this->rest->ignore_limits) === false) {
// Everything is fine
- return TRUE;
+ return true;
}
$api_key = isset($this->rest->key) ? $this->rest->key : '';
- switch ($this->config->item('rest_limits_method'))
- {
+ switch ($this->config->item('rest_limits_method')) {
case 'IP_ADDRESS':
- $limited_uri = 'ip-address:' .$this->input->ip_address();
$api_key = $this->input->ip_address();
+ $limited_uri = 'ip-address:'.$api_key;
break;
case 'API_KEY':
- $limited_uri = 'api-key:' . $api_key;
+ $limited_uri = 'api-key:'.$api_key;
break;
case 'METHOD_NAME':
- $limited_uri = 'method-name:' . $controller_method;
+ $limited_uri = 'method-name:'.$controller_method;
break;
case 'ROUTED_URL':
default:
$limited_uri = $this->uri->ruri_string();
- if (strpos(strrev($limited_uri), strrev($this->response->format)) === 0)
- {
- $limited_uri = substr($limited_uri,0, -strlen($this->response->format) - 1);
+ if (strpos(strrev($limited_uri), strrev($this->response->format)) === 0) {
+ $limited_uri = substr($limited_uri, 0, -strlen($this->response->format) - 1);
}
$limited_uri = 'uri:'.$limited_uri.':'.$this->request->method; // It's good to differentiate GET from PUT
break;
}
- if (isset($this->methods[$controller_method]['limit']) === FALSE )
- {
+ if (isset($this->methods[$controller_method]['limit']) === false) {
// Everything is fine
- return TRUE;
+ return true;
}
// How many times can you get to this method in a defined time_limit (default: 1 hour)?
@@ -1265,20 +1043,18 @@ protected function _check_limit($controller_method)
->row();
// No calls have been made for this key
- if ($result === NULL)
- {
+ if ($result === null) {
// Create a new row for the following key
$this->rest->db->insert($this->config->item('rest_limits_table'), [
- 'uri' => $limited_uri,
- 'api_key' =>$api_key,
- 'count' => 1,
- 'hour_started' => time()
+ 'uri' => $limited_uri,
+ 'api_key' => $api_key,
+ 'count' => 1,
+ 'hour_started' => time(),
]);
}
// Been a time limit (or by default an hour) since they called
- elseif ($result->hour_started < (time() - $time_limit))
- {
+ elseif ($result->hour_started < (time() - $time_limit)) {
// Reset the started period and count
$this->rest->db
->where('uri', $limited_uri)
@@ -1289,29 +1065,26 @@ protected function _check_limit($controller_method)
}
// They have called within the hour, so lets update
- else
- {
+ else {
// The limit has been exceeded
- if ($result->count >= $limit)
- {
- return FALSE;
+ if ($result->count >= $limit) {
+ return false;
}
// Increase the count by one
$this->rest->db
->where('uri', $limited_uri)
->where('api_key', $api_key)
- ->set('count', 'count + 1', FALSE)
+ ->set('count', 'count + 1', false)
->update($this->config->item('rest_limits_table'));
}
- return TRUE;
+ return true;
}
/**
- * Check if there is a specific auth type set for the current class/method/HTTP-method being called
+ * Check if there is a specific auth type set for the current class/method/HTTP-method being called.
*
- * @access protected
* @return bool
*/
protected function _auth_override_check()
@@ -1320,89 +1093,76 @@ protected function _auth_override_check()
$auth_override_class_method = $this->config->item('auth_override_class_method');
// Check to see if the override array is even populated
- if ( ! empty($auth_override_class_method))
- {
+ if (!empty($auth_override_class_method)) {
// Check for wildcard flag for rules for classes
- if ( ! empty($auth_override_class_method[$this->router->class]['*'])) // Check for class overrides
- {
+ if (!empty($auth_override_class_method[$this->router->class]['*'])) { // Check for class overrides
// No auth override found, prepare nothing but send back a TRUE override flag
- if ($auth_override_class_method[$this->router->class]['*'] === 'none')
- {
- return TRUE;
+ if ($auth_override_class_method[$this->router->class]['*'] === 'none') {
+ return true;
}
// Basic auth override found, prepare basic
- if ($auth_override_class_method[$this->router->class]['*'] === 'basic')
- {
+ if ($auth_override_class_method[$this->router->class]['*'] === 'basic') {
$this->_prepare_basic_auth();
- return TRUE;
+ return true;
}
// Digest auth override found, prepare digest
- if ($auth_override_class_method[$this->router->class]['*'] === 'digest')
- {
+ if ($auth_override_class_method[$this->router->class]['*'] === 'digest') {
$this->_prepare_digest_auth();
- return TRUE;
+ return true;
}
// Session auth override found, check session
- if ($auth_override_class_method[$this->router->class]['*'] === 'session')
- {
+ if ($auth_override_class_method[$this->router->class]['*'] === 'session') {
$this->_check_php_session();
- return TRUE;
+ return true;
}
// Whitelist auth override found, check client's ip against config whitelist
- if ($auth_override_class_method[$this->router->class]['*'] === 'whitelist')
- {
+ if ($auth_override_class_method[$this->router->class]['*'] === 'whitelist') {
$this->_check_whitelist_auth();
- return TRUE;
+ return true;
}
}
// Check to see if there's an override value set for the current class/method being called
- if ( ! empty($auth_override_class_method[$this->router->class][$this->router->method]))
- {
+ if (!empty($auth_override_class_method[$this->router->class][$this->router->method])) {
// None auth override found, prepare nothing but send back a TRUE override flag
- if ($auth_override_class_method[$this->router->class][$this->router->method] === 'none')
- {
- return TRUE;
+ if ($auth_override_class_method[$this->router->class][$this->router->method] === 'none') {
+ return true;
}
// Basic auth override found, prepare basic
- if ($auth_override_class_method[$this->router->class][$this->router->method] === 'basic')
- {
+ if ($auth_override_class_method[$this->router->class][$this->router->method] === 'basic') {
$this->_prepare_basic_auth();
- return TRUE;
+ return true;
}
// Digest auth override found, prepare digest
- if ($auth_override_class_method[$this->router->class][$this->router->method] === 'digest')
- {
+ if ($auth_override_class_method[$this->router->class][$this->router->method] === 'digest') {
$this->_prepare_digest_auth();
- return TRUE;
+ return true;
}
// Session auth override found, check session
- if ($auth_override_class_method[$this->router->class][$this->router->method] === 'session')
- {
+ if ($auth_override_class_method[$this->router->class][$this->router->method] === 'session') {
$this->_check_php_session();
- return TRUE;
+ return true;
}
// Whitelist auth override found, check client's ip against config whitelist
- if ($auth_override_class_method[$this->router->class][$this->router->method] === 'whitelist')
- {
+ if ($auth_override_class_method[$this->router->class][$this->router->method] === 'whitelist') {
$this->_check_whitelist_auth();
- return TRUE;
+ return true;
}
}
}
@@ -1411,99 +1171,86 @@ protected function _auth_override_check()
$auth_override_class_method_http = $this->config->item('auth_override_class_method_http');
// Check to see if the override array is even populated
- if ( ! empty($auth_override_class_method_http))
- {
+ if (!empty($auth_override_class_method_http)) {
// check for wildcard flag for rules for classes
- if ( ! empty($auth_override_class_method_http[$this->router->class]['*'][$this->request->method]))
- {
+ if (!empty($auth_override_class_method_http[$this->router->class]['*'][$this->request->method])) {
// None auth override found, prepare nothing but send back a TRUE override flag
- if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'none')
- {
- return TRUE;
+ if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'none') {
+ return true;
}
// Basic auth override found, prepare basic
- if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'basic')
- {
+ if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'basic') {
$this->_prepare_basic_auth();
- return TRUE;
+ return true;
}
// Digest auth override found, prepare digest
- if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'digest')
- {
+ if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'digest') {
$this->_prepare_digest_auth();
- return TRUE;
+ return true;
}
// Session auth override found, check session
- if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'session')
- {
+ if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'session') {
$this->_check_php_session();
- return TRUE;
+ return true;
}
// Whitelist auth override found, check client's ip against config whitelist
- if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'whitelist')
- {
+ if ($auth_override_class_method_http[$this->router->class]['*'][$this->request->method] === 'whitelist') {
$this->_check_whitelist_auth();
- return TRUE;
+ return true;
}
}
// Check to see if there's an override value set for the current class/method/HTTP-method being called
- if ( ! empty($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method]))
- {
+ if (!empty($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method])) {
// None auth override found, prepare nothing but send back a TRUE override flag
- if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'none')
- {
- return TRUE;
+ if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'none') {
+ return true;
}
// Basic auth override found, prepare basic
- if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'basic')
- {
+ if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'basic') {
$this->_prepare_basic_auth();
- return TRUE;
+ return true;
}
// Digest auth override found, prepare digest
- if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'digest')
- {
+ if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'digest') {
$this->_prepare_digest_auth();
- return TRUE;
+ return true;
}
// Session auth override found, check session
- if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'session')
- {
+ if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'session') {
$this->_check_php_session();
- return TRUE;
+ return true;
}
// Whitelist auth override found, check client's ip against config whitelist
- if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'whitelist')
- {
+ if ($auth_override_class_method_http[$this->router->class][$this->router->method][$this->request->method] === 'whitelist') {
$this->_check_whitelist_auth();
- return TRUE;
+ return true;
}
}
}
- return FALSE;
+
+ return false;
}
/**
- * Parse the GET request arguments
+ * Parse the GET request arguments.
*
- * @access protected
* @return void
*/
protected function _parse_get()
@@ -1513,48 +1260,40 @@ protected function _parse_get()
}
/**
- * Parse the POST request arguments
+ * Parse the POST request arguments.
*
- * @access protected
* @return void
*/
protected function _parse_post()
{
$this->_post_args = $_POST;
- if ($this->request->format)
- {
+ if ($this->request->format) {
$this->request->body = $this->input->raw_input_stream;
}
}
/**
- * Parse the PUT request arguments
+ * Parse the PUT request arguments.
*
- * @access protected
* @return void
*/
protected function _parse_put()
{
- if ($this->request->format)
- {
+ if ($this->request->format) {
$this->request->body = $this->input->raw_input_stream;
- if ($this->request->format === 'json')
- {
+ if ($this->request->format === 'json') {
$this->_put_args = json_decode($this->input->raw_input_stream);
}
- }
- else if ($this->input->method() === 'put')
- {
+ } elseif ($this->input->method() === 'put') {
// If no file type is provided, then there are probably just arguments
$this->_put_args = $this->input->input_stream();
}
}
/**
- * Parse the HEAD request arguments
+ * Parse the HEAD request arguments.
*
- * @access protected
* @return void
*/
protected function _parse_head()
@@ -1567,9 +1306,8 @@ protected function _parse_head()
}
/**
- * Parse the OPTIONS request arguments
+ * Parse the OPTIONS request arguments.
*
- * @access protected
* @return void
*/
protected function _parse_options()
@@ -1582,44 +1320,37 @@ protected function _parse_options()
}
/**
- * Parse the PATCH request arguments
+ * Parse the PATCH request arguments.
*
- * @access protected
* @return void
*/
protected function _parse_patch()
{
// It might be a HTTP body
- if ($this->request->format)
- {
+ if ($this->request->format) {
$this->request->body = $this->input->raw_input_stream;
- }
- else if ($this->input->method() === 'patch')
- {
+ } elseif ($this->input->method() === 'patch') {
// If no file type is provided, then there are probably just arguments
$this->_patch_args = $this->input->input_stream();
}
}
/**
- * Parse the DELETE request arguments
+ * Parse the DELETE request arguments.
*
- * @access protected
* @return void
*/
protected function _parse_delete()
{
// These should exist if a DELETE request
- if ($this->input->method() === 'delete')
- {
+ if ($this->input->method() === 'delete') {
$this->_delete_args = $this->input->input_stream();
}
}
/**
- * Parse the query parameters
+ * Parse the query parameters.
*
- * @access protected
* @return void
*/
protected function _parse_query()
@@ -1630,177 +1361,172 @@ protected function _parse_query()
// INPUT FUNCTION --------------------------------------------------------------
/**
- * Retrieve a value from a GET request
+ * Retrieve a value from a GET request.
*
- * @access public
- * @param NULL $key Key to retrieve from the GET request
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the GET request; otherwise, NULL
+ * @param null $key Key to retrieve from the GET request
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
+ *
+ * @return array|string|null Value from the GET request; otherwise, NULL
*/
- public function get($key = NULL, $xss_clean = NULL)
+ public function get($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
return $this->_get_args;
}
- return isset($this->_get_args[$key]) ? $this->_xss_clean($this->_get_args[$key], $xss_clean) : NULL;
+ return isset($this->_get_args[$key]) ? $this->_xss_clean($this->_get_args[$key], $xss_clean) : null;
}
/**
- * Retrieve a value from a OPTIONS request
+ * Retrieve a value from a OPTIONS request.
+ *
+ * @param null $key Key to retrieve from the OPTIONS request.
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
*
- * @access public
- * @param NULL $key Key to retrieve from the OPTIONS request.
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the OPTIONS request; otherwise, NULL
+ * @return array|string|null Value from the OPTIONS request; otherwise, NULL
*/
- public function options($key = NULL, $xss_clean = NULL)
+ public function options($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
return $this->_options_args;
}
- return isset($this->_options_args[$key]) ? $this->_xss_clean($this->_options_args[$key], $xss_clean) : NULL;
+ return isset($this->_options_args[$key]) ? $this->_xss_clean($this->_options_args[$key], $xss_clean) : null;
}
/**
- * Retrieve a value from a HEAD request
+ * Retrieve a value from a HEAD request.
*
- * @access public
- * @param NULL $key Key to retrieve from the HEAD request
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the HEAD request; otherwise, NULL
+ * @param null $key Key to retrieve from the HEAD request
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
+ *
+ * @return array|string|null Value from the HEAD request; otherwise, NULL
*/
- public function head($key = NULL, $xss_clean = NULL)
+ public function head($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
return $this->_head_args;
}
- return isset($this->_head_args[$key]) ? $this->_xss_clean($this->_head_args[$key], $xss_clean) : NULL;
+ return isset($this->_head_args[$key]) ? $this->_xss_clean($this->_head_args[$key], $xss_clean) : null;
}
/**
- * Retrieve a value from a POST request
+ * Retrieve a value from a POST request.
+ *
+ * @param null $key Key to retrieve from the POST request
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
*
- * @access public
- * @param NULL $key Key to retrieve from the POST request
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the POST request; otherwise, NULL
+ * @return array|string|null Value from the POST request; otherwise, NULL
*/
- public function post($key = NULL, $xss_clean = NULL)
+ public function post($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
+ foreach (new RecursiveIteratorIterator(new RecursiveArrayIterator($this->_post_args), RecursiveIteratorIterator::CATCH_GET_CHILD) as $key => $value) {
+ $this->_post_args[$key] = $this->_xss_clean($this->_post_args[$key], $xss_clean);
+ }
+
return $this->_post_args;
}
- return isset($this->_post_args[$key]) ? $this->_xss_clean($this->_post_args[$key], $xss_clean) : NULL;
+ return isset($this->_post_args[$key]) ? $this->_xss_clean($this->_post_args[$key], $xss_clean) : null;
}
/**
- * Retrieve a value from a PUT request
+ * Retrieve a value from a PUT request.
*
- * @access public
- * @param NULL $key Key to retrieve from the PUT request
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the PUT request; otherwise, NULL
+ * @param null $key Key to retrieve from the PUT request
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
+ *
+ * @return array|string|null Value from the PUT request; otherwise, NULL
*/
- public function put($key = NULL, $xss_clean = NULL)
+ public function put($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
return $this->_put_args;
}
- return isset($this->_put_args[$key]) ? $this->_xss_clean($this->_put_args[$key], $xss_clean) : NULL;
+ return isset($this->_put_args[$key]) ? $this->_xss_clean($this->_put_args[$key], $xss_clean) : null;
}
/**
- * Retrieve a value from a DELETE request
+ * Retrieve a value from a DELETE request.
+ *
+ * @param null $key Key to retrieve from the DELETE request
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
*
- * @access public
- * @param NULL $key Key to retrieve from the DELETE request
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the DELETE request; otherwise, NULL
+ * @return array|string|null Value from the DELETE request; otherwise, NULL
*/
- public function delete($key = NULL, $xss_clean = NULL)
+ public function delete($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
return $this->_delete_args;
}
- return isset($this->_delete_args[$key]) ? $this->_xss_clean($this->_delete_args[$key], $xss_clean) : NULL;
+ return isset($this->_delete_args[$key]) ? $this->_xss_clean($this->_delete_args[$key], $xss_clean) : null;
}
/**
- * Retrieve a value from a PATCH request
+ * Retrieve a value from a PATCH request.
+ *
+ * @param null $key Key to retrieve from the PATCH request
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
*
- * @access public
- * @param NULL $key Key to retrieve from the PATCH request
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the PATCH request; otherwise, NULL
+ * @return array|string|null Value from the PATCH request; otherwise, NULL
*/
- public function patch($key = NULL, $xss_clean = NULL)
+ public function patch($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
return $this->_patch_args;
}
- return isset($this->_patch_args[$key]) ? $this->_xss_clean($this->_patch_args[$key], $xss_clean) : NULL;
+ return isset($this->_patch_args[$key]) ? $this->_xss_clean($this->_patch_args[$key], $xss_clean) : null;
}
/**
- * Retrieve a value from the query parameters
+ * Retrieve a value from the query parameters.
*
- * @access public
- * @param NULL $key Key to retrieve from the query parameters
- * If NULL an array of arguments is returned
- * @param NULL $xss_clean Whether to apply XSS filtering
- * @return array|string|NULL Value from the query parameters; otherwise, NULL
+ * @param null $key Key to retrieve from the query parameters
+ * If NULL an array of arguments is returned
+ * @param null $xss_clean Whether to apply XSS filtering
+ *
+ * @return array|string|null Value from the query parameters; otherwise, NULL
*/
- public function query($key = NULL, $xss_clean = NULL)
+ public function query($key = null, $xss_clean = null)
{
- if ($key === NULL)
- {
+ if ($key === null) {
return $this->_query_args;
}
- return isset($this->_query_args[$key]) ? $this->_xss_clean($this->_query_args[$key], $xss_clean) : NULL;
+ return isset($this->_query_args[$key]) ? $this->_xss_clean($this->_query_args[$key], $xss_clean) : null;
}
/**
* Sanitizes data so that Cross Site Scripting Hacks can be
- * prevented
+ * prevented.
+ *
+ * @param string $value Input data
+ * @param bool $xss_clean Whether to apply XSS filtering
*
- * @access protected
- * @param string $value Input data
- * @param bool $xss_clean Whether to apply XSS filtering
* @return string
*/
protected function _xss_clean($value, $xss_clean)
{
is_bool($xss_clean) || $xss_clean = $this->_enable_xss;
- return $xss_clean === TRUE ? $this->security->xss_clean($value) : $value;
+ return $xss_clean === true ? $this->security->xss_clean($value) : $value;
}
/**
- * Retrieve the validation errors
+ * Retrieve the validation errors.
*
- * @access public
* @return array
*/
public function validation_errors()
@@ -1813,40 +1539,39 @@ public function validation_errors()
// SECURITY FUNCTIONS ---------------------------------------------------------
/**
- * Perform LDAP Authentication
+ * Perform LDAP Authentication.
*
- * @access protected
* @param string $username The username to validate
* @param string $password The password to validate
+ *
* @return bool
*/
- protected function _perform_ldap_auth($username = '', $password = NULL)
+ protected function _perform_ldap_auth($username = '', $password = null)
{
- if (empty($username))
- {
+ if (empty($username)) {
log_message('debug', 'LDAP Auth: failure, empty username');
- return FALSE;
+
+ return false;
}
log_message('debug', 'LDAP Auth: Loading configuration');
- $this->config->load('ldap', TRUE);
+ $this->config->load('ldap', true);
$ldap = [
'timeout' => $this->config->item('timeout', 'ldap'),
- 'host' => $this->config->item('server', 'ldap'),
- 'port' => $this->config->item('port', 'ldap'),
- 'rdn' => $this->config->item('binduser', 'ldap'),
- 'pass' => $this->config->item('bindpw', 'ldap'),
- 'basedn' => $this->config->item('basedn', 'ldap'),
+ 'host' => $this->config->item('server', 'ldap'),
+ 'port' => $this->config->item('port', 'ldap'),
+ 'rdn' => $this->config->item('binduser', 'ldap'),
+ 'pass' => $this->config->item('bindpw', 'ldap'),
+ 'basedn' => $this->config->item('basedn', 'ldap'),
];
- log_message('debug', 'LDAP Auth: Connect to ' . (isset($ldaphost) ? $ldaphost : '[ldap not configured]'));
+ log_message('debug', 'LDAP Auth: Connect to '.(isset($ldap['host']) ? $ldap['host'] : '[ldap not configured]'));
// Connect to the ldap server
$ldapconn = ldap_connect($ldap['host'], $ldap['port']);
- if ($ldapconn)
- {
+ if ($ldapconn) {
log_message('debug', 'Setting timeout to '.$ldap['timeout'].' seconds');
ldap_set_option($ldapconn, LDAP_OPT_NETWORK_TIMEOUT, $ldap['timeout']);
@@ -1857,45 +1582,45 @@ protected function _perform_ldap_auth($username = '', $password = NULL)
$ldapbind = ldap_bind($ldapconn, $ldap['rdn'], $ldap['pass']);
// Verify the binding
- if ($ldapbind === FALSE)
- {
+ if ($ldapbind === false) {
log_message('error', 'LDAP Auth: bind was unsuccessful');
- return FALSE;
+
+ return false;
}
log_message('debug', 'LDAP Auth: bind successful');
}
// Search for user
- if (($res_id = ldap_search($ldapconn, $ldap['basedn'], "uid=$username")) === FALSE)
- {
+ if (($res_id = ldap_search($ldapconn, $ldap['basedn'], "uid=$username")) === false) {
log_message('error', 'LDAP Auth: User '.$username.' not found in search');
- return FALSE;
+
+ return false;
}
- if (ldap_count_entries($ldapconn, $res_id) !== 1)
- {
+ if (ldap_count_entries($ldapconn, $res_id) !== 1) {
log_message('error', 'LDAP Auth: Failure, username '.$username.'found more than once');
- return FALSE;
+
+ return false;
}
- if (($entry_id = ldap_first_entry($ldapconn, $res_id)) === FALSE)
- {
+ if (($entry_id = ldap_first_entry($ldapconn, $res_id)) === false) {
log_message('error', 'LDAP Auth: Failure, entry of search result could not be fetched');
- return FALSE;
+
+ return false;
}
- if (($user_dn = ldap_get_dn($ldapconn, $entry_id)) === FALSE)
- {
+ if (($user_dn = ldap_get_dn($ldapconn, $entry_id)) === false) {
log_message('error', 'LDAP Auth: Failure, user-dn could not be fetched');
- return FALSE;
+
+ return false;
}
// User found, could not authenticate as user
- if (($link_id = ldap_bind($ldapconn, $user_dn, $password)) === FALSE)
- {
- log_message('error', 'LDAP Auth: Failure, username/password did not match: ' . $user_dn);
- return FALSE;
+ if (($link_id = ldap_bind($ldapconn, $user_dn, $password)) === false) {
+ log_message('error', 'LDAP Auth: Failure, username/password did not match: '.$user_dn);
+
+ return false;
}
log_message('debug', 'LDAP Auth: Success '.$user_dn.' authenticated successfully');
@@ -1904,42 +1629,41 @@ protected function _perform_ldap_auth($username = '', $password = NULL)
ldap_close($ldapconn);
- return TRUE;
+ return true;
}
/**
- * Perform Library Authentication - Override this function to change the way the library is called
+ * Perform Library Authentication - Override this function to change the way the library is called.
*
- * @access protected
* @param string $username The username to validate
* @param string $password The password to validate
+ *
* @return bool
*/
- protected function _perform_library_auth($username = '', $password = NULL)
+ protected function _perform_library_auth($username = '', $password = null)
{
- if (empty($username))
- {
+ if (empty($username)) {
log_message('error', 'Library Auth: Failure, empty username');
- return FALSE;
+
+ return false;
}
$auth_library_class = strtolower($this->config->item('auth_library_class'));
$auth_library_function = strtolower($this->config->item('auth_library_function'));
- if (empty($auth_library_class))
- {
+ if (empty($auth_library_class)) {
log_message('debug', 'Library Auth: Failure, empty auth_library_class');
- return FALSE;
+
+ return false;
}
- if (empty($auth_library_function))
- {
+ if (empty($auth_library_function)) {
log_message('debug', 'Library Auth: Failure, empty auth_library_function');
- return FALSE;
+
+ return false;
}
- if (is_callable([$auth_library_class, $auth_library_function]) === FALSE)
- {
+ if (is_callable([$auth_library_class, $auth_library_function]) === false) {
$this->load->library($auth_library_class);
}
@@ -1947,95 +1671,92 @@ protected function _perform_library_auth($username = '', $password = NULL)
}
/**
- * Check if the user is logged in
+ * Check if the user is logged in.
*
- * @access protected
- * @param string $username The user's name
+ * @param string $username The user's name
* @param bool|string $password The user's password
+ *
* @return bool
*/
- protected function _check_login($username = NULL, $password = FALSE)
+ protected function _check_login($username = null, $password = false)
{
- if (empty($username))
- {
- return FALSE;
+ if (empty($username)) {
+ return false;
}
$auth_source = strtolower($this->config->item('auth_source'));
$rest_auth = strtolower($this->config->item('rest_auth'));
$valid_logins = $this->config->item('rest_valid_logins');
- if ( ! $this->config->item('auth_source') && $rest_auth === 'digest')
- {
+ if (!$this->config->item('auth_source') && $rest_auth === 'digest') {
// For digest we do not have a password passed as argument
return md5($username.':'.$this->config->item('rest_realm').':'.(isset($valid_logins[$username]) ? $valid_logins[$username] : ''));
}
- if ($password === FALSE)
- {
- return FALSE;
+ if ($password === false) {
+ return false;
}
- if ($auth_source === 'ldap')
- {
+ if ($auth_source === 'ldap') {
log_message('debug', "Performing LDAP authentication for $username");
return $this->_perform_ldap_auth($username, $password);
}
- if ($auth_source === 'library')
- {
+ if ($auth_source === 'library') {
log_message('debug', "Performing Library authentication for $username");
return $this->_perform_library_auth($username, $password);
}
- if (array_key_exists($username, $valid_logins) === FALSE)
- {
- return FALSE;
+ if (array_key_exists($username, $valid_logins) === false) {
+ return false;
}
- if ($valid_logins[$username] !== $password)
- {
- return FALSE;
+ if ($valid_logins[$username] !== $password) {
+ return false;
}
- return TRUE;
+ return true;
}
/**
- * Check to see if the user is logged in with a PHP session key
+ * Check to see if the user is logged in with a PHP session key.
*
- * @access protected
* @return void
*/
protected function _check_php_session()
{
+ // If whitelist is enabled it has the first chance to kick them out
+ if ($this->config->item('rest_ip_whitelist_enabled')) {
+ $this->_check_whitelist_auth();
+ }
+
+ // Load library session of CodeIgniter
+ $this->load->library('session');
+
// Get the auth_source config item
$key = $this->config->item('auth_source');
// If false, then the user isn't logged in
- if ( ! $this->session->userdata($key))
- {
+ if (!$this->session->userdata($key)) {
// Display an error response
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unauthorized')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unauthorized'),
], self::HTTP_UNAUTHORIZED);
}
}
/**
- * Prepares for basic authentication
+ * Prepares for basic authentication.
*
- * @access protected
* @return void
*/
protected function _prepare_basic_auth()
{
// If whitelist is enabled it has the first chance to kick them out
- if ($this->config->item('rest_ip_whitelist_enabled'))
- {
+ if ($this->config->item('rest_ip_whitelist_enabled')) {
$this->_check_whitelist_auth();
}
@@ -2043,48 +1764,40 @@ protected function _prepare_basic_auth()
$username = $this->input->server('PHP_AUTH_USER');
$http_auth = $this->input->server('HTTP_AUTHENTICATION') ?: $this->input->server('HTTP_AUTHORIZATION');
- $password = NULL;
- if ($username !== NULL)
- {
+ $password = null;
+ if ($username !== null) {
$password = $this->input->server('PHP_AUTH_PW');
- }
- elseif ($http_auth !== NULL)
- {
+ } elseif ($http_auth !== null) {
// If the authentication header is set as basic, then extract the username and password from
// HTTP_AUTHORIZATION e.g. my_username:my_password. This is passed in the .htaccess file
- if (strpos(strtolower($http_auth), 'basic') === 0)
- {
+ if (strpos(strtolower($http_auth), 'basic') === 0) {
// Search online for HTTP_AUTHORIZATION workaround to explain what this is doing
list($username, $password) = explode(':', base64_decode(substr($this->input->server('HTTP_AUTHORIZATION'), 6)));
}
}
// Check if the user is logged into the system
- if ($this->_check_login($username, $password) === FALSE)
- {
+ if ($this->_check_login($username, $password) === false) {
$this->_force_login();
}
}
/**
- * Prepares for digest authentication
+ * Prepares for digest authentication.
*
- * @access protected
* @return void
*/
protected function _prepare_digest_auth()
{
// If whitelist is enabled it has the first chance to kick them out
- if ($this->config->item('rest_ip_whitelist_enabled'))
- {
+ if ($this->config->item('rest_ip_whitelist_enabled')) {
$this->_check_whitelist_auth();
}
// We need to test which server authentication variable to use,
// because the PHP ISAPI module in IIS acts different from CGI
$digest_string = $this->input->server('PHP_AUTH_DIGEST');
- if ($digest_string === NULL)
- {
+ if ($digest_string === null) {
$digest_string = $this->input->server('HTTP_AUTHORIZATION');
}
@@ -2092,8 +1805,7 @@ protected function _prepare_digest_auth()
// The $_SESSION['error_prompted'] variable is used to ask the password
// again if none given or if the user enters wrong auth information
- if (empty($digest_string))
- {
+ if (empty($digest_string)) {
$this->_force_login($unique_id);
}
@@ -2103,9 +1815,8 @@ protected function _prepare_digest_auth()
$digest = (empty($matches[1]) || empty($matches[2])) ? [] : array_combine($matches[1], $matches[2]);
// For digest authentication the library function should return already stored md5(username:restrealm:password) for that username see rest.php::auth_library_function config
- $username = $this->_check_login($digest['username'], TRUE);
- if (array_key_exists('username', $digest) === FALSE || $username === FALSE)
- {
+ $username = $this->_check_login($digest['username'], true);
+ if (isset($digest['username']) === false || $username === false) {
$this->_force_login($unique_id);
}
@@ -2113,20 +1824,18 @@ protected function _prepare_digest_auth()
$valid_response = md5($username.':'.$digest['nonce'].':'.$digest['nc'].':'.$digest['cnonce'].':'.$digest['qop'].':'.$md5);
// Check if the string don't compare (case-insensitive)
- if (strcasecmp($digest['response'], $valid_response) !== 0)
- {
+ if (strcasecmp($digest['response'], $valid_response) !== 0) {
// Display an error response
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_invalid_credentials')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_invalid_credentials'),
], self::HTTP_UNAUTHORIZED);
}
}
/**
- * Checks if the client's ip is in the 'rest_ip_blacklist' config and generates a 401 response
+ * Checks if the client's ip is in the 'rest_ip_blacklist' config and generates a 401 response.
*
- * @access protected
* @return void
*/
protected function _check_blacklist_auth()
@@ -2135,20 +1844,18 @@ protected function _check_blacklist_auth()
$pattern = sprintf('/(?:,\s*|^)\Q%s\E(?=,\s*|$)/m', $this->input->ip_address());
// Returns 1, 0 or FALSE (on error only). Therefore implicitly convert 1 to TRUE
- if (preg_match($pattern, $this->config->item('rest_ip_blacklist')))
- {
+ if (preg_match($pattern, $this->config->item('rest_ip_blacklist'))) {
// Display an error response
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_denied')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_denied'),
], self::HTTP_UNAUTHORIZED);
}
}
/**
- * Check if the client's ip is in the 'rest_ip_whitelist' config and generates a 401 response
+ * Check if the client's ip is in the 'rest_ip_whitelist' config and generates a 401 response.
*
- * @access protected
* @return void
*/
protected function _check_whitelist_auth()
@@ -2157,46 +1864,42 @@ protected function _check_whitelist_auth()
array_push($whitelist, '127.0.0.1', '0.0.0.0');
- foreach ($whitelist as &$ip)
- {
+ foreach ($whitelist as &$ip) {
// As $ip is a reference, trim leading and trailing whitespace, then store the new value
// using the reference
$ip = trim($ip);
}
- if (in_array($this->input->ip_address(), $whitelist) === FALSE)
- {
+ if (in_array($this->input->ip_address(), $whitelist) === false) {
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_unauthorized')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_ip_unauthorized'),
], self::HTTP_UNAUTHORIZED);
}
}
/**
- * Force logging in by setting the WWW-Authenticate header
+ * Force logging in by setting the WWW-Authenticate header.
*
- * @access protected
* @param string $nonce A server-specified data string which should be uniquely generated
- * each time
+ * each time
+ *
* @return void
*/
protected function _force_login($nonce = '')
{
- $rest_auth = $this->config->item('rest_auth');
+ $rest_auth = strtolower($this->config->item('rest_auth'));
$rest_realm = $this->config->item('rest_realm');
- if (strtolower($rest_auth) === 'basic')
- {
+ if ($rest_auth === 'basic') {
// See http://tools.ietf.org/html/rfc2617#page-5
header('WWW-Authenticate: Basic realm="'.$rest_realm.'"');
- }
- elseif (strtolower($rest_auth) === 'digest')
- {
+ } elseif ($rest_auth === 'digest') {
// See http://tools.ietf.org/html/rfc2617#page-18
header(
'WWW-Authenticate: Digest realm="'.$rest_realm
.'", qop="auth", nonce="'.$nonce
- .'", opaque="' . md5($rest_realm).'"');
+ .'", opaque="'.md5($rest_realm).'"'
+ );
}
if ($this->config->item('strict_api_and_auth') === true) {
@@ -2205,100 +1908,101 @@ protected function _force_login($nonce = '')
// Display an error response
$this->response([
- $this->config->item('rest_status_field_name') => FALSE,
- $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unauthorized')
+ $this->config->item('rest_status_field_name') => false,
+ $this->config->item('rest_message_field_name') => $this->lang->line('text_rest_unauthorized'),
], self::HTTP_UNAUTHORIZED);
}
/**
- * Updates the log table with the total access time
+ * Updates the log table with the total access time.
*
- * @access protected
* @author Chris Kacerguis
+ *
* @return bool TRUE log table updated; otherwise, FALSE
*/
protected function _log_access_time()
{
- if($this->_insert_id == ''){
+ if ($this->_insert_id == '') {
return false;
}
$payload['rtime'] = $this->_end_rtime - $this->_start_rtime;
return $this->rest->db->update(
- $this->config->item('rest_logs_table'), $payload, [
- 'id' => $this->_insert_id
- ]);
+ $this->config->item('rest_logs_table'),
+ $payload,
+ [
+ 'id' => $this->_insert_id,
+ ]
+ );
}
/**
- * Updates the log table with HTTP response code
+ * Updates the log table with HTTP response code.
*
- * @access protected
* @author Justin Chen
+ *
* @param $http_code int HTTP status code
+ *
* @return bool TRUE log table updated; otherwise, FALSE
*/
protected function _log_response_code($http_code)
{
- if($this->_insert_id == ''){
+ if ($this->_insert_id == '') {
return false;
}
$payload['response_code'] = $http_code;
return $this->rest->db->update(
- $this->config->item('rest_logs_table'), $payload, [
- 'id' => $this->_insert_id
- ]);
+ $this->config->item('rest_logs_table'),
+ $payload,
+ [
+ 'id' => $this->_insert_id,
+ ]
+ );
}
/**
- * Check to see if the API key has access to the controller and methods
+ * Check to see if the API key has access to the controller and methods.
*
- * @access protected
* @return bool TRUE the API key has access; otherwise, FALSE
*/
protected function _check_access()
{
// If we don't want to check access, just return TRUE
- if ($this->config->item('rest_enable_access') === FALSE)
- {
- return TRUE;
+ if ($this->config->item('rest_enable_access') === false) {
+ return true;
}
+ // Fetch controller based on path and controller name
+ $controller = implode(
+ '/',
+ [
+ $this->router->directory,
+ $this->router->class,
+ ]
+ );
+
+ // Remove any double slashes for safety
+ $controller = str_replace('//', '/', $controller);
+
//check if the key has all_access
$accessRow = $this->rest->db
->where('key', $this->rest->key)
+ ->where('controller', $controller)
->get($this->config->item('rest_access_table'))->row_array();
- if (!empty($accessRow) && !empty($accessRow['all_access']))
- {
- return TRUE;
+ if (!empty($accessRow) && !empty($accessRow['all_access'])) {
+ return true;
}
- // Fetch controller based on path and controller name
- $controller = implode(
- '/', [
- $this->router->directory,
- $this->router->class
- ]);
-
- // Remove any double slashes for safety
- $controller = str_replace('//', '/', $controller);
-
- // Query the access table and get the number of results
- return $this->rest->db
- ->where('key', $this->rest->key)
- ->where('controller', $controller)
- ->get($this->config->item('rest_access_table'))
- ->num_rows() > 0;
+ return false;
}
/**
- * Checks allowed domains, and adds appropriate headers for HTTP access control (CORS)
+ * Checks allowed domains, and adds appropriate headers for HTTP access control (CORS).
*
- * @access protected
* @return void
*/
protected function _check_cors()
@@ -2308,34 +2012,39 @@ protected function _check_cors()
$allowed_methods = implode(', ', $this->config->item('allowed_cors_methods'));
// If we want to allow any domain to access the API
- if ($this->config->item('allow_any_cors_domain') === TRUE)
- {
+ if ($this->config->item('allow_any_cors_domain') === true) {
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: '.$allowed_headers);
header('Access-Control-Allow-Methods: '.$allowed_methods);
- }
- else
- {
+ } else {
// We're going to allow only certain domains access
// Store the HTTP Origin header
$origin = $this->input->server('HTTP_ORIGIN');
- if ($origin === NULL)
- {
+ if ($origin === null) {
$origin = '';
}
// If the origin domain is in the allowed_cors_origins list, then add the Access Control headers
- if (in_array($origin, $this->config->item('allowed_cors_origins')))
- {
+ if (in_array($origin, $this->config->item('allowed_cors_origins'))) {
header('Access-Control-Allow-Origin: '.$origin);
header('Access-Control-Allow-Headers: '.$allowed_headers);
header('Access-Control-Allow-Methods: '.$allowed_methods);
}
}
+ // If there are headers that should be forced in the CORS check, add them now
+ if (is_array($this->config->item('forced_cors_headers'))) {
+ foreach ($this->config->item('forced_cors_headers') as $header => $value) {
+ header($header.': '.$value);
+ }
+ }
+
// If the request HTTP method is 'OPTIONS', kill the response and send it to the client
- if ($this->input->method() === 'options')
- {
+ if ($this->input->method() === 'options') {
+ // Load DB if needed for logging
+ if (!isset($this->rest->db) && $this->config->item('rest_enable_logging')) {
+ $this->rest->db = $this->load->database($this->config->item('rest_database_group'), true);
+ }
exit;
}
}
diff --git a/src/auth/apikey.php b/src/auth/apikey.php
new file mode 100644
index 00000000..e69de29b
diff --git a/src/auth/basic.php b/src/auth/basic.php
new file mode 100644
index 00000000..e69de29b
diff --git a/src/auth/ldap.php b/src/auth/ldap.php
new file mode 100644
index 00000000..e69de29b
diff --git a/application/language/serbian_lat/index.html b/src/index.html
old mode 100644
new mode 100755
similarity index 100%
rename from application/language/serbian_lat/index.html
rename to src/index.html
diff --git a/application/config/rest.php b/src/rest.php
similarity index 82%
rename from application/config/rest.php
rename to src/rest.php
index cdb92bf4..7c8c4c9b 100644
--- a/application/config/rest.php
+++ b/src/rest.php
@@ -1,6 +1,6 @@
method['METHOD_NAME']['limit'] = [NUM_REQUESTS_PER_HOUR];
+| $this->methods['METHOD_NAME']['limit'] = [NUM_REQUESTS_PER_HOUR];
|
| See application/controllers/api/example.php for examples
*/
-$config['rest_enable_limits'] = FALSE;
+$config['rest_enable_limits'] = false;
/*
|--------------------------------------------------------------------------
@@ -509,7 +585,7 @@
| Only do this if you are using the $this->rest_format or /format/xml in URLs
|
*/
-$config['rest_ignore_http_accept'] = FALSE;
+$config['rest_ignore_http_accept'] = false;
/*
|--------------------------------------------------------------------------
@@ -524,7 +600,7 @@
| Hint: This is good for production environments
|
*/
-$config['rest_ajax_only'] = FALSE;
+$config['rest_ajax_only'] = false;
/*
|--------------------------------------------------------------------------
@@ -546,7 +622,7 @@
| will access it through a browser
|
*/
-$config['check_cors'] = FALSE;
+$config['check_cors'] = false;
/*
|--------------------------------------------------------------------------
@@ -557,11 +633,11 @@
|
*/
$config['allowed_cors_headers'] = [
- 'Origin',
- 'X-Requested-With',
- 'Content-Type',
- 'Accept',
- 'Access-Control-Request-Method'
+ 'Origin',
+ 'X-Requested-With',
+ 'Content-Type',
+ 'Accept',
+ 'Access-Control-Request-Method',
];
/*
@@ -573,12 +649,12 @@
|
*/
$config['allowed_cors_methods'] = [
- 'GET',
- 'POST',
- 'OPTIONS',
- 'PUT',
- 'PATCH',
- 'DELETE'
+ 'GET',
+ 'POST',
+ 'OPTIONS',
+ 'PUT',
+ 'PATCH',
+ 'DELETE',
];
/*
@@ -590,7 +666,7 @@
| source domain
|
*/
-$config['allow_any_cors_domain'] = FALSE;
+$config['allow_any_cors_domain'] = false;
/*
|--------------------------------------------------------------------------
@@ -604,3 +680,24 @@
|
*/
$config['allowed_cors_origins'] = [];
+
+/*
+|--------------------------------------------------------------------------
+| CORS Forced Headers
+|--------------------------------------------------------------------------
+|
+| If using CORS checks, always include the headers and values specified here
+| in the OPTIONS client preflight.
+| Example:
+| $config['forced_cors_headers'] = [
+| 'Access-Control-Allow-Credentials' => 'true'
+| ];
+|
+| Added because of how Sencha Ext JS framework requires the header
+| Access-Control-Allow-Credentials to be set to true to allow the use of
+| credentials in the REST Proxy.
+| See documentation here:
+| http://docs.sencha.com/extjs/6.5.2/classic/Ext.data.proxy.Rest.html#cfg-withCredentials
+|
+*/
+$config['forced_cors_headers'] = [];