├── .codeclimate.yml ├── AUTHORS.md ├── CHANGELOG.md ├── LICENSE ├── README.md ├── application ├── config │ ├── config.php.sample │ ├── hooks.php │ ├── index.html │ ├── ldap.php │ ├── profiler.php │ ├── rest.php │ └── routes.php ├── controllers │ ├── Rest_server.php │ ├── Welcome.php │ ├── api │ │ ├── Example.php │ │ ├── Key.php │ │ └── index.html │ └── index.html ├── helpers │ ├── db_helper.php │ └── index.html ├── hooks │ └── hooks.profiler.php ├── language │ ├── bulgarian │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── dutch │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── english │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── french │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── german │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── greek │ │ └── rest_controller_lang.php │ ├── index.html │ ├── indonesia │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── italian │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── korean │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── portuguese-brazilian │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── romanian │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── serbian_cyr │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── serbian_lat │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── simplified-chinese │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── spanish │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── traditional-chinese │ │ ├── index.html │ │ └── rest_controller_lang.php │ └── turkish │ │ ├── index.html │ │ └── rest_controller_lang.php ├── libraries │ ├── Format.php │ ├── REST_Controller.php │ └── index.html ├── migrations │ ├── 20170706025420_create_table_users.php │ ├── 20170706030520_create_table_api_keys.php │ ├── 20170706031435_create_table_api_logs.php │ ├── 20170706032133_create_table_api_access.php │ ├── 20170706032825_create_table_api_limits.php │ └── index.html └── views │ ├── index.html │ ├── rest_server.php │ └── welcome_message.php ├── composer.json └── documentation ├── 404.html ├── class-Example.html ├── class-Format.html ├── class-Key.html ├── class-REST_Controller.html ├── class-Rest_server.html ├── class-Welcome.html ├── elementlist.js ├── index.html ├── package-CodeIgniter.Libraries.html ├── package-CodeIgniter.Rest.html ├── package-CodeIgniter.html ├── package-None.html ├── resources ├── collapsed.png ├── combined.js ├── footer.png ├── inherit.png ├── resize.png ├── sort.png ├── style.css ├── tree-cleaner.png ├── tree-hasnext.png ├── tree-last.png └── tree-vertical.png ├── source-class-Example.html ├── source-class-Format.html ├── source-class-Key.html ├── source-class-REST_Controller.html ├── source-class-Rest_server.html └── source-class-Welcome.html /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | exclude_paths: 2 | - "documentation/" 3 | - "application/language/" -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | # The Core Team 2 | 3 | * [Chris Kacerguis](//github.com/chriskacerguis) 4 | * [Phil Sturgeon](//github.com/philsturgeon) 5 | 6 | ### Special Thanks To 7 | 8 | * [Fabian Hanisch](//github.com/Hanisch-IT) 9 | 10 | *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.* 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Changelog: 2 | =========== 3 | 4 | ### UNRELEASED 5 | * Added support for CodeIgniter controller's index methods (index_GET, index_POST...) 6 | * Added exceptions handling when the method could not be found 7 | 8 | ### 2.7.2 9 | 10 | * Added $this->query() in which query parameters can now be obtained regardless of whether a GET request is sent or not 11 | * Added doc comments added to functions 12 | * Added HTTP status constants e.g. REST_Controller::HTTP_OK 13 | * Added new CSV formatting function 14 | * Fixed numerous bug fixes 15 | * Updated API calls limit can be based on API key, routed url or method name 16 | * Updated documentation 17 | * Updated examples (thanks @ivantcholakov and @lagaisse) 18 | * Updated many functions by re-writing (thanks @softwarespot) 19 | * Updated performance increase 20 | 21 | ### 2.7.0 22 | 23 | * Added Blacklist IP option 24 | * Added controller based access controls 25 | * Added support for OPTIONS, PATCH, and HEAD (from boh1996) 26 | * Added logging of the time it takes for a request (rtime column in DB) 27 | * Changed DB schemas to use InnoDB, not MyISAM 28 | * Updated Readme to reflect new developer (Chris Kacerguis) 29 | 30 | ### 2.6.2 31 | 32 | * Update CodeIgniter files to 2.1.3 33 | * Fixed issue #165 34 | 35 | ### 2.6.1 36 | 37 | * Update CodeIgniter files to 2.1.2 38 | * Log Table support for IPv6 & NULL parameters 39 | * Abstract out the processes of firing a controller method within _remap() to an separate method 40 | * Moved GET, POST, PUT, and DELETE parsing to separate methods, allowing them to be overridden as needed 41 | * Small bug-fix for a PHP 5.3 strlen error 42 | * Fixed some PHP 5.4 warnings 43 | * Fix for bug in Format.php's to_html() which failed to detect if $data was really a multidimensional array. 44 | * Fix for empty node on XML output format, for false = 0, true = 1. 45 | 46 | ### 2.6.0 47 | 48 | * Added loads of PHPDoc comments. 49 | * Response where method doesn't exist is now "HTTP 405 Method Not Allowed", not "HTTP 404 Not Found". 50 | * Compatible with PHP 5.4. 51 | * Added support for gzip compression. 52 | * Fix the apache\_request\_header function with CGI. 53 | * Fixed up correctly .foo extensions to work when get arguments provided. 54 | * Allows method emulation via X-HTTP-Method-Override 55 | * Support for Backbone.emulateHTTP improved. 56 | * Combine both URI segment and GET params instead of using one or the other 57 | * Separate each piece of the WWW-Authenticate header for digest requests with a comma. 58 | * Added IP white-list option. 59 | 60 | ### 2.5 61 | 62 | * Instead of just seeing item, item, item, the singular version of the base-node will be used if possible. [Example](http://d.pr/RS46). 63 | * Re-factored to use the Format library, which will soon be merged with CodeIgniter. 64 | * Fixed Limit bug (limit of 5 would allow 6 requests). 65 | * Added logging for invalid API key requests. 66 | * Changed serialize to serialized. 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2012 - 2015 Phil Sturgeon, Chris Kacerguis 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter Rest Server 2 | 3 | 4 | A fully RESTful server implementation for CodeIgniter using one library, one 5 | config file and one controller. 6 | 7 | ## Requirements 8 | 9 | 1. PHP 5.4 or greater 10 | 2. CodeIgniter 3.0+ 11 | -------------------------------------------------------------------------------- /application/config/config.php.sample: -------------------------------------------------------------------------------- 1 | ]+$/i 170 | | 171 | | DO NOT CHANGE THIS UNLESS YOU FULLY UNDERSTAND THE REPERCUSSIONS!! 172 | | 173 | | Note: This option is ignored for CLI requests. 174 | | 175 | */ 176 | $config['permitted_uri_chars'] = 'a-z 0-9~%.:_\-'; 177 | 178 | /* 179 | |-------------------------------------------------------------------------- 180 | | Enable Query Strings 181 | |-------------------------------------------------------------------------- 182 | | 183 | | By default CodeIgniter uses search-engine friendly segment based URLs: 184 | | example.com/who/what/where/ 185 | | 186 | | You can optionally enable standard query string based URLs: 187 | | example.com?who=me&what=something&where=here 188 | | 189 | | Options are: TRUE or FALSE (boolean) 190 | | 191 | | The other items let you set the query string 'words' that will 192 | | invoke your controllers and its functions: 193 | | example.com/index.php?c=controller&m=function 194 | | 195 | | Please note that some of the helpers won't work as expected when 196 | | this feature is enabled, since CodeIgniter is designed primarily to 197 | | use segment based URLs. 198 | | 199 | */ 200 | $config['enable_query_strings'] = FALSE; 201 | $config['controller_trigger'] = 'c'; 202 | $config['function_trigger'] = 'm'; 203 | $config['directory_trigger'] = 'd'; 204 | 205 | /* 206 | |-------------------------------------------------------------------------- 207 | | Error Logging Threshold 208 | |-------------------------------------------------------------------------- 209 | | 210 | | You can enable error logging by setting a threshold over zero. The 211 | | threshold determines what gets logged. Threshold options are: 212 | | 213 | | 0 = Disables logging, Error logging TURNED OFF 214 | | 1 = Error Messages (including PHP errors) 215 | | 2 = Debug Messages 216 | | 3 = Informational Messages 217 | | 4 = All Messages 218 | | 219 | | You can also pass an array with threshold levels to show individual error types 220 | | 221 | | array(2) = Debug Messages, without Error Messages 222 | | 223 | | For a live site you'll usually only enable Errors (1) to be logged otherwise 224 | | your log files will fill up very fast. 225 | | 226 | */ 227 | $config['log_threshold'] = 0; 228 | 229 | /* 230 | |-------------------------------------------------------------------------- 231 | | Error Logging Directory Path 232 | |-------------------------------------------------------------------------- 233 | | 234 | | Leave this BLANK unless you would like to set something other than the default 235 | | application/logs/ directory. Use a full server path. 236 | | 237 | */ 238 | $config['log_path'] = ''; 239 | 240 | /* 241 | |-------------------------------------------------------------------------- 242 | | Log File Extension 243 | |-------------------------------------------------------------------------- 244 | | 245 | | The default filename extension for log files. The default 'php' allows for 246 | | protecting the log files via basic scripting, when they are to be stored 247 | | under a publicly accessible directory. 248 | | 249 | | Note: Leaving it blank will default to 'php'. 250 | | 251 | */ 252 | $config['log_file_extension'] = ''; 253 | 254 | /* 255 | |-------------------------------------------------------------------------- 256 | | Log File Permissions 257 | |-------------------------------------------------------------------------- 258 | | 259 | | The file system permissions to be applied on newly created log files. 260 | | 261 | | IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal 262 | | integer notation (i.e. 0700, 0644, etc.) 263 | */ 264 | $config['log_file_permissions'] = 0644; 265 | 266 | /* 267 | |-------------------------------------------------------------------------- 268 | | Date Format for Logs 269 | |-------------------------------------------------------------------------- 270 | | 271 | | Each item that is logged has an associated date. You can use PHP date 272 | | codes to set your own date formatting 273 | | 274 | */ 275 | $config['log_date_format'] = 'Y-m-d H:i:s'; 276 | 277 | /* 278 | |-------------------------------------------------------------------------- 279 | | Error Views Directory Path 280 | |-------------------------------------------------------------------------- 281 | | 282 | | Leave this BLANK unless you would like to set something other than the default 283 | | application/views/errors/ directory. Use a full server path. 284 | | 285 | */ 286 | $config['error_views_path'] = ''; 287 | 288 | /* 289 | |-------------------------------------------------------------------------- 290 | | Cache Directory Path 291 | |-------------------------------------------------------------------------- 292 | | 293 | | Leave this BLANK unless you would like to set something other than the default 294 | | application/cache/ directory. Use a full server path. 295 | | 296 | */ 297 | $config['cache_path'] = ''; 298 | 299 | /* 300 | |-------------------------------------------------------------------------- 301 | | Cache Include Query String 302 | |-------------------------------------------------------------------------- 303 | | 304 | | Whether to take the URL query string into consideration when generating 305 | | output cache files. Valid options are: 306 | | 307 | | FALSE = Disabled 308 | | TRUE = Enabled, take all query parameters into account. 309 | | Please be aware that this may result in numerous cache 310 | | files generated for the same page over and over again. 311 | | array('q') = Enabled, but only take into account the specified list 312 | | of query parameters. 313 | | 314 | */ 315 | $config['cache_query_string'] = FALSE; 316 | 317 | /* 318 | |-------------------------------------------------------------------------- 319 | | Encryption Key 320 | |-------------------------------------------------------------------------- 321 | | 322 | | If you use the Encryption class, you must set an encryption key. 323 | | See the user guide for more info. 324 | | 325 | | https://codeigniter.com/user_guide/libraries/encryption.html 326 | | 327 | */ 328 | $config['encryption_key'] = ''; 329 | 330 | /* 331 | |-------------------------------------------------------------------------- 332 | | Session Variables 333 | |-------------------------------------------------------------------------- 334 | | 335 | | 'sess_driver' 336 | | 337 | | The storage driver to use: files, database, redis, memcached 338 | | 339 | | 'sess_cookie_name' 340 | | 341 | | The session cookie name, must contain only [0-9a-z_-] characters 342 | | 343 | | 'sess_expiration' 344 | | 345 | | The number of SECONDS you want the session to last. 346 | | Setting to 0 (zero) means expire when the browser is closed. 347 | | 348 | | 'sess_save_path' 349 | | 350 | | The location to save sessions to, driver dependent. 351 | | 352 | | For the 'files' driver, it's a path to a writable directory. 353 | | WARNING: Only absolute paths are supported! 354 | | 355 | | For the 'database' driver, it's a table name. 356 | | Please read up the manual for the format with other session drivers. 357 | | 358 | | IMPORTANT: You are REQUIRED to set a valid save path! 359 | | 360 | | 'sess_match_ip' 361 | | 362 | | Whether to match the user's IP address when reading the session data. 363 | | 364 | | WARNING: If you're using the database driver, don't forget to update 365 | | your session table's PRIMARY KEY when changing this setting. 366 | | 367 | | 'sess_time_to_update' 368 | | 369 | | How many seconds between CI regenerating the session ID. 370 | | 371 | | 'sess_regenerate_destroy' 372 | | 373 | | Whether to destroy session data associated with the old session ID 374 | | when auto-regenerating the session ID. When set to FALSE, the data 375 | | will be later deleted by the garbage collector. 376 | | 377 | | Other session cookie settings are shared with the rest of the application, 378 | | except for 'cookie_prefix' and 'cookie_httponly', which are ignored here. 379 | | 380 | */ 381 | $config['sess_driver'] = 'files'; 382 | $config['sess_cookie_name'] = 'ci_session'; 383 | $config['sess_expiration'] = 7200; 384 | $config['sess_save_path'] = NULL; 385 | $config['sess_match_ip'] = FALSE; 386 | $config['sess_time_to_update'] = 300; 387 | $config['sess_regenerate_destroy'] = FALSE; 388 | 389 | /* 390 | |-------------------------------------------------------------------------- 391 | | Cookie Related Variables 392 | |-------------------------------------------------------------------------- 393 | | 394 | | 'cookie_prefix' = Set a cookie name prefix if you need to avoid collisions 395 | | 'cookie_domain' = Set to .your-domain.com for site-wide cookies 396 | | 'cookie_path' = Typically will be a forward slash 397 | | 'cookie_secure' = Cookie will only be set if a secure HTTPS connection exists. 398 | | 'cookie_httponly' = Cookie will only be accessible via HTTP(S) (no javascript) 399 | | 400 | | Note: These settings (with the exception of 'cookie_prefix' and 401 | | 'cookie_httponly') will also affect sessions. 402 | | 403 | */ 404 | $config['cookie_prefix'] = ''; 405 | $config['cookie_domain'] = ''; 406 | $config['cookie_path'] = '/'; 407 | $config['cookie_secure'] = FALSE; 408 | $config['cookie_httponly'] = FALSE; 409 | 410 | /* 411 | |-------------------------------------------------------------------------- 412 | | Cross Site Request Forgery 413 | |-------------------------------------------------------------------------- 414 | | Enables a CSRF cookie token to be set. When set to TRUE, token will be 415 | | checked on a submitted form. If you are accepting user data, it is strongly 416 | | recommended CSRF protection be enabled. 417 | | 418 | | 'csrf_token_name' = The token name 419 | | 'csrf_cookie_name' = The cookie name 420 | | 'csrf_expire' = The number in seconds the token should expire. 421 | | 'csrf_regenerate' = Regenerate token on every submission 422 | | 'csrf_exclude_uris' = Array of URIs which ignore CSRF checks 423 | */ 424 | $config['csrf_protection'] = FALSE; 425 | $config['csrf_token_name'] = 'csrf_test_name'; 426 | $config['csrf_cookie_name'] = 'csrf_cookie_name'; 427 | $config['csrf_expire'] = 7200; 428 | $config['csrf_regenerate'] = TRUE; 429 | $config['csrf_exclude_uris'] = array(); 430 | 431 | /* 432 | |-------------------------------------------------------------------------- 433 | | Output Compression 434 | |-------------------------------------------------------------------------- 435 | | 436 | | Enables Gzip output compression for faster page loads. When enabled, 437 | | the output class will test whether your server supports Gzip. 438 | | Even if it does, however, not all browsers support compression 439 | | so enable only if you are reasonably sure your visitors can handle it. 440 | | 441 | | Only used if zlib.output_compression is turned off in your php.ini. 442 | | Please do not use it together with httpd-level output compression. 443 | | 444 | | VERY IMPORTANT: If you are getting a blank page when compression is enabled it 445 | | means you are prematurely outputting something to your browser. It could 446 | | even be a line of whitespace at the end of one of your scripts. For 447 | | compression to work, nothing can be sent before the output buffer is called 448 | | by the output class. Do not 'echo' any values with compression enabled. 449 | | 450 | */ 451 | $config['compress_output'] = FALSE; 452 | 453 | /* 454 | |-------------------------------------------------------------------------- 455 | | Master Time Reference 456 | |-------------------------------------------------------------------------- 457 | | 458 | | Options are 'local' or any PHP supported timezone. This preference tells 459 | | the system whether to use your server's local time as the master 'now' 460 | | reference, or convert it to the configured one timezone. See the 'date 461 | | helper' page of the user guide for information regarding date handling. 462 | | 463 | */ 464 | $config['time_reference'] = 'local'; 465 | 466 | /* 467 | |-------------------------------------------------------------------------- 468 | | Reverse Proxy IPs 469 | |-------------------------------------------------------------------------- 470 | | 471 | | If your server is behind a reverse proxy, you must whitelist the proxy 472 | | IP addresses from which CodeIgniter should trust headers such as 473 | | HTTP_X_FORWARDED_FOR and HTTP_CLIENT_IP in order to properly identify 474 | | the visitor's IP address. 475 | | 476 | | You can use both an array or a comma-separated list of proxy addresses, 477 | | as well as specifying whole subnets. Here are a few examples: 478 | | 479 | | Comma-separated: '10.0.1.200,192.168.5.0/24' 480 | | Array: array('10.0.1.200', '192.168.5.0/24') 481 | */ 482 | $config['proxy_ips'] = ''; 483 | -------------------------------------------------------------------------------- /application/config/hooks.php: -------------------------------------------------------------------------------- 1 | 'ProfilerEnabler', 17 | 'function' => 'enableProfiler', 18 | 'filename' => 'hooks.profiler.php', 19 | 'filepath' => 'hooks', 20 | 'params' => array() 21 | ); -------------------------------------------------------------------------------- /application/config/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/config/ldap.php: -------------------------------------------------------------------------------- 1 | my_controller/index 50 | | my-controller/my-method -> my_controller/my_method 51 | */ 52 | $route['default_controller'] = 'welcome'; 53 | $route['404_override'] = ''; 54 | $route['translate_uri_dashes'] = TRUE; 55 | 56 | /* 57 | | ------------------------------------------------------------------------- 58 | | Sample REST API Routes 59 | | ------------------------------------------------------------------------- 60 | */ 61 | $route['api/example/users/(:num)'] = 'api/example/users/id/$1'; // Example 4 62 | $route['api/example/users/(:num)(\.)([a-zA-Z0-9_-]+)(.*)'] = 'api/example/users/id/$1/format/$3$4'; // Example 8 63 | -------------------------------------------------------------------------------- /application/controllers/Rest_server.php: -------------------------------------------------------------------------------- 1 | load->helper('url'); 10 | 11 | $this->load->view('rest_server'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /application/controllers/Welcome.php: -------------------------------------------------------------------------------- 1 | 19 | * @see https://codeigniter.com/user_guide/general/urls.html 20 | */ 21 | public function index() 22 | { 23 | $this->load->helper('url'); 24 | 25 | $this->load->view('welcome_message'); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /application/controllers/api/Example.php: -------------------------------------------------------------------------------- 1 | methods['users_get']['limit'] = 500; // 500 requests per hour per user/key 32 | $this->methods['users_post']['limit'] = 100; // 100 requests per hour per user/key 33 | $this->methods['users_delete']['limit'] = 50; // 50 requests per hour per user/key 34 | } 35 | 36 | public function users_get() 37 | { 38 | // Users from a data store e.g. database 39 | $users = [ 40 | ['id' => 1, 'name' => 'John', 'email' => 'john@example.com', 'fact' => 'Loves coding'], 41 | ['id' => 2, 'name' => 'Jim', 'email' => 'jim@example.com', 'fact' => 'Developed on CodeIgniter'], 42 | ['id' => 3, 'name' => 'Jane', 'email' => 'jane@example.com', 'fact' => 'Lives in the USA', ['hobbies' => ['guitar', 'cycling']]], 43 | ]; 44 | 45 | $id = $this->get('id'); 46 | 47 | // If the id parameter doesn't exist return all the users 48 | 49 | if ($id === NULL) 50 | { 51 | // Check if the users data store contains users (in case the database result returns NULL) 52 | if ($users) 53 | { 54 | // Set the response and exit 55 | $this->response($users, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 56 | } 57 | else 58 | { 59 | // Set the response and exit 60 | $this->response([ 61 | 'status' => FALSE, 62 | 'message' => 'No users were found' 63 | ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code 64 | } 65 | } 66 | 67 | // Find and return a single record for a particular user. 68 | 69 | $id = (int) $id; 70 | 71 | // Validate the id. 72 | if ($id <= 0) 73 | { 74 | // Invalid id, set the response and exit. 75 | $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 76 | } 77 | 78 | // Get the user from the array, using the id as key for retrieval. 79 | // Usually a model is to be used for this. 80 | 81 | $user = NULL; 82 | 83 | if (!empty($users)) 84 | { 85 | foreach ($users as $key => $value) 86 | { 87 | if (isset($value['id']) && $value['id'] === $id) 88 | { 89 | $user = $value; 90 | } 91 | } 92 | } 93 | 94 | if (!empty($user)) 95 | { 96 | $this->set_response($user, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 97 | } 98 | else 99 | { 100 | $this->set_response([ 101 | 'status' => FALSE, 102 | 'message' => 'User could not be found' 103 | ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code 104 | } 105 | } 106 | 107 | public function users_post() 108 | { 109 | // $this->some_model->update_user( ... ); 110 | $message = [ 111 | 'id' => 100, // Automatically generated by the model 112 | 'name' => $this->post('name'), 113 | 'email' => $this->post('email'), 114 | 'message' => 'Added a resource' 115 | ]; 116 | 117 | $this->set_response($message, REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code 118 | } 119 | 120 | public function users_delete() 121 | { 122 | $id = (int) $this->get('id'); 123 | 124 | // Validate the id. 125 | if ($id <= 0) 126 | { 127 | // Set the response and exit 128 | $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 129 | } 130 | 131 | // $this->some_model->delete_something($id); 132 | $message = [ 133 | 'id' => $id, 134 | 'message' => 'Deleted the resource' 135 | ]; 136 | 137 | $this->set_response($message, REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code 138 | } 139 | 140 | } 141 | -------------------------------------------------------------------------------- /application/controllers/api/Key.php: -------------------------------------------------------------------------------- 1 | ['level' => 10, 'limit' => 10], 25 | 'index_delete' => ['level' => 10], 26 | 'level_post' => ['level' => 10], 27 | 'regenerate_post' => ['level' => 10], 28 | ]; 29 | 30 | /** 31 | * Insert a key into the database 32 | * 33 | * @access public 34 | * @return void 35 | */ 36 | public function index_put() 37 | { 38 | // Build a new key 39 | $key = $this->_generate_key(); 40 | 41 | // If no key level provided, provide a generic key 42 | $level = $this->put('level') ? $this->put('level') : 1; 43 | $ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1; 44 | 45 | // Insert the new key 46 | if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits])) 47 | { 48 | $this->response([ 49 | 'status' => TRUE, 50 | 'key' => $key 51 | ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code 52 | } 53 | else 54 | { 55 | $this->response([ 56 | 'status' => FALSE, 57 | 'message' => 'Could not save the key' 58 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 59 | } 60 | } 61 | 62 | /** 63 | * Remove a key from the database to stop it working 64 | * 65 | * @access public 66 | * @return void 67 | */ 68 | public function index_delete() 69 | { 70 | $key = $this->delete('key'); 71 | 72 | // Does this key exist? 73 | if (!$this->_key_exists($key)) 74 | { 75 | // It doesn't appear the key exists 76 | $this->response([ 77 | 'status' => FALSE, 78 | 'message' => 'Invalid API key' 79 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 80 | } 81 | 82 | // Destroy it 83 | $this->_delete_key($key); 84 | 85 | // Respond that the key was destroyed 86 | $this->response([ 87 | 'status' => TRUE, 88 | 'message' => 'API key was deleted' 89 | ], REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code 90 | } 91 | 92 | /** 93 | * Change the level 94 | * 95 | * @access public 96 | * @return void 97 | */ 98 | public function level_post() 99 | { 100 | $key = $this->post('key'); 101 | $new_level = $this->post('level'); 102 | 103 | // Does this key exist? 104 | if (!$this->_key_exists($key)) 105 | { 106 | // It doesn't appear the key exists 107 | $this->response([ 108 | 'status' => FALSE, 109 | 'message' => 'Invalid API key' 110 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 111 | } 112 | 113 | // Update the key level 114 | if ($this->_update_key($key, ['level' => $new_level])) 115 | { 116 | $this->response([ 117 | 'status' => TRUE, 118 | 'message' => 'API key was updated' 119 | ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 120 | } 121 | else 122 | { 123 | $this->response([ 124 | 'status' => FALSE, 125 | 'message' => 'Could not update the key level' 126 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 127 | } 128 | } 129 | 130 | /** 131 | * Suspend a key 132 | * 133 | * @access public 134 | * @return void 135 | */ 136 | public function suspend_post() 137 | { 138 | $key = $this->post('key'); 139 | 140 | // Does this key exist? 141 | if (!$this->_key_exists($key)) 142 | { 143 | // It doesn't appear the key exists 144 | $this->response([ 145 | 'status' => FALSE, 146 | 'message' => 'Invalid API key' 147 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 148 | } 149 | 150 | // Update the key level 151 | if ($this->_update_key($key, ['level' => 0])) 152 | { 153 | $this->response([ 154 | 'status' => TRUE, 155 | 'message' => 'Key was suspended' 156 | ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 157 | } 158 | else 159 | { 160 | $this->response([ 161 | 'status' => FALSE, 162 | 'message' => 'Could not suspend the user' 163 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 164 | } 165 | } 166 | 167 | /** 168 | * Regenerate a key 169 | * 170 | * @access public 171 | * @return void 172 | */ 173 | public function regenerate_post() 174 | { 175 | $old_key = $this->post('key'); 176 | $key_details = $this->_get_key($old_key); 177 | 178 | // Does this key exist? 179 | if (!$key_details) 180 | { 181 | // It doesn't appear the key exists 182 | $this->response([ 183 | 'status' => FALSE, 184 | 'message' => 'Invalid API key' 185 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 186 | } 187 | 188 | // Build a new key 189 | $new_key = $this->_generate_key(); 190 | 191 | // Insert the new key 192 | if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits])) 193 | { 194 | // Suspend old key 195 | $this->_update_key($old_key, ['level' => 0]); 196 | 197 | $this->response([ 198 | 'status' => TRUE, 199 | 'key' => $new_key 200 | ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code 201 | } 202 | else 203 | { 204 | $this->response([ 205 | 'status' => FALSE, 206 | 'message' => 'Could not save the key' 207 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 208 | } 209 | } 210 | 211 | /* Helper Methods */ 212 | 213 | private function _generate_key() 214 | { 215 | do 216 | { 217 | // Generate a random salt 218 | $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36); 219 | 220 | // If an error occurred, then fall back to the previous method 221 | if ($salt === FALSE) 222 | { 223 | $salt = hash('sha256', time() . mt_rand()); 224 | } 225 | 226 | $new_key = substr($salt, 0, config_item('rest_key_length')); 227 | } 228 | while ($this->_key_exists($new_key)); 229 | 230 | return $new_key; 231 | } 232 | 233 | /* Private Data Methods */ 234 | 235 | private function _get_key($key) 236 | { 237 | return $this->rest->db 238 | ->where(config_item('rest_key_column'), $key) 239 | ->get(config_item('rest_keys_table')) 240 | ->row(); 241 | } 242 | 243 | private function _key_exists($key) 244 | { 245 | return $this->rest->db 246 | ->where(config_item('rest_key_column'), $key) 247 | ->count_all_results(config_item('rest_keys_table')) > 0; 248 | } 249 | 250 | private function _insert_key($key, $data) 251 | { 252 | $data[config_item('rest_key_column')] = $key; 253 | $data['date_created'] = function_exists('now') ? now() : time(); 254 | 255 | return $this->rest->db 256 | ->set($data) 257 | ->insert(config_item('rest_keys_table')); 258 | } 259 | 260 | private function _update_key($key, $data) 261 | { 262 | return $this->rest->db 263 | ->where(config_item('rest_key_column'), $key) 264 | ->update(config_item('rest_keys_table'), $data); 265 | } 266 | 267 | private function _delete_key($key) 268 | { 269 | return $this->rest->db 270 | ->where(config_item('rest_key_column'), $key) 271 | ->delete(config_item('rest_keys_table')); 272 | } 273 | 274 | } 275 | -------------------------------------------------------------------------------- /application/controllers/api/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/controllers/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/helpers/db_helper.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | defined('BASEPATH') OR exit('No direct script access allowed'); 6 | 7 | if ( ! function_exists('add_foreign_key')) 8 | { 9 | /** 10 | * @param string $table Table name 11 | * @param string $foreign_key Collumn name having the Foreign Key 12 | * @param string $references Table and column reference. Ex: users(id) 13 | * @param string $on_delete RESTRICT, NO ACTION, CASCADE, SET NULL, SET DEFAULT 14 | * @param string $on_update RESTRICT, NO ACTION, CASCADE, SET NULL, SET DEFAULT 15 | * 16 | * @return string SQL command 17 | */ 18 | function add_foreign_key($table, $foreign_key, $references, $on_delete = 'RESTRICT', $on_update = 'RESTRICT') 19 | { 20 | $references = explode('(', str_replace(')', '', str_replace('`', '', $references))); 21 | 22 | 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}"; 23 | } 24 | } 25 | 26 | if ( ! function_exists('drop_foreign_key')) 27 | { 28 | /** 29 | * @param string $table Table name 30 | * @param string $foreign_key Collumn name having the Foreign Key 31 | * 32 | * @return string SQL command 33 | */ 34 | function drop_foreign_key($table, $foreign_key) 35 | { 36 | return "ALTER TABLE `{$table}` DROP FOREIGN KEY `{$table}_{$foreign_key}_fk`"; 37 | } 38 | } 39 | 40 | if ( ! function_exists('add_trigger')) 41 | { 42 | /** 43 | * @param string $trigger_name Trigger name 44 | * @param string $table Table name 45 | * @param string $statement Command to run 46 | * @param string $time BEFORE or AFTER 47 | * @param string $event INSERT, UPDATE or DELETE 48 | * @param string $type FOR EACH ROW [FOLLOWS|PRECEDES] 49 | * 50 | * @return string SQL Command 51 | */ 52 | function add_trigger($trigger_name, $table, $statement, $time = 'BEFORE', $event = 'INSERT', $type = 'FOR EACH ROW') 53 | { 54 | 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 ;;'; 55 | } 56 | } 57 | 58 | if ( ! function_exists('drop_trigger')) 59 | { 60 | /** 61 | * @param string $trigger_name Trigger name 62 | * 63 | * @return string SQL Command 64 | */ 65 | function drop_trigger($trigger_name) 66 | { 67 | return "DROP TRIGGER {$trigger_name};"; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /application/helpers/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/hooks/hooks.profiler.php: -------------------------------------------------------------------------------- 1 | output->enable_profiler( config_item('enable_profiling') ); 16 | } 17 | } 18 | ?> 19 | -------------------------------------------------------------------------------- /application/language/bulgarian/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/bulgarian/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/dutch/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/english/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/french/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/german/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/indonesia/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/indonesia/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/italian/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/korean/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/portuguese-brazilian/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/romanian/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/serbian_cyr/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/serbian_lat/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/simplified-chinese/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/spanish/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/traditional-chinese/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/turkish/rest_controller_lang.php: -------------------------------------------------------------------------------- 1 | _CI = &get_instance(); 89 | 90 | // Load the inflector helper 91 | $this->_CI->load->helper('inflector'); 92 | 93 | // If the provided data is already formatted we should probably convert it to an array 94 | if ($from_type !== NULL) 95 | { 96 | if (method_exists($this, '_from_'.$from_type)) 97 | { 98 | $data = call_user_func([$this, '_from_'.$from_type], $data); 99 | } 100 | else 101 | { 102 | throw new Exception('Format class does not support conversion from "'.$from_type.'".'); 103 | } 104 | } 105 | 106 | // Set the member variable to the data passed 107 | $this->_data = $data; 108 | } 109 | 110 | /** 111 | * Create an instance of the format class 112 | * e.g: echo $this->format->factory(['foo' => 'bar'])->to_csv(); 113 | * 114 | * @param mixed $data Data to convert/parse 115 | * @param string $from_type Type to convert from e.g. json, csv, html 116 | * 117 | * @return object Instance of the format class 118 | */ 119 | public static function factory($data, $from_type = NULL) 120 | { 121 | // $class = __CLASS__; 122 | // return new $class(); 123 | 124 | return new static($data, $from_type); 125 | } 126 | 127 | // FORMATTING OUTPUT --------------------------------------------------------- 128 | 129 | /** 130 | * Format data as an array 131 | * 132 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 133 | * to the constructor 134 | * @return array Data parsed as an array; otherwise, an empty array 135 | */ 136 | public function to_array($data = NULL) 137 | { 138 | // If no data is passed as a parameter, then use the data passed 139 | // via the constructor 140 | if ($data === NULL && func_num_args() === 0) 141 | { 142 | $data = $this->_data; 143 | } 144 | 145 | // Cast as an array if not already 146 | if (is_array($data) === FALSE) 147 | { 148 | $data = (array) $data; 149 | } 150 | 151 | $array = []; 152 | foreach ((array) $data as $key => $value) 153 | { 154 | if (is_object($value) === TRUE || is_array($value) === TRUE) 155 | { 156 | $array[$key] = $this->to_array($value); 157 | } 158 | else 159 | { 160 | $array[$key] = $value; 161 | } 162 | } 163 | 164 | return $array; 165 | } 166 | 167 | /** 168 | * Format data as XML 169 | * 170 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 171 | * to the constructor 172 | * @param NULL $structure 173 | * @param string $basenode 174 | * @return mixed 175 | */ 176 | public function to_xml($data = NULL, $structure = NULL, $basenode = 'xml') 177 | { 178 | if ($data === NULL && func_num_args() === 0) 179 | { 180 | $data = $this->_data; 181 | } 182 | 183 | if ($structure === NULL) 184 | { 185 | $structure = simplexml_load_string("<$basenode />"); 186 | } 187 | 188 | // Force it to be something useful 189 | if (is_array($data) === FALSE && is_object($data) === FALSE) 190 | { 191 | $data = (array) $data; 192 | } 193 | 194 | foreach ($data as $key => $value) 195 | { 196 | 197 | //change false/true to 0/1 198 | if (is_bool($value)) 199 | { 200 | $value = (int) $value; 201 | } 202 | 203 | // no numeric keys in our xml please! 204 | if (is_numeric($key)) 205 | { 206 | // make string key... 207 | $key = (singular($basenode) != $basenode) ? singular($basenode) : 'item'; 208 | } 209 | 210 | // replace anything not alpha numeric 211 | $key = preg_replace('/[^a-z_\-0-9]/i', '', $key); 212 | 213 | if ($key === '_attributes' && (is_array($value) || is_object($value))) 214 | { 215 | $attributes = $value; 216 | if (is_object($attributes)) 217 | { 218 | $attributes = get_object_vars($attributes); 219 | } 220 | 221 | foreach ($attributes as $attribute_name => $attribute_value) 222 | { 223 | $structure->addAttribute($attribute_name, $attribute_value); 224 | } 225 | } 226 | // if there is another array found recursively call this function 227 | elseif (is_array($value) || is_object($value)) 228 | { 229 | $node = $structure->addChild($key); 230 | 231 | // recursive call. 232 | $this->to_xml($value, $node, $key); 233 | } 234 | else 235 | { 236 | // add single node. 237 | $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'); 238 | 239 | $structure->addChild($key, $value); 240 | } 241 | } 242 | 243 | return $structure->asXML(); 244 | } 245 | 246 | /** 247 | * Format data as HTML 248 | * 249 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 250 | * to the constructor 251 | * @return mixed 252 | */ 253 | public function to_html($data = NULL) 254 | { 255 | // If no data is passed as a parameter, then use the data passed 256 | // via the constructor 257 | if ($data === NULL && func_num_args() === 0) 258 | { 259 | $data = $this->_data; 260 | } 261 | 262 | // Cast as an array if not already 263 | if (is_array($data) === FALSE) 264 | { 265 | $data = (array) $data; 266 | } 267 | 268 | // Check if it's a multi-dimensional array 269 | if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) 270 | { 271 | // Multi-dimensional array 272 | $headings = array_keys($data[0]); 273 | } 274 | else 275 | { 276 | // Single array 277 | $headings = array_keys($data); 278 | $data = [$data]; 279 | } 280 | 281 | // Load the table library 282 | $this->_CI->load->library('table'); 283 | 284 | $this->_CI->table->set_heading($headings); 285 | 286 | foreach ($data as $row) 287 | { 288 | // Suppressing the "array to string conversion" notice 289 | // Keep the "evil" @ here 290 | $row = @array_map('strval', $row); 291 | 292 | $this->_CI->table->add_row($row); 293 | } 294 | 295 | return $this->_CI->table->generate(); 296 | } 297 | 298 | /** 299 | * @link http://www.metashock.de/2014/02/create-csv-file-in-memory-php/ 300 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 301 | * to the constructor 302 | * @param string $delimiter The optional delimiter parameter sets the field 303 | * delimiter (one character only). NULL will use the default value (,) 304 | * @param string $enclosure The optional enclosure parameter sets the field 305 | * enclosure (one character only). NULL will use the default value (") 306 | * @return string A csv string 307 | */ 308 | public function to_csv($data = NULL, $delimiter = ',', $enclosure = '"') 309 | { 310 | // Use a threshold of 1 MB (1024 * 1024) 311 | $handle = fopen('php://temp/maxmemory:1048576', 'w'); 312 | if ($handle === FALSE) 313 | { 314 | return NULL; 315 | } 316 | 317 | // If no data is passed as a parameter, then use the data passed 318 | // via the constructor 319 | if ($data === NULL && func_num_args() === 0) 320 | { 321 | $data = $this->_data; 322 | } 323 | 324 | // If NULL, then set as the default delimiter 325 | if ($delimiter === NULL) 326 | { 327 | $delimiter = ','; 328 | } 329 | 330 | // If NULL, then set as the default enclosure 331 | if ($enclosure === NULL) 332 | { 333 | $enclosure = '"'; 334 | } 335 | 336 | // Cast as an array if not already 337 | if (is_array($data) === FALSE) 338 | { 339 | $data = (array) $data; 340 | } 341 | 342 | // Check if it's a multi-dimensional array 343 | if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) 344 | { 345 | // Multi-dimensional array 346 | $headings = array_keys($data[0]); 347 | } 348 | else 349 | { 350 | // Single array 351 | $headings = array_keys($data); 352 | $data = [$data]; 353 | } 354 | 355 | // Apply the headings 356 | fputcsv($handle, $headings, $delimiter, $enclosure); 357 | 358 | foreach ($data as $record) 359 | { 360 | // If the record is not an array, then break. This is because the 2nd param of 361 | // fputcsv() should be an array 362 | if (is_array($record) === FALSE) 363 | { 364 | break; 365 | } 366 | 367 | // Suppressing the "array to string conversion" notice. 368 | // Keep the "evil" @ here. 369 | $record = @ array_map('strval', $record); 370 | 371 | // Returns the length of the string written or FALSE 372 | fputcsv($handle, $record, $delimiter, $enclosure); 373 | } 374 | 375 | // Reset the file pointer 376 | rewind($handle); 377 | 378 | // Retrieve the csv contents 379 | $csv = stream_get_contents($handle); 380 | 381 | // Close the handle 382 | fclose($handle); 383 | 384 | // Convert UTF-8 encoding to UTF-16LE which is supported by MS Excel 385 | $csv = mb_convert_encoding($csv, 'UTF-16LE', 'UTF-8'); 386 | 387 | return $csv; 388 | } 389 | 390 | /** 391 | * Encode data as json 392 | * 393 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 394 | * to the constructor 395 | * @return string Json representation of a value 396 | */ 397 | public function to_json($data = NULL) 398 | { 399 | // If no data is passed as a parameter, then use the data passed 400 | // via the constructor 401 | if ($data === NULL && func_num_args() === 0) 402 | { 403 | $data = $this->_data; 404 | } 405 | 406 | // Get the callback parameter (if set) 407 | $callback = $this->_CI->input->get('callback'); 408 | 409 | if (empty($callback) === TRUE) 410 | { 411 | return json_encode($data, JSON_UNESCAPED_UNICODE); 412 | } 413 | 414 | // We only honour a jsonp callback which are valid javascript identifiers 415 | elseif (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback)) 416 | { 417 | // Return the data as encoded json with a callback 418 | return $callback.'('.json_encode($data, JSON_UNESCAPED_UNICODE).');'; 419 | } 420 | 421 | // An invalid jsonp callback function provided. 422 | // Though I don't believe this should be hardcoded here 423 | $data['warning'] = 'INVALID JSONP CALLBACK: '.$callback; 424 | 425 | return json_encode($data, JSON_UNESCAPED_UNICODE); 426 | } 427 | 428 | /** 429 | * Encode data as a serialized array 430 | * 431 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 432 | * to the constructor 433 | * @return string Serialized data 434 | */ 435 | public function to_serialized($data = NULL) 436 | { 437 | // If no data is passed as a parameter, then use the data passed 438 | // via the constructor 439 | if ($data === NULL && func_num_args() === 0) 440 | { 441 | $data = $this->_data; 442 | } 443 | 444 | return serialize($data); 445 | } 446 | 447 | /** 448 | * Format data using a PHP structure 449 | * 450 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 451 | * to the constructor 452 | * @return mixed String representation of a variable 453 | */ 454 | public function to_php($data = NULL) 455 | { 456 | // If no data is passed as a parameter, then use the data passed 457 | // via the constructor 458 | if ($data === NULL && func_num_args() === 0) 459 | { 460 | $data = $this->_data; 461 | } 462 | 463 | return var_export($data, TRUE); 464 | } 465 | 466 | // INTERNAL FUNCTIONS 467 | 468 | /** 469 | * @param string $data XML string 470 | * @return array XML element object; otherwise, empty array 471 | */ 472 | protected function _from_xml($data) 473 | { 474 | return $data ? (array) simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA) : []; 475 | } 476 | 477 | /** 478 | * @param string $data CSV string 479 | * @param string $delimiter The optional delimiter parameter sets the field 480 | * delimiter (one character only). NULL will use the default value (,) 481 | * @param string $enclosure The optional enclosure parameter sets the field 482 | * enclosure (one character only). NULL will use the default value (") 483 | * @return array A multi-dimensional array with the outer array being the number of rows 484 | * and the inner arrays the individual fields 485 | */ 486 | protected function _from_csv($data, $delimiter = ',', $enclosure = '"') 487 | { 488 | // If NULL, then set as the default delimiter 489 | if ($delimiter === NULL) 490 | { 491 | $delimiter = ','; 492 | } 493 | 494 | // If NULL, then set as the default enclosure 495 | if ($enclosure === NULL) 496 | { 497 | $enclosure = '"'; 498 | } 499 | 500 | return str_getcsv($data, $delimiter, $enclosure); 501 | } 502 | 503 | /** 504 | * @param string $data Encoded json string 505 | * @return mixed Decoded json string with leading and trailing whitespace removed 506 | */ 507 | protected function _from_json($data) 508 | { 509 | return json_decode(trim($data)); 510 | } 511 | 512 | /** 513 | * @param string $data Data to unserialize 514 | * @return mixed Unserialized data 515 | */ 516 | protected function _from_serialize($data) 517 | { 518 | return unserialize(trim($data)); 519 | } 520 | 521 | /** 522 | * @param string $data Data to trim leading and trailing whitespace 523 | * @return string Data with leading and trailing whitespace removed 524 | */ 525 | protected function _from_php($data) 526 | { 527 | return trim($data); 528 | } 529 | } 530 | -------------------------------------------------------------------------------- /application/libraries/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/migrations/20170706025420_create_table_users.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | defined('BASEPATH') OR exit('No direct script access allowed'); 6 | 7 | /** 8 | * Class Migration_create_table_users 9 | * 10 | * @property CI_DB_forge $dbforge 11 | * @property CI_DB_query_builder $db 12 | */ 13 | class Migration_create_table_users extends CI_Migration { 14 | 15 | 16 | protected $table = 'users'; 17 | 18 | 19 | public function up() 20 | { 21 | $fields = array( 22 | 'id' => [ 23 | 'type' => 'INT(11)', 24 | 'auto_increment' => TRUE, 25 | 'unsigned' => TRUE, 26 | ], 27 | 'email' => [ 28 | 'type' => 'VARCHAR(255)', 29 | 'unique' => TRUE, 30 | ], 31 | 'password' => [ 32 | 'type' => 'VARCHAR(64)', 33 | ], 34 | 'firstname' => [ 35 | 'type' => 'VARCHAR(32)', 36 | ], 37 | 'lastname' => [ 38 | 'type' => 'VARCHAR(32)', 39 | ], 40 | 'created_at' => [ 41 | 'type' => 'DATETIME', 42 | ], 43 | ); 44 | $this->dbforge->add_field($fields); 45 | $this->dbforge->add_key('id', TRUE); 46 | $this->dbforge->create_table($this->table, TRUE); 47 | 48 | /*for ($i = 1; $i <= 100; $i++) 49 | { 50 | $this->db->insert($this->table, [ 51 | 'email' => "user-{$i}@mail.com", 52 | 'password' => password_hash('codeigniter', PASSWORD_DEFAULT), 53 | 'firstname' => "Firstname {$i}", 54 | 'lastname' => "Lastname {$i}", 55 | 'created_at' => date('Y-' . rand(1, 12) . '-' . rand(1, 28) . ' H:i:s'), 56 | ]); 57 | }*/ 58 | } 59 | 60 | 61 | public function down() 62 | { 63 | if ($this->db->table_exists($this->table)) 64 | { 65 | $this->dbforge->drop_table($this->table); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /application/migrations/20170706030520_create_table_api_keys.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | defined('BASEPATH') OR exit('No direct script access allowed'); 6 | 7 | /** 8 | * Class Migration_create_table_api_keys 9 | * 10 | * @property CI_DB_forge $dbforge 11 | * @property CI_DB_query_builder $db 12 | */ 13 | class Migration_create_table_api_keys extends CI_Migration { 14 | 15 | 16 | public function up() 17 | { 18 | $this->config->load('rest'); 19 | $table = config_item('rest_keys_table'); 20 | $fields = array( 21 | 'id' => [ 22 | 'type' => 'INT(11)', 23 | 'auto_increment' => TRUE, 24 | 'unsigned' => TRUE, 25 | ], 26 | 'user_id' => [ 27 | 'type' => 'INT(11)', 28 | 'unsigned' => TRUE, 29 | ], 30 | config_item('rest_key_column') => [ 31 | 'type' => 'VARCHAR(' . config_item('rest_key_length') . ')', 32 | 'unique' => TRUE, 33 | ], 34 | 'level' => [ 35 | 'type' => 'INT(2)', 36 | ], 37 | 'ignore_limits' => [ 38 | 'type' => 'TINYINT(1)', 39 | 'default' => 0, 40 | ], 41 | 'is_private_key' => [ 42 | 'type' => 'TINYINT(1)', 43 | 'default' => 0, 44 | ], 45 | 'ip_addresses' => [ 46 | 'type' => 'TEXT', 47 | 'null' => TRUE, 48 | ], 49 | 'date_created' => [ 50 | 'type' => 'INT(11)', 51 | ], 52 | ); 53 | $this->dbforge->add_field($fields); 54 | $this->dbforge->add_key('id', TRUE); 55 | $this->dbforge->create_table($table); 56 | $this->db->query(add_foreign_key($table, 'user_id', 'users(id)', 'CASCADE', 'CASCADE')); 57 | } 58 | 59 | 60 | public function down() 61 | { 62 | $table = config_item('rest_key_column'); 63 | if ($this->db->table_exists($table)) 64 | { 65 | $this->db->query(drop_foreign_key($table, 'user_id')); 66 | $this->dbforge->drop_table($table); 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /application/migrations/20170706031435_create_table_api_logs.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | defined('BASEPATH') OR exit('No direct script access allowed'); 6 | 7 | /** 8 | * Class Migration_create_table_api_logs 9 | * 10 | * @property CI_DB_forge $dbforge 11 | * @property CI_DB_query_builder $db 12 | */ 13 | class Migration_create_table_api_logs extends CI_Migration { 14 | 15 | 16 | public function up() 17 | { 18 | $this->config->load('rest'); 19 | $table = config_item('rest_logs_table'); 20 | $fields = array( 21 | 'id' => [ 22 | 'type' => 'INT(11)', 23 | 'auto_increment' => TRUE, 24 | 'unsigned' => TRUE, 25 | ], 26 | 'api_key' => [ 27 | 'type' => 'VARCHAR(' . config_item('rest_key_length') . ')', 28 | ], 29 | 'uri' => [ 30 | 'type' => 'VARCHAR(255)', 31 | ], 32 | 'method' => [ 33 | 'type' => 'ENUM("get","post","options","put","patch","delete")', 34 | ], 35 | 'params' => [ 36 | 'type' => 'TEXT', 37 | 'null' => TRUE, 38 | ], 39 | 'ip_address' => [ 40 | 'type' => 'VARCHAR(45)', 41 | ], 42 | 'time' => [ 43 | 'type' => 'INT(11)', 44 | ], 45 | 'rtime' => [ 46 | 'type' => 'FLOAT', 47 | 'null' => TRUE, 48 | ], 49 | 'authorized' => [ 50 | 'type' => 'VARCHAR(1)', 51 | ], 52 | 'response_code' => [ 53 | 'type' => 'SMALLINT(3)', 54 | 'null' => TRUE, 55 | 'default' => 0, 56 | ], 57 | ); 58 | $this->dbforge->add_field($fields); 59 | $this->dbforge->add_key('id', TRUE); 60 | $this->dbforge->create_table($table); 61 | /*$this->db->query(add_foreign_key($table, 'api_key', 62 | config_item('rest_keys_table') . '(' . config_item('rest_key_column') . ')', 'CASCADE', 'CASCADE'));*/ 63 | } 64 | 65 | 66 | public function down() 67 | { 68 | $table = config_item('rest_logs_table'); 69 | if ($this->db->table_exists($table)) 70 | { 71 | // $this->db->query(drop_foreign_key($table, 'api_key')); 72 | $this->dbforge->drop_table($table); 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /application/migrations/20170706032133_create_table_api_access.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | defined('BASEPATH') OR exit('No direct script access allowed'); 6 | 7 | /** 8 | * Class Migration_create_table_api_access 9 | * 10 | * @property CI_DB_forge $dbforge 11 | * @property CI_DB_query_builder $db 12 | */ 13 | class Migration_create_table_api_access extends CI_Migration { 14 | 15 | 16 | public function up() 17 | { 18 | $this->config->load('rest'); 19 | $table = config_item('rest_access_table'); 20 | $fields = array( 21 | 'id' => [ 22 | 'type' => 'INT(11)', 23 | 'auto_increment' => TRUE, 24 | 'unsigned' => TRUE, 25 | ], 26 | 'key' => [ 27 | 'type' => 'VARCHAR(' . config_item('rest_key_length') . ')', 28 | ], 29 | 'all_access' => [ 30 | 'type' => 'TINYINT(1)', 31 | 'default' => 0, 32 | ], 33 | 'controller' => [ 34 | 'type' => 'VARCHAR(50)', 35 | ], 36 | 'date_created' => [ 37 | 'type' => 'DATETIME', 38 | 'null' => TRUE, 39 | ], 40 | 'date_modified' => [ 41 | 'type' => 'TIMESTAMP', 42 | ], 43 | ); 44 | $this->dbforge->add_field($fields); 45 | $this->dbforge->add_key('id', TRUE); 46 | $this->dbforge->add_key('controller'); 47 | $this->dbforge->create_table($table); 48 | $this->db->query(add_foreign_key($table, 'key', 49 | config_item('rest_keys_table') . '(' . config_item('rest_key_column') . ')', 'CASCADE', 'CASCADE')); 50 | } 51 | 52 | 53 | public function down() 54 | { 55 | $table = config_item('rest_access_table'); 56 | if ($this->db->table_exists($table)) 57 | { 58 | $this->db->query(drop_foreign_key($table, 'key')); 59 | $this->dbforge->drop_table($table); 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /application/migrations/20170706032825_create_table_api_limits.php: -------------------------------------------------------------------------------- 1 | 4 | */ 5 | defined('BASEPATH') OR exit('No direct script access allowed'); 6 | 7 | /** 8 | * Class Migration_create_table_api_limits 9 | * 10 | * @property CI_DB_forge $dbforge 11 | * @property CI_DB_query_builder $db 12 | */ 13 | class Migration_create_table_api_limits extends CI_Migration { 14 | 15 | 16 | public function up() 17 | { 18 | $this->config->load('rest'); 19 | $table = config_item('rest_limits_table'); 20 | $fields = array( 21 | 'id' => [ 22 | 'type' => 'INT(11)', 23 | 'auto_increment' => TRUE, 24 | 'unsigned' => TRUE, 25 | ], 26 | 'api_key' => [ 27 | 'type' => 'VARCHAR(' . config_item('rest_key_length') . ')', 28 | ], 29 | 'uri' => [ 30 | 'type' => 'VARCHAR(255)', 31 | ], 32 | 'count' => [ 33 | 'type' => 'INT(10)', 34 | ], 35 | 'hour_started' => [ 36 | 'type' => 'INT(11)', 37 | ], 38 | ); 39 | $this->dbforge->add_field($fields); 40 | $this->dbforge->add_key('id', TRUE); 41 | $this->dbforge->add_key('uri'); 42 | $this->dbforge->create_table($table); 43 | $this->db->query(add_foreign_key($table, 'api_key', 44 | config_item('rest_keys_table') . '(' . config_item('rest_key_column') . ')', 'CASCADE', 'CASCADE')); 45 | } 46 | 47 | 48 | public function down() 49 | { 50 | $table = config_item('rest_limits_table'); 51 | if ($this->db->table_exists($table)) 52 | { 53 | $this->db->query(drop_foreign_key($table, 'api_key')); 54 | $this->dbforge->drop_table($table); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /application/migrations/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/views/rest_server.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | REST Server Tests 10 | 11 | 70 | 71 | 72 | 73 |
74 |

REST Server Tests

75 | 76 |
77 | 78 |

Home

79 | 80 |

81 | See the article 82 | 83 | http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/ 84 | 85 |

86 | 87 |

88 | The master project repository is 89 | 90 | https://github.com/chriskacerguis/codeigniter-restserver 91 | 92 |

93 | 94 |

95 | Click on the links to check whether the REST server is working. 96 |

97 | 98 |
    99 |
  1. Users - defaulting to JSON
  2. 100 |
  3. Users - get it in CSV
  4. 101 |
  5. User #1 - defaulting to JSON (users/id/1)
  6. 102 |
  7. User #1 - defaulting to JSON (users/1)
  8. 103 |
  9. User #1 - get it in XML (users/id/1.xml)
  10. 104 |
  11. User #1 - get it in XML (users/id/1/format/xml)
  12. 105 |
  13. User #1 - get it in XML (users/id/1?format=xml)
  14. 106 |
  15. User #1 - get it in XML (users/1.xml)
  16. 107 |
  17. Users - get it in JSON (AJAX request)
  18. 108 |
  19. Users - get it in HTML (users.html)
  20. 109 |
  21. Users - get it in HTML (users/format/html)
  22. 110 |
  23. Users - get it in HTML (users?format=html)
  24. 111 |
112 | 113 |
114 | 115 | 116 |
117 | 118 | 119 | 120 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /application/views/welcome_message.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | Welcome to CodeIgniter 10 | 11 | 70 | 71 | 72 | 73 |
74 |

Welcome to CodeIgniter!

75 | 76 |
77 | 78 |

REST Server Tests

79 | 80 | 81 |

REST Server Documentation

82 | 83 | 84 |

The page you are looking at is being generated dynamically by CodeIgniter.

85 | 86 |

If you would like to edit this page you'll find it located at:

87 | application/views/welcome_message.php 88 | 89 |

The corresponding controller for this page is found at:

90 | application/controllers/Welcome.php 91 | 92 | 93 |

If you are exploring CodeIgniter for the very first time, you should start by reading the User Guide.

94 | 95 |
96 | 97 | 98 |
99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "REST Server for the CodeIgniter framework", 3 | "name": "chriskacerguis/codeigniter-restserver", 4 | "type": "library", 5 | "homepage": "https://github.com/chriskacerguis/codeigniter-restserver", 6 | "authors": [ 7 | { 8 | "name": "Chris Kacerguis", 9 | "role": "Developer" 10 | } 11 | ], 12 | "license": "MIT", 13 | "support": { 14 | "source": "https://github.com/chriskacerguis/codeigniter-restserver" 15 | }, 16 | "require": { 17 | "php": ">=5.4.0", 18 | "codeigniter/framework": "^3.0.4" 19 | }, 20 | "autoload": { 21 | "classmap": [ 22 | "application/libraries/Format.php", 23 | "application/libraries/REST_Controller.php" 24 | ], 25 | "psr-4" : { 26 | "Restserver\\Libraries\\" : "application/libraries/" 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /documentation/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Page not found 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 67 |
68 | 69 |
70 | 71 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /documentation/class-Example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Class Example 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 62 |
63 | 64 |
65 | 66 | 454 | 455 | 456 | 457 | 458 | -------------------------------------------------------------------------------- /documentation/class-Key.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Class Key 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 62 |
63 | 64 |
65 | 66 | 509 | 510 | 511 | 512 | 513 | -------------------------------------------------------------------------------- /documentation/class-Rest_server.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Class Rest_server 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 63 |
64 | 65 |
66 | 67 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /documentation/class-Welcome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Class Welcome 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 63 |
64 | 65 |
66 | 67 | 200 | 201 | 202 | 203 | 204 | -------------------------------------------------------------------------------- /documentation/elementlist.js: -------------------------------------------------------------------------------- 1 | 2 | var ApiGen = ApiGen || {}; 3 | ApiGen.elements = [["c","Example"],["c","Format"],["c","Key"],["c","REST_Controller"],["c","Rest_server"],["c","Welcome"]]; 4 | -------------------------------------------------------------------------------- /documentation/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Overview 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 65 |
66 | 67 |
68 | 69 | 128 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /documentation/package-CodeIgniter.Libraries.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Package CodeIgniter\Libraries 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 61 |
62 | 63 |
64 | 65 | 114 | 115 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /documentation/package-CodeIgniter.Rest.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Package CodeIgniter\Rest 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 62 |
63 | 64 |
65 | 66 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /documentation/package-CodeIgniter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Package CodeIgniter 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 56 |
57 | 58 |
59 | 60 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /documentation/package-None.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | No package 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 | 63 |
64 | 65 |
66 | 67 | 124 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /documentation/resources/collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/collapsed.png -------------------------------------------------------------------------------- /documentation/resources/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/footer.png -------------------------------------------------------------------------------- /documentation/resources/inherit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/inherit.png -------------------------------------------------------------------------------- /documentation/resources/resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/resize.png -------------------------------------------------------------------------------- /documentation/resources/sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/sort.png -------------------------------------------------------------------------------- /documentation/resources/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: 13px/1.5 Verdana, 'Geneva CE', lucida, sans-serif; 3 | margin: 0; 4 | padding: 0; 5 | background: #ffffff; 6 | color: #333333; 7 | } 8 | 9 | h1, h2, h3, h4, caption { 10 | font-family: 'Trebuchet MS', 'Geneva CE', lucida, sans-serif; 11 | color: #053368; 12 | } 13 | 14 | h1 { 15 | color: #1e5eb6; 16 | font-size: 230%; 17 | font-weight: normal; 18 | margin: .3em 0; 19 | } 20 | 21 | h2 { 22 | color: #1e5eb6; 23 | font-size: 150%; 24 | font-weight: normal; 25 | margin: -.3em 0 .3em 0; 26 | } 27 | 28 | h3 { 29 | font-size: 1.6em; 30 | font-weight: normal; 31 | margin-bottom: 2px; 32 | } 33 | 34 | h4 { 35 | font-size: 100%; 36 | font-weight: bold; 37 | padding: 0; 38 | margin: 0; 39 | } 40 | 41 | caption { 42 | border: 1px solid #cccccc; 43 | background: #ecede5; 44 | font-weight: bold; 45 | font-size: 1.2em; 46 | padding: 3px 5px; 47 | text-align: left; 48 | margin-bottom: 0; 49 | } 50 | 51 | p { 52 | margin: .7em 0 1em; 53 | padding: 0; 54 | } 55 | 56 | hr { 57 | margin: 2em 0 1em; 58 | border: none; 59 | border-top: 1px solid #cccccc; 60 | height: 0; 61 | } 62 | 63 | a { 64 | color: #006aeb; 65 | padding: 3px 1px; 66 | text-decoration: none; 67 | } 68 | 69 | h1 a { 70 | color: #1e5eb6; 71 | } 72 | 73 | a:hover, a:active, a:focus, a:hover b, a:hover var { 74 | background-color: #006aeb; 75 | color: #ffffff !important; 76 | } 77 | 78 | code, var, pre { 79 | font-family: monospace; 80 | } 81 | 82 | var { 83 | font-weight: bold; 84 | font-style: normal; 85 | color: #ca8a04; 86 | } 87 | 88 | pre { 89 | margin: 0; 90 | } 91 | 92 | code a b { 93 | color: #000000; 94 | } 95 | 96 | .deprecated { 97 | text-decoration: line-through; 98 | opacity: .5; 99 | } 100 | 101 | .invalid { 102 | color: #e71818; 103 | } 104 | 105 | .hidden { 106 | display: none; 107 | } 108 | 109 | /* Left side */ 110 | #left { 111 | overflow: auto; 112 | width: 270px; 113 | height: 100%; 114 | position: fixed; 115 | } 116 | 117 | /* Menu */ 118 | #menu { 119 | padding: 10px; 120 | } 121 | 122 | #menu ul { 123 | list-style: none; 124 | padding: 0; 125 | margin: 0; 126 | } 127 | 128 | #menu ul ul { 129 | padding-left: 10px; 130 | } 131 | 132 | #menu li { 133 | white-space: nowrap; 134 | position: relative; 135 | } 136 | 137 | #menu a { 138 | display: block; 139 | padding: 0 2px; 140 | } 141 | 142 | #menu .active > a, #menu > span { 143 | color: #333333; 144 | background: none; 145 | font-weight: bold; 146 | } 147 | 148 | #menu .active > a.invalid { 149 | color: #e71818; 150 | } 151 | 152 | #menu .active > a:hover, #menu .active > a:active, #menu .active > a:focus { 153 | background-color: #006aeb; 154 | } 155 | 156 | #menu #groups span { 157 | position: absolute; 158 | top: 4px; 159 | right: 2px; 160 | cursor: pointer; 161 | display: block; 162 | width: 12px; 163 | height: 12px; 164 | background: url('collapsed.png') transparent 0 0 no-repeat; 165 | } 166 | 167 | #menu #groups span:hover { 168 | background-position: -12px 0; 169 | } 170 | 171 | #menu #groups span.collapsed { 172 | background-position: 0 -12px; 173 | } 174 | 175 | #menu #groups span.collapsed:hover { 176 | background-position: -12px -12px; 177 | } 178 | 179 | #menu #groups ul.collapsed { 180 | display: none; 181 | } 182 | 183 | /* Right side */ 184 | #right { 185 | overflow: auto; 186 | margin-left: 275px; 187 | height: 100%; 188 | position: relative; 189 | left: 0; 190 | right: 0; 191 | } 192 | 193 | #rightInner { 194 | max-width: 1000px; 195 | min-width: 350px; 196 | } 197 | 198 | /* Search */ 199 | #search { 200 | float: right; 201 | margin: 3px 8px; 202 | } 203 | 204 | #search input.text { 205 | padding: 3px 5px; 206 | width: 250px; 207 | } 208 | 209 | /* Autocomplete */ 210 | .ac_results { 211 | padding: 0; 212 | border: 1px solid #cccccc; 213 | background-color: #ffffff; 214 | overflow: hidden; 215 | z-index: 99999; 216 | } 217 | 218 | .ac_results ul { 219 | width: 100%; 220 | list-style-position: outside; 221 | list-style: none; 222 | padding: 0; 223 | margin: 0; 224 | } 225 | 226 | .ac_results li { 227 | margin: 0; 228 | padding: 2px 5px; 229 | cursor: default; 230 | display: block; 231 | font: 12px 'Trebuchet MS', 'Geneva CE', lucida, sans-serif; 232 | line-height: 16px; 233 | overflow: hidden; 234 | white-space: nowrap; 235 | } 236 | 237 | .ac_results li strong { 238 | color: #000000; 239 | } 240 | 241 | .ac_odd { 242 | background-color: #eeeeee; 243 | } 244 | 245 | .ac_over { 246 | background-color: #006aeb; 247 | color: #ffffff; 248 | } 249 | 250 | .ac_results li.ac_over strong { 251 | color: #ffffff; 252 | } 253 | 254 | /* Navigation */ 255 | #navigation { 256 | padding: 3px 8px; 257 | background-color: #f6f6f4; 258 | height: 26px; 259 | } 260 | 261 | #navigation ul { 262 | list-style: none; 263 | margin: 0 8px 4px 0; 264 | padding: 0; 265 | overflow: hidden; 266 | float: left; 267 | } 268 | 269 | #navigation ul + ul { 270 | border-left: 1px solid #000000; 271 | padding-left: 8px; 272 | } 273 | 274 | #navigation ul li { 275 | float: left; 276 | margin: 2px; 277 | padding: 0 3px; 278 | font-family: Verdana, 'Geneva CE', lucida, sans-serif; 279 | color: #808080; 280 | } 281 | 282 | #navigation ul li.active { 283 | background-color: #053368; 284 | color: #ffffff; 285 | font-weight: bold; 286 | } 287 | 288 | #navigation ul li a { 289 | color: #000000; 290 | font-weight: bold; 291 | padding: 0; 292 | } 293 | 294 | #navigation ul li span { 295 | float: left; 296 | padding: 0 3px; 297 | } 298 | 299 | #navigation ul li a:hover span, #navigation ul li a:active span, #navigation ul li a:focus span { 300 | background-color: #006aeb; 301 | } 302 | 303 | /* Content */ 304 | #content { 305 | clear: both; 306 | padding: 5px 15px; 307 | } 308 | 309 | .description pre { 310 | padding: .6em; 311 | background: #fcfcf7; 312 | } 313 | 314 | #content > .description { 315 | background: #ecede5; 316 | padding: 1px 8px; 317 | margin: 1.2em 0; 318 | } 319 | 320 | #content > .description pre { 321 | margin: .5em 0; 322 | } 323 | 324 | dl.tree { 325 | margin: 1.2em 0; 326 | } 327 | 328 | dl.tree dd { 329 | margin: 0; 330 | padding: 0; 331 | } 332 | 333 | .info { 334 | margin: 1.2em 0; 335 | } 336 | 337 | .summary { 338 | border: 1px solid #cccccc; 339 | border-collapse: collapse; 340 | font-size: 1em; 341 | width: 100%; 342 | margin: 1.2em 0 2.4em; 343 | } 344 | 345 | .summary caption { 346 | border-width: 1px 1px 0; 347 | } 348 | 349 | .summary caption.switchable { 350 | background: #ecede5 url('sort.png') no-repeat center right; 351 | cursor: pointer; 352 | } 353 | 354 | .summary td { 355 | border: 1px solid #cccccc; 356 | margin: 0; 357 | padding: 3px 10px; 358 | font-size: 1em; 359 | vertical-align: top; 360 | } 361 | 362 | .summary td:first-child { 363 | text-align: right; 364 | } 365 | 366 | .summary td hr { 367 | margin: 3px -10px; 368 | } 369 | 370 | #packages.summary td:first-child, #namespaces.summary td:first-child, .inherited.summary td:first-child, .used.summary td:first-child { 371 | text-align: left; 372 | } 373 | 374 | .summary tr:hover td { 375 | background: #f6f6f4; 376 | } 377 | 378 | .summary .description pre { 379 | border: .5em solid #ecede5; 380 | } 381 | 382 | .summary .description p { 383 | margin: 0; 384 | } 385 | 386 | .summary .description p + p, .summary .description ul { 387 | margin: 3px 0 0 0; 388 | } 389 | 390 | .summary .description.detailed h4 { 391 | margin-top: 3px; 392 | } 393 | 394 | .summary dl { 395 | margin: 0; 396 | } 397 | 398 | .summary dd { 399 | margin: 0 0 0 25px; 400 | } 401 | 402 | .name, .attributes { 403 | white-space: nowrap; 404 | } 405 | 406 | .value code { 407 | white-space: pre-wrap; 408 | } 409 | 410 | td.name, td.attributes { 411 | width: 1%; 412 | } 413 | 414 | td.attributes { 415 | width: 1%; 416 | } 417 | 418 | .class .methods .name, .class .properties .name, .class .constants .name { 419 | width: auto; 420 | white-space: normal; 421 | } 422 | 423 | .class .methods .name > div > code { 424 | white-space: pre-wrap; 425 | } 426 | 427 | .class .methods .name > div > code span, .function .value > code { 428 | white-space: nowrap; 429 | } 430 | 431 | .class .methods td.name > div, .class td.value > div { 432 | position: relative; 433 | padding-right: 1em; 434 | } 435 | 436 | .anchor { 437 | position: absolute; 438 | top: 0; 439 | right: 0; 440 | line-height: 1; 441 | font-size: 85%; 442 | margin: 0; 443 | color: #006aeb !important; 444 | } 445 | 446 | .list { 447 | margin: 0 0 5px 25px; 448 | } 449 | 450 | div.invalid { 451 | background-color: #fae4e0; 452 | padding: 10px; 453 | } 454 | 455 | /* Splitter */ 456 | #splitter { 457 | position: fixed; 458 | height: 100%; 459 | width: 5px; 460 | left: 270px; 461 | background: #1e5eb6 url('resize.png') left center no-repeat; 462 | cursor: e-resize; 463 | } 464 | 465 | #splitter.active { 466 | opacity: .5; 467 | } 468 | 469 | /* Footer */ 470 | #footer { 471 | border-top: 1px solid #e9eeef; 472 | clear: both; 473 | color: #a7a7a7; 474 | font-size: 8pt; 475 | text-align: center; 476 | padding: 20px 0 0; 477 | margin: 3em 0 0; 478 | height: 90px; 479 | background: #ffffff url('footer.png') no-repeat center top; 480 | } 481 | 482 | /* Tree */ 483 | div.tree ul { 484 | list-style: none; 485 | background: url('tree-vertical.png') left repeat-y; 486 | padding: 0; 487 | margin-left: 20px; 488 | } 489 | 490 | div.tree li { 491 | margin: 0; 492 | padding: 0; 493 | } 494 | 495 | div.tree div { 496 | padding-left: 30px; 497 | } 498 | 499 | div.tree div.notlast { 500 | background: url('tree-hasnext.png') left 10px no-repeat; 501 | } 502 | 503 | div.tree div.last { 504 | background: url('tree-last.png') left -240px no-repeat; 505 | } 506 | 507 | div.tree li.last { 508 | background: url('tree-cleaner.png') left center repeat-y; 509 | } 510 | 511 | div.tree span.padding { 512 | padding-left: 15px; 513 | } 514 | 515 | /* Source code */ 516 | .php-keyword1 { 517 | color: #e71818; 518 | font-weight: bold; 519 | } 520 | 521 | .php-keyword2 { 522 | font-weight: bold; 523 | } 524 | 525 | .php-var { 526 | color: #d59401; 527 | font-weight: bold; 528 | } 529 | 530 | .php-num { 531 | color: #cd0673; 532 | } 533 | 534 | .php-quote { 535 | color: #008000; 536 | } 537 | 538 | .php-comment { 539 | color: #929292; 540 | } 541 | 542 | .xlang { 543 | color: #ff0000; 544 | font-weight: bold; 545 | } 546 | 547 | span.l { 548 | display: block; 549 | } 550 | 551 | span.l.selected { 552 | background: #f6f6f4; 553 | } 554 | 555 | span.l a { 556 | color: #333333; 557 | } 558 | 559 | span.l a:hover, div.l a:active, div.l a:focus { 560 | background: transparent; 561 | color: #333333 !important; 562 | } 563 | 564 | span.l .php-var a { 565 | color: #d59401; 566 | } 567 | 568 | span.l .php-var a:hover, span.l .php-var a:active, span.l .php-var a:focus { 569 | color: #d59401 !important; 570 | } 571 | 572 | span.l a.l { 573 | padding-left: 2px; 574 | color: #c0c0c0; 575 | } 576 | 577 | span.l a.l:hover, span.l a.l:active, span.l a.l:focus { 578 | background: transparent; 579 | color: #c0c0c0 !important; 580 | } 581 | 582 | #rightInner.medium #navigation { 583 | height: 52px; 584 | } 585 | 586 | #rightInner.medium #navigation ul:first-child + ul { 587 | clear: left; 588 | border: none; 589 | padding: 0; 590 | } 591 | 592 | #rightInner.medium .name, #rightInner.medium .attributes { 593 | white-space: normal; 594 | } 595 | 596 | #rightInner.small #search { 597 | float: left; 598 | } 599 | 600 | #rightInner.small #navigation { 601 | height: 78px; 602 | } 603 | 604 | #rightInner.small #navigation ul:first-child { 605 | clear: both; 606 | } 607 | 608 | /* global style */ 609 | .left, .summary td.left { 610 | text-align: left; 611 | } 612 | .right, .summary td.right { 613 | text-align: right; 614 | } 615 | -------------------------------------------------------------------------------- /documentation/resources/tree-cleaner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/tree-cleaner.png -------------------------------------------------------------------------------- /documentation/resources/tree-hasnext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/tree-hasnext.png -------------------------------------------------------------------------------- /documentation/resources/tree-last.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/tree-last.png -------------------------------------------------------------------------------- /documentation/resources/tree-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ajaysoftdeveloper/codeigniter-restserver/89503b0e1dceacaa9407f4d28e611ab034a7bb8b/documentation/resources/tree-vertical.png -------------------------------------------------------------------------------- /documentation/source-class-Example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File controllers/api/Example.php 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 67 |
68 | 69 |
70 | 71 | 239 | 240 | 241 | 242 | 243 | -------------------------------------------------------------------------------- /documentation/source-class-Rest_server.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File controllers/Rest_server.php 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 67 |
68 | 69 |
70 | 71 | 115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /documentation/source-class-Welcome.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | File controllers/Welcome.php 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 67 |
68 | 69 |
70 | 71 | 129 | 130 | 131 | 132 | 133 | --------------------------------------------------------------------------------