├── .gitignore ├── .codeclimate.yml ├── documentation ├── resources │ ├── sort.png │ ├── footer.png │ ├── inherit.png │ ├── resize.png │ ├── collapsed.png │ ├── tree-last.png │ ├── tree-cleaner.png │ ├── tree-hasnext.png │ ├── tree-vertical.png │ └── style.css ├── elementlist.js ├── package-CodeIgniter.html ├── package-CodeIgniter.Libraries.html ├── 404.html ├── package-None.html ├── package-CodeIgniter.Rest.html ├── index.html ├── class-Rest_server.html ├── source-class-Rest_server.html ├── class-Welcome.html ├── source-class-Welcome.html ├── class-Example.html ├── source-class-Example.html └── class-Key.html ├── application ├── config │ ├── index.html │ ├── routes.php │ └── rest.php ├── language │ ├── index.html │ ├── 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 │ ├── indonesia │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── italian │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── korean │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── romanian │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── spanish │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── turkish │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── serbian_cyr │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── serbian_lat │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── traditional-chinese │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── portuguese-brazilian │ │ ├── index.html │ │ └── rest_controller_lang.php │ ├── simplified-chinese │ │ ├── index.html │ │ └── rest_controller_lang.php │ └── greek │ │ └── rest_controller_lang.php ├── views │ ├── index.html │ ├── welcome_message.php │ └── rest_server.php ├── controllers │ ├── index.html │ ├── api │ │ ├── index.html │ │ ├── Example.php │ │ └── Key.php │ ├── Rest_server.php │ └── Welcome.php └── libraries │ ├── index.html │ └── Format.php ├── composer.json ├── LICENSE ├── CHANGELOG.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | vendor 3 | .idea -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | exclude_paths: 2 | - "documentation/" 3 | - "application/language/" -------------------------------------------------------------------------------- /documentation/resources/sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/sort.png -------------------------------------------------------------------------------- /documentation/resources/footer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/footer.png -------------------------------------------------------------------------------- /documentation/resources/inherit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/inherit.png -------------------------------------------------------------------------------- /documentation/resources/resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/resize.png -------------------------------------------------------------------------------- /documentation/resources/collapsed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/collapsed.png -------------------------------------------------------------------------------- /documentation/resources/tree-last.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/tree-last.png -------------------------------------------------------------------------------- /documentation/resources/tree-cleaner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/tree-cleaner.png -------------------------------------------------------------------------------- /documentation/resources/tree-hasnext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/tree-hasnext.png -------------------------------------------------------------------------------- /documentation/resources/tree-vertical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/natanfelles/codeigniter-restserver/master/documentation/resources/tree-vertical.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /application/config/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/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/controllers/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /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/dutch/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/language/german/index.html: -------------------------------------------------------------------------------- 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/italian/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 403 Forbidden 5 | 6 | 7 | 8 |

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

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

Directory access is forbidden.

9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /application/controllers/Rest_server.php: -------------------------------------------------------------------------------- 1 | load->helper('url'); 10 | 11 | $this->load->view('rest_server'); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "REST Server for the CodeIgniter framework", 3 | "name": "chriskacerguis/codeigniter-restserver", 4 | "type": "project", 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 | } -------------------------------------------------------------------------------- /application/language/traditional-chinese/rest_controller_lang.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/language/korean/rest_controller_lang.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 | -------------------------------------------------------------------------------- /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-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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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/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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /application/controllers/api/Example.php: -------------------------------------------------------------------------------- 1 | methods['users_get']['limit'] = 500; // 500 requests per hour per user/key 30 | $this->methods['users_post']['limit'] = 100; // 100 requests per hour per user/key 31 | $this->methods['users_delete']['limit'] = 50; // 50 requests per hour per user/key 32 | } 33 | 34 | public function users_get() 35 | { 36 | // Users from a data store e.g. database 37 | $users = [ 38 | ['id' => 1, 'name' => 'John', 'email' => 'john@example.com', 'fact' => 'Loves coding'], 39 | ['id' => 2, 'name' => 'Jim', 'email' => 'jim@example.com', 'fact' => 'Developed on CodeIgniter'], 40 | ['id' => 3, 'name' => 'Jane', 'email' => 'jane@example.com', 'fact' => 'Lives in the USA', ['hobbies' => ['guitar', 'cycling']]], 41 | ]; 42 | 43 | $id = $this->get('id'); 44 | 45 | // If the id parameter doesn't exist return all the users 46 | 47 | if ($id === NULL) 48 | { 49 | // Check if the users data store contains users (in case the database result returns NULL) 50 | if ($users) 51 | { 52 | // Set the response and exit 53 | $this->response($users, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 54 | } 55 | else 56 | { 57 | // Set the response and exit 58 | $this->response([ 59 | 'status' => FALSE, 60 | 'message' => 'No users were found' 61 | ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code 62 | } 63 | } 64 | 65 | // Find and return a single record for a particular user. 66 | 67 | $id = (int) $id; 68 | 69 | // Validate the id. 70 | if ($id <= 0) 71 | { 72 | // Invalid id, set the response and exit. 73 | $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 74 | } 75 | 76 | // Get the user from the array, using the id as key for retrieval. 77 | // Usually a model is to be used for this. 78 | 79 | $user = NULL; 80 | 81 | if (!empty($users)) 82 | { 83 | foreach ($users as $key => $value) 84 | { 85 | if (isset($value['id']) && $value['id'] === $id) 86 | { 87 | $user = $value; 88 | } 89 | } 90 | } 91 | 92 | if (!empty($user)) 93 | { 94 | $this->set_response($user, REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 95 | } 96 | else 97 | { 98 | $this->set_response([ 99 | 'status' => FALSE, 100 | 'message' => 'User could not be found' 101 | ], REST_Controller::HTTP_NOT_FOUND); // NOT_FOUND (404) being the HTTP response code 102 | } 103 | } 104 | 105 | public function users_post() 106 | { 107 | // $this->some_model->update_user( ... ); 108 | $message = [ 109 | 'id' => 100, // Automatically generated by the model 110 | 'name' => $this->post('name'), 111 | 'email' => $this->post('email'), 112 | 'message' => 'Added a resource' 113 | ]; 114 | 115 | $this->set_response($message, REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code 116 | } 117 | 118 | public function users_delete() 119 | { 120 | $id = (int) $this->get('id'); 121 | 122 | // Validate the id. 123 | if ($id <= 0) 124 | { 125 | // Set the response and exit 126 | $this->response(NULL, REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 127 | } 128 | 129 | // $this->some_model->delete_something($id); 130 | $message = [ 131 | 'id' => $id, 132 | 'message' => 'Deleted the resource' 133 | ]; 134 | 135 | $this->set_response($message, REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CodeIgniter Rest Server 2 | 3 | [![Gitter chat](https://badges.gitter.im/chriskacerguis/codeigniter-restserver.png)](https://gitter.im/codeigniter-restserver/Lobby) 4 | 5 | A fully RESTful server implementation for CodeIgniter using one library, one 6 | config file and one controller. 7 | 8 | ## Requirements 9 | 10 | 1. PHP 5.4 or greater 11 | 2. CodeIgniter 3.0+ 12 | 13 | _Note: for 1.7.x support download v2.2 from Downloads tab_ 14 | 15 | ## Important Update on 4.0.0 16 | 17 | 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. 18 | 19 | Take a look at the "development" branch to see what's up. 20 | 21 | ## Installation 22 | 23 | Drag and drop the **application/libraries/Format.php** and **application/libraries/REST_Controller.php** files into your application's directories. To use `require_once` it at the top of your controllers to load it into the scope. Additionally, copy the **rest.php** file from **application/config** in your application's configuration directory. 24 | 25 | ## Handling Requests 26 | 27 | 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. 28 | 29 | This allows you to implement a RESTful interface easily: 30 | 31 | ```php 32 | class Books extends REST_Controller 33 | { 34 | public function index_get() 35 | { 36 | // Display all books 37 | } 38 | 39 | public function index_post() 40 | { 41 | // Create a new book 42 | } 43 | } 44 | ``` 45 | 46 | `REST_Controller` also supports `PUT` and `DELETE` methods, allowing you to support a truly RESTful interface. 47 | 48 | 49 | Accessing parameters is also easy. Simply use the name of the HTTP verb as a method: 50 | 51 | ```php 52 | $this->get('blah'); // GET param 53 | $this->post('blah'); // POST param 54 | $this->put('blah'); // PUT param 55 | ``` 56 | 57 | The HTTP spec for DELETE requests precludes the use of parameters. For delete requests, you can add items to the URL 58 | 59 | ```php 60 | public function index_delete($id) 61 | { 62 | $this->response([ 63 | 'returned from delete:' => $id, 64 | ]); 65 | } 66 | ``` 67 | 68 | If query parameters are passed via the URL, regardless of whether it's a GET request, can be obtained by the query method: 69 | 70 | ```php 71 | $this->query('blah'); // Query param 72 | ``` 73 | 74 | ## Content Types 75 | 76 | `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. 77 | 78 | This means your URLs can look like this: 79 | ``` 80 | http://example.com/books.json 81 | http://example.com/books?format=json 82 | ``` 83 | 84 | This can be flaky with URI segments, so the recommend approach is using the HTTP `Accept` header: 85 | 86 | ```bash 87 | $ curl -H "Accept: application/json" http://example.com 88 | ``` 89 | 90 | Any responses you make from the class (see [responses](#responses) for more on this) will be serialised in the designated format. 91 | 92 | ## Responses 93 | 94 | The class provides a `response()` method that allows you to return data in the user's requested response format. 95 | 96 | Returning any object / array / string / whatever is easy: 97 | 98 | ```php 99 | public function index_get() 100 | { 101 | $this->response($this->db->get('books')->result()); 102 | } 103 | ``` 104 | 105 | This will automatically return an `HTTP 200 OK` response. You can specify the status code in the second parameter: 106 | 107 | ```php 108 | public function index_post() 109 | { 110 | // ...create new book 111 | $this->response($book, 201); // Send an HTTP 201 Created 112 | } 113 | ``` 114 | 115 | 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`: 116 | 117 | ```php 118 | $this->response([]); // HTTP 404 Not Found 119 | ``` 120 | 121 | ## Multilingual Support 122 | 123 | If your application uses language files to support multiple locales, `REST_Controller` will automatically parse the HTTP `Accept-Language` header and provide the language(s) in your actions. This information can be found in the `$this->response->lang` object: 124 | 125 | ```php 126 | public function __construct() 127 | { 128 | parent::__construct(); 129 | 130 | if (is_array($this->response->lang)) 131 | { 132 | $this->load->language('application', $this->response->lang[0]); 133 | } 134 | else 135 | { 136 | $this->load->language('application', $this->response->lang); 137 | } 138 | } 139 | ``` 140 | 141 | ## Authentication 142 | 143 | This class also provides rudimentary support for HTTP basic authentication and/or the securer HTTP digest access authentication. 144 | 145 | 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: 146 | 147 | ```php 148 | $config['rest_valid_logins'] = ['username' => 'password', 'other_person' => 'secure123']; 149 | ``` 150 | 151 | 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. 152 | 153 | 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``. 154 | 155 | 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. 156 | 157 | 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: 158 | 159 | ```php 160 | $config['rest_ip_whitelist'] = '123.456.789.0, 987.654.32.1'; 161 | ``` 162 | 163 | Your localhost IPs (`127.0.0.1` and `0.0.0.0`) are allowed by default. 164 | 165 | ## API Keys 166 | 167 | 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: 168 | 169 | ```php 170 | $config['rest_enable_keys'] = TRUE; 171 | ``` 172 | 173 | 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: 174 | 175 | ```sql 176 | CREATE TABLE `keys` ( 177 | `id` INT(11) NOT NULL AUTO_INCREMENT, 178 | `key` VARCHAR(40) NOT NULL, 179 | `level` INT(2) NOT NULL, 180 | `ignore_limits` TINYINT(1) NOT NULL DEFAULT '0', 181 | `date_created` INT(11) NOT NULL, 182 | PRIMARY KEY (`id`) 183 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 184 | ``` 185 | 186 | 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`. 187 | 188 | By default, the HTTP will be `X-API-KEY`. This can be configured in **config/rest.php**. 189 | 190 | ```bash 191 | $ curl -X POST -H "X-API-KEY: some_key_here" http://example.com/books 192 | ``` 193 | 194 | ## Other Documentation / Tutorials 195 | 196 | * [NetTuts: Working with RESTful Services in CodeIgniter](http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/) 197 | 198 | ## Contributions 199 | 200 | This project was originally written by Phil Sturgeon, however his involvement has shifted 201 | as he is no longer using it. As of 2013/11/20 further development and support will be done by Chris Kacerguis. 202 | 203 | Pull Requests are the best way to fix bugs or add features. I know loads of you use this, so please 204 | contribute if you have improvements to be made and I'll keep releasing versions over time. 205 | 206 | [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://raw.githubusercontent.com/chriskacerguis/codeigniter-restserver/master/LICENSE) 207 | -------------------------------------------------------------------------------- /application/controllers/api/Key.php: -------------------------------------------------------------------------------- 1 | ['level' => 10, 'limit' => 10], 24 | 'index_delete' => ['level' => 10], 25 | 'level_post' => ['level' => 10], 26 | 'regenerate_post' => ['level' => 10], 27 | ]; 28 | 29 | /** 30 | * Insert a key into the database 31 | * 32 | * @access public 33 | * @return void 34 | */ 35 | public function index_put() 36 | { 37 | // Build a new key 38 | $key = $this->_generate_key(); 39 | 40 | // If no key level provided, provide a generic key 41 | $level = $this->put('level') ? $this->put('level') : 1; 42 | $ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1; 43 | 44 | // Insert the new key 45 | if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits])) 46 | { 47 | $this->response([ 48 | 'status' => TRUE, 49 | 'key' => $key 50 | ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code 51 | } 52 | else 53 | { 54 | $this->response([ 55 | 'status' => FALSE, 56 | 'message' => 'Could not save the key' 57 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 58 | } 59 | } 60 | 61 | /** 62 | * Remove a key from the database to stop it working 63 | * 64 | * @access public 65 | * @return void 66 | */ 67 | public function index_delete() 68 | { 69 | $key = $this->delete('key'); 70 | 71 | // Does this key exist? 72 | if (!$this->_key_exists($key)) 73 | { 74 | // It doesn't appear the key exists 75 | $this->response([ 76 | 'status' => FALSE, 77 | 'message' => 'Invalid API key' 78 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 79 | } 80 | 81 | // Destroy it 82 | $this->_delete_key($key); 83 | 84 | // Respond that the key was destroyed 85 | $this->response([ 86 | 'status' => TRUE, 87 | 'message' => 'API key was deleted' 88 | ], REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code 89 | } 90 | 91 | /** 92 | * Change the level 93 | * 94 | * @access public 95 | * @return void 96 | */ 97 | public function level_post() 98 | { 99 | $key = $this->post('key'); 100 | $new_level = $this->post('level'); 101 | 102 | // Does this key exist? 103 | if (!$this->_key_exists($key)) 104 | { 105 | // It doesn't appear the key exists 106 | $this->response([ 107 | 'status' => FALSE, 108 | 'message' => 'Invalid API key' 109 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 110 | } 111 | 112 | // Update the key level 113 | if ($this->_update_key($key, ['level' => $new_level])) 114 | { 115 | $this->response([ 116 | 'status' => TRUE, 117 | 'message' => 'API key was updated' 118 | ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 119 | } 120 | else 121 | { 122 | $this->response([ 123 | 'status' => FALSE, 124 | 'message' => 'Could not update the key level' 125 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 126 | } 127 | } 128 | 129 | /** 130 | * Suspend a key 131 | * 132 | * @access public 133 | * @return void 134 | */ 135 | public function suspend_post() 136 | { 137 | $key = $this->post('key'); 138 | 139 | // Does this key exist? 140 | if (!$this->_key_exists($key)) 141 | { 142 | // It doesn't appear the key exists 143 | $this->response([ 144 | 'status' => FALSE, 145 | 'message' => 'Invalid API key' 146 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 147 | } 148 | 149 | // Update the key level 150 | if ($this->_update_key($key, ['level' => 0])) 151 | { 152 | $this->response([ 153 | 'status' => TRUE, 154 | 'message' => 'Key was suspended' 155 | ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code 156 | } 157 | else 158 | { 159 | $this->response([ 160 | 'status' => FALSE, 161 | 'message' => 'Could not suspend the user' 162 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 163 | } 164 | } 165 | 166 | /** 167 | * Regenerate a key 168 | * 169 | * @access public 170 | * @return void 171 | */ 172 | public function regenerate_post() 173 | { 174 | $old_key = $this->post('key'); 175 | $key_details = $this->_get_key($old_key); 176 | 177 | // Does this key exist? 178 | if (!$key_details) 179 | { 180 | // It doesn't appear the key exists 181 | $this->response([ 182 | 'status' => FALSE, 183 | 'message' => 'Invalid API key' 184 | ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code 185 | } 186 | 187 | // Build a new key 188 | $new_key = $this->_generate_key(); 189 | 190 | // Insert the new key 191 | if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits])) 192 | { 193 | // Suspend old key 194 | $this->_update_key($old_key, ['level' => 0]); 195 | 196 | $this->response([ 197 | 'status' => TRUE, 198 | 'key' => $new_key 199 | ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code 200 | } 201 | else 202 | { 203 | $this->response([ 204 | 'status' => FALSE, 205 | 'message' => 'Could not save the key' 206 | ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code 207 | } 208 | } 209 | 210 | /* Helper Methods */ 211 | 212 | private function _generate_key() 213 | { 214 | do 215 | { 216 | // Generate a random salt 217 | $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36); 218 | 219 | // If an error occurred, then fall back to the previous method 220 | if ($salt === FALSE) 221 | { 222 | $salt = hash('sha256', time() . mt_rand()); 223 | } 224 | 225 | $new_key = substr($salt, 0, config_item('rest_key_length')); 226 | } 227 | while ($this->_key_exists($new_key)); 228 | 229 | return $new_key; 230 | } 231 | 232 | /* Private Data Methods */ 233 | 234 | private function _get_key($key) 235 | { 236 | return $this->rest->db 237 | ->where(config_item('rest_key_column'), $key) 238 | ->get(config_item('rest_keys_table')) 239 | ->row(); 240 | } 241 | 242 | private function _key_exists($key) 243 | { 244 | return $this->rest->db 245 | ->where(config_item('rest_key_column'), $key) 246 | ->count_all_results(config_item('rest_keys_table')) > 0; 247 | } 248 | 249 | private function _insert_key($key, $data) 250 | { 251 | $data[config_item('rest_key_column')] = $key; 252 | $data['date_created'] = function_exists('now') ? now() : time(); 253 | 254 | return $this->rest->db 255 | ->set($data) 256 | ->insert(config_item('rest_keys_table')); 257 | } 258 | 259 | private function _update_key($key, $data) 260 | { 261 | return $this->rest->db 262 | ->where(config_item('rest_key_column'), $key) 263 | ->update(config_item('rest_keys_table'), $data); 264 | } 265 | 266 | private function _delete_key($key) 267 | { 268 | return $this->rest->db 269 | ->where(config_item('rest_key_column'), $key) 270 | ->delete(config_item('rest_keys_table')); 271 | } 272 | 273 | } 274 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /application/libraries/Format.php: -------------------------------------------------------------------------------- 1 | _CI = &get_instance(); 87 | 88 | // Load the inflector helper 89 | $this->_CI->load->helper('inflector'); 90 | 91 | // If the provided data is already formatted we should probably convert it to an array 92 | if ($from_type !== NULL) 93 | { 94 | if (method_exists($this, '_from_'.$from_type)) 95 | { 96 | $data = call_user_func([$this, '_from_'.$from_type], $data); 97 | } 98 | else 99 | { 100 | throw new Exception('Format class does not support conversion from "'.$from_type.'".'); 101 | } 102 | } 103 | 104 | // Set the member variable to the data passed 105 | $this->_data = $data; 106 | } 107 | 108 | /** 109 | * Create an instance of the format class 110 | * e.g: echo $this->format->factory(['foo' => 'bar'])->to_csv(); 111 | * 112 | * @param mixed $data Data to convert/parse 113 | * @param string $from_type Type to convert from e.g. json, csv, html 114 | * 115 | * @return object Instance of the format class 116 | */ 117 | public function factory($data, $from_type = NULL) 118 | { 119 | // $class = __CLASS__; 120 | // return new $class(); 121 | 122 | return new static($data, $from_type); 123 | } 124 | 125 | // FORMATTING OUTPUT --------------------------------------------------------- 126 | 127 | /** 128 | * Format data as an array 129 | * 130 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 131 | * to the constructor 132 | * @return array Data parsed as an array; otherwise, an empty array 133 | */ 134 | public function to_array($data = NULL) 135 | { 136 | // If no data is passed as a parameter, then use the data passed 137 | // via the constructor 138 | if ($data === NULL && func_num_args() === 0) 139 | { 140 | $data = $this->_data; 141 | } 142 | 143 | // Cast as an array if not already 144 | if (is_array($data) === FALSE) 145 | { 146 | $data = (array) $data; 147 | } 148 | 149 | $array = []; 150 | foreach ((array) $data as $key => $value) 151 | { 152 | if (is_object($value) === TRUE || is_array($value) === TRUE) 153 | { 154 | $array[$key] = $this->to_array($value); 155 | } 156 | else 157 | { 158 | $array[$key] = $value; 159 | } 160 | } 161 | 162 | return $array; 163 | } 164 | 165 | /** 166 | * Format data as XML 167 | * 168 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 169 | * to the constructor 170 | * @param NULL $structure 171 | * @param string $basenode 172 | * @return mixed 173 | */ 174 | public function to_xml($data = NULL, $structure = NULL, $basenode = 'xml') 175 | { 176 | if ($data === NULL && func_num_args() === 0) 177 | { 178 | $data = $this->_data; 179 | } 180 | 181 | if ($structure === NULL) 182 | { 183 | $structure = simplexml_load_string("<$basenode />"); 184 | } 185 | 186 | // Force it to be something useful 187 | if (is_array($data) === FALSE && is_object($data) === FALSE) 188 | { 189 | $data = (array) $data; 190 | } 191 | 192 | foreach ($data as $key => $value) 193 | { 194 | 195 | //change false/true to 0/1 196 | if (is_bool($value)) 197 | { 198 | $value = (int) $value; 199 | } 200 | 201 | // no numeric keys in our xml please! 202 | if (is_numeric($key)) 203 | { 204 | // make string key... 205 | $key = (singular($basenode) != $basenode) ? singular($basenode) : 'item'; 206 | } 207 | 208 | // replace anything not alpha numeric 209 | $key = preg_replace('/[^a-z_\-0-9]/i', '', $key); 210 | 211 | if ($key === '_attributes' && (is_array($value) || is_object($value))) 212 | { 213 | $attributes = $value; 214 | if (is_object($attributes)) 215 | { 216 | $attributes = get_object_vars($attributes); 217 | } 218 | 219 | foreach ($attributes as $attribute_name => $attribute_value) 220 | { 221 | $structure->addAttribute($attribute_name, $attribute_value); 222 | } 223 | } 224 | // if there is another array found recursively call this function 225 | elseif (is_array($value) || is_object($value)) 226 | { 227 | $node = $structure->addChild($key); 228 | 229 | // recursive call. 230 | $this->to_xml($value, $node, $key); 231 | } 232 | else 233 | { 234 | // add single node. 235 | $value = htmlspecialchars(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8'); 236 | 237 | $structure->addChild($key, $value); 238 | } 239 | } 240 | 241 | return $structure->asXML(); 242 | } 243 | 244 | /** 245 | * Format data as HTML 246 | * 247 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 248 | * to the constructor 249 | * @return mixed 250 | */ 251 | public function to_html($data = NULL) 252 | { 253 | // If no data is passed as a parameter, then use the data passed 254 | // via the constructor 255 | if ($data === NULL && func_num_args() === 0) 256 | { 257 | $data = $this->_data; 258 | } 259 | 260 | // Cast as an array if not already 261 | if (is_array($data) === FALSE) 262 | { 263 | $data = (array) $data; 264 | } 265 | 266 | // Check if it's a multi-dimensional array 267 | if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) 268 | { 269 | // Multi-dimensional array 270 | $headings = array_keys($data[0]); 271 | } 272 | else 273 | { 274 | // Single array 275 | $headings = array_keys($data); 276 | $data = [$data]; 277 | } 278 | 279 | // Load the table library 280 | $this->_CI->load->library('table'); 281 | 282 | $this->_CI->table->set_heading($headings); 283 | 284 | foreach ($data as $row) 285 | { 286 | // Suppressing the "array to string conversion" notice 287 | // Keep the "evil" @ here 288 | $row = @array_map('strval', $row); 289 | 290 | $this->_CI->table->add_row($row); 291 | } 292 | 293 | return $this->_CI->table->generate(); 294 | } 295 | 296 | /** 297 | * @link http://www.metashock.de/2014/02/create-csv-file-in-memory-php/ 298 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 299 | * to the constructor 300 | * @param string $delimiter The optional delimiter parameter sets the field 301 | * delimiter (one character only). NULL will use the default value (,) 302 | * @param string $enclosure The optional enclosure parameter sets the field 303 | * enclosure (one character only). NULL will use the default value (") 304 | * @return string A csv string 305 | */ 306 | public function to_csv($data = NULL, $delimiter = ',', $enclosure = '"') 307 | { 308 | // Use a threshold of 1 MB (1024 * 1024) 309 | $handle = fopen('php://temp/maxmemory:1048576', 'w'); 310 | if ($handle === FALSE) 311 | { 312 | return NULL; 313 | } 314 | 315 | // If no data is passed as a parameter, then use the data passed 316 | // via the constructor 317 | if ($data === NULL && func_num_args() === 0) 318 | { 319 | $data = $this->_data; 320 | } 321 | 322 | // If NULL, then set as the default delimiter 323 | if ($delimiter === NULL) 324 | { 325 | $delimiter = ','; 326 | } 327 | 328 | // If NULL, then set as the default enclosure 329 | if ($enclosure === NULL) 330 | { 331 | $enclosure = '"'; 332 | } 333 | 334 | // Cast as an array if not already 335 | if (is_array($data) === FALSE) 336 | { 337 | $data = (array) $data; 338 | } 339 | 340 | // Check if it's a multi-dimensional array 341 | if (isset($data[0]) && count($data) !== count($data, COUNT_RECURSIVE)) 342 | { 343 | // Multi-dimensional array 344 | $headings = array_keys($data[0]); 345 | } 346 | else 347 | { 348 | // Single array 349 | $headings = array_keys($data); 350 | $data = [$data]; 351 | } 352 | 353 | // Apply the headings 354 | fputcsv($handle, $headings, $delimiter, $enclosure); 355 | 356 | foreach ($data as $record) 357 | { 358 | // If the record is not an array, then break. This is because the 2nd param of 359 | // fputcsv() should be an array 360 | if (is_array($record) === FALSE) 361 | { 362 | break; 363 | } 364 | 365 | // Suppressing the "array to string conversion" notice. 366 | // Keep the "evil" @ here. 367 | $record = @ array_map('strval', $record); 368 | 369 | // Returns the length of the string written or FALSE 370 | fputcsv($handle, $record, $delimiter, $enclosure); 371 | } 372 | 373 | // Reset the file pointer 374 | rewind($handle); 375 | 376 | // Retrieve the csv contents 377 | $csv = stream_get_contents($handle); 378 | 379 | // Close the handle 380 | fclose($handle); 381 | 382 | return $csv; 383 | } 384 | 385 | /** 386 | * Encode data as json 387 | * 388 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 389 | * to the constructor 390 | * @return string Json representation of a value 391 | */ 392 | public function to_json($data = NULL) 393 | { 394 | // If no data is passed as a parameter, then use the data passed 395 | // via the constructor 396 | if ($data === NULL && func_num_args() === 0) 397 | { 398 | $data = $this->_data; 399 | } 400 | 401 | // Get the callback parameter (if set) 402 | $callback = $this->_CI->input->get('callback'); 403 | 404 | if (empty($callback) === TRUE) 405 | { 406 | return json_encode($data); 407 | } 408 | 409 | // We only honour a jsonp callback which are valid javascript identifiers 410 | elseif (preg_match('/^[a-z_\$][a-z0-9\$_]*(\.[a-z_\$][a-z0-9\$_]*)*$/i', $callback)) 411 | { 412 | // Return the data as encoded json with a callback 413 | return $callback.'('.json_encode($data).');'; 414 | } 415 | 416 | // An invalid jsonp callback function provided. 417 | // Though I don't believe this should be hardcoded here 418 | $data['warning'] = 'INVALID JSONP CALLBACK: '.$callback; 419 | 420 | return json_encode($data); 421 | } 422 | 423 | /** 424 | * Encode data as a serialized array 425 | * 426 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 427 | * to the constructor 428 | * @return string Serialized data 429 | */ 430 | public function to_serialized($data = NULL) 431 | { 432 | // If no data is passed as a parameter, then use the data passed 433 | // via the constructor 434 | if ($data === NULL && func_num_args() === 0) 435 | { 436 | $data = $this->_data; 437 | } 438 | 439 | return serialize($data); 440 | } 441 | 442 | /** 443 | * Format data using a PHP structure 444 | * 445 | * @param mixed|NULL $data Optional data to pass, so as to override the data passed 446 | * to the constructor 447 | * @return mixed String representation of a variable 448 | */ 449 | public function to_php($data = NULL) 450 | { 451 | // If no data is passed as a parameter, then use the data passed 452 | // via the constructor 453 | if ($data === NULL && func_num_args() === 0) 454 | { 455 | $data = $this->_data; 456 | } 457 | 458 | return var_export($data, TRUE); 459 | } 460 | 461 | // INTERNAL FUNCTIONS 462 | 463 | /** 464 | * @param string $data XML string 465 | * @return array XML element object; otherwise, empty array 466 | */ 467 | protected function _from_xml($data) 468 | { 469 | return $data ? (array) simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA) : []; 470 | } 471 | 472 | /** 473 | * @param string $data CSV string 474 | * @param string $delimiter The optional delimiter parameter sets the field 475 | * delimiter (one character only). NULL will use the default value (,) 476 | * @param string $enclosure The optional enclosure parameter sets the field 477 | * enclosure (one character only). NULL will use the default value (") 478 | * @return array A multi-dimensional array with the outer array being the number of rows 479 | * and the inner arrays the individual fields 480 | */ 481 | protected function _from_csv($data, $delimiter = ',', $enclosure = '"') 482 | { 483 | // If NULL, then set as the default delimiter 484 | if ($delimiter === NULL) 485 | { 486 | $delimiter = ','; 487 | } 488 | 489 | // If NULL, then set as the default enclosure 490 | if ($enclosure === NULL) 491 | { 492 | $enclosure = '"'; 493 | } 494 | 495 | return str_getcsv($data, $delimiter, $enclosure); 496 | } 497 | 498 | /** 499 | * @param string $data Encoded json string 500 | * @return mixed Decoded json string with leading and trailing whitespace removed 501 | */ 502 | protected function _from_json($data) 503 | { 504 | return json_decode(trim($data)); 505 | } 506 | 507 | /** 508 | * @param string $data Data to unserialize 509 | * @return mixed Unserialized data 510 | */ 511 | protected function _from_serialize($data) 512 | { 513 | return unserialize(trim($data)); 514 | } 515 | 516 | /** 517 | * @param string $data Data to trim leading and trailing whitespace 518 | * @return string Data with leading and trailing whitespace removed 519 | */ 520 | protected function _from_php($data) 521 | { 522 | return trim($data); 523 | } 524 | } 525 | -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /application/config/rest.php: -------------------------------------------------------------------------------- 1 | function($username, $password) 150 | | In other cases override the function _perform_library_auth in your controller 151 | | 152 | | For digest authentication the library function should return already a stored 153 | | md5(username:restrealm:password) for that username 154 | | 155 | | e.g: md5('admin:REST API:1234') = '1e957ebc35631ab22d5bd6526bd14ea2' 156 | | 157 | */ 158 | $config['auth_library_class'] = ''; 159 | $config['auth_library_function'] = ''; 160 | 161 | /* 162 | |-------------------------------------------------------------------------- 163 | | Override auth types for specific class/method 164 | |-------------------------------------------------------------------------- 165 | | 166 | | Set specific authentication types for methods within a class (controller) 167 | | 168 | | Set as many config entries as needed. Any methods not set will use the default 'rest_auth' config value. 169 | | 170 | | e.g: 171 | | 172 | | $config['auth_override_class_method']['deals']['view'] = 'none'; 173 | | $config['auth_override_class_method']['deals']['insert'] = 'digest'; 174 | | $config['auth_override_class_method']['accounts']['user'] = 'basic'; 175 | | $config['auth_override_class_method']['dashboard']['*'] = 'none|digest|basic'; 176 | | 177 | | Here 'deals', 'accounts' and 'dashboard' are controller names, 'view', 'insert' and 'user' are methods within. An asterisk may also be used to specify an authentication method for an entire classes methods. Ex: $config['auth_override_class_method']['dashboard']['*'] = 'basic'; (NOTE: leave off the '_get' or '_post' from the end of the method name) 178 | | Acceptable values are; 'none', 'digest' and 'basic'. 179 | | 180 | */ 181 | // $config['auth_override_class_method']['deals']['view'] = 'none'; 182 | // $config['auth_override_class_method']['deals']['insert'] = 'digest'; 183 | // $config['auth_override_class_method']['accounts']['user'] = 'basic'; 184 | // $config['auth_override_class_method']['dashboard']['*'] = 'basic'; 185 | 186 | 187 | // ---Uncomment list line for the wildard unit test 188 | // $config['auth_override_class_method']['wildcard_test_cases']['*'] = 'basic'; 189 | 190 | /* 191 | |-------------------------------------------------------------------------- 192 | | Override auth types for specific 'class/method/HTTP method' 193 | |-------------------------------------------------------------------------- 194 | | 195 | | example: 196 | | 197 | | $config['auth_override_class_method_http']['deals']['view']['get'] = 'none'; 198 | | $config['auth_override_class_method_http']['deals']['insert']['post'] = 'none'; 199 | | $config['auth_override_class_method_http']['deals']['*']['options'] = 'none'; 200 | */ 201 | 202 | // ---Uncomment list line for the wildard unit test 203 | // $config['auth_override_class_method_http']['wildcard_test_cases']['*']['options'] = 'basic'; 204 | 205 | /* 206 | |-------------------------------------------------------------------------- 207 | | REST Login Usernames 208 | |-------------------------------------------------------------------------- 209 | | 210 | | Array of usernames and passwords for login, if ldap is configured this is ignored 211 | | 212 | */ 213 | $config['rest_valid_logins'] = ['admin' => '1234']; 214 | 215 | /* 216 | |-------------------------------------------------------------------------- 217 | | Global IP White-listing 218 | |-------------------------------------------------------------------------- 219 | | 220 | | Limit connections to your REST server to White-listed IP addresses 221 | | 222 | | Usage: 223 | | 1. Set to TRUE and select an auth option for extreme security (client's IP 224 | | address must be in white-list and they must also log in) 225 | | 2. Set to TRUE with auth set to FALSE to allow White-listed IPs access with no login 226 | | 3. Set to FALSE but set 'auth_override_class_method' to 'white-list' to 227 | | restrict certain methods to IPs in your white-list 228 | | 229 | */ 230 | $config['rest_ip_whitelist_enabled'] = FALSE; 231 | 232 | /* 233 | |-------------------------------------------------------------------------- 234 | | REST Handle Exceptions 235 | |-------------------------------------------------------------------------- 236 | | 237 | | Handle exceptions caused by the controller 238 | | 239 | */ 240 | $config['rest_handle_exceptions'] = TRUE; 241 | 242 | /* 243 | |-------------------------------------------------------------------------- 244 | | REST IP White-list 245 | |-------------------------------------------------------------------------- 246 | | 247 | | Limit connections to your REST server with a comma separated 248 | | list of IP addresses 249 | | 250 | | e.g: '123.456.789.0, 987.654.32.1' 251 | | 252 | | 127.0.0.1 and 0.0.0.0 are allowed by default 253 | | 254 | */ 255 | $config['rest_ip_whitelist'] = ''; 256 | 257 | /* 258 | |-------------------------------------------------------------------------- 259 | | Global IP Blacklisting 260 | |-------------------------------------------------------------------------- 261 | | 262 | | Prevent connections to the REST server from blacklisted IP addresses 263 | | 264 | | Usage: 265 | | 1. Set to TRUE and add any IP address to 'rest_ip_blacklist' 266 | | 267 | */ 268 | $config['rest_ip_blacklist_enabled'] = FALSE; 269 | 270 | /* 271 | |-------------------------------------------------------------------------- 272 | | REST IP Blacklist 273 | |-------------------------------------------------------------------------- 274 | | 275 | | Prevent connections from the following IP addresses 276 | | 277 | | e.g: '123.456.789.0, 987.654.32.1' 278 | | 279 | */ 280 | $config['rest_ip_blacklist'] = ''; 281 | 282 | /* 283 | |-------------------------------------------------------------------------- 284 | | REST Database Group 285 | |-------------------------------------------------------------------------- 286 | | 287 | | Connect to a database group for keys, logging, etc. It will only connect 288 | | if you have any of these features enabled 289 | | 290 | */ 291 | $config['rest_database_group'] = 'default'; 292 | 293 | /* 294 | |-------------------------------------------------------------------------- 295 | | REST API Keys Table Name 296 | |-------------------------------------------------------------------------- 297 | | 298 | | The table name in your database that stores API keys 299 | | 300 | */ 301 | $config['rest_keys_table'] = 'keys'; 302 | 303 | /* 304 | |-------------------------------------------------------------------------- 305 | | REST Enable Keys 306 | |-------------------------------------------------------------------------- 307 | | 308 | | When set to TRUE, the REST API will look for a column name called 'key'. 309 | | If no key is provided, the request will result in an error. To override the 310 | | column name see 'rest_key_column' 311 | | 312 | | Default table schema: 313 | | CREATE TABLE `keys` ( 314 | | `id` INT(11) NOT NULL AUTO_INCREMENT, 315 | | `user_id` INT(11) NOT NULL, 316 | | `key` VARCHAR(40) NOT NULL, 317 | | `level` INT(2) NOT NULL, 318 | | `ignore_limits` TINYINT(1) NOT NULL DEFAULT '0', 319 | | `is_private_key` TINYINT(1) NOT NULL DEFAULT '0', 320 | | `ip_addresses` TEXT NULL DEFAULT NULL, 321 | | `date_created` INT(11) NOT NULL, 322 | | PRIMARY KEY (`id`) 323 | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 324 | | 325 | */ 326 | $config['rest_enable_keys'] = FALSE; 327 | 328 | /* 329 | |-------------------------------------------------------------------------- 330 | | REST Table Key Column Name 331 | |-------------------------------------------------------------------------- 332 | | 333 | | If not using the default table schema in 'rest_enable_keys', specify the 334 | | column name to match e.g. my_key 335 | | 336 | */ 337 | $config['rest_key_column'] = 'key'; 338 | 339 | /* 340 | |-------------------------------------------------------------------------- 341 | | REST API Limits method 342 | |-------------------------------------------------------------------------- 343 | | 344 | | Specify the method used to limit the API calls 345 | | 346 | | Available methods are : 347 | | $config['rest_limits_method'] = 'IP_ADDRESS'; // Put a limit per ip address 348 | | $config['rest_limits_method'] = 'API_KEY'; // Put a limit per api key 349 | | $config['rest_limits_method'] = 'METHOD_NAME'; // Put a limit on method calls 350 | | $config['rest_limits_method'] = 'ROUTED_URL'; // Put a limit on the routed URL 351 | | 352 | */ 353 | $config['rest_limits_method'] = 'ROUTED_URL'; 354 | 355 | /* 356 | |-------------------------------------------------------------------------- 357 | | REST Key Length 358 | |-------------------------------------------------------------------------- 359 | | 360 | | Length of the created keys. Check your default database schema on the 361 | | maximum length allowed 362 | | 363 | | Note: The maximum length is 40 364 | | 365 | */ 366 | $config['rest_key_length'] = 40; 367 | 368 | /* 369 | |-------------------------------------------------------------------------- 370 | | REST API Key Variable 371 | |-------------------------------------------------------------------------- 372 | | 373 | | Custom header to specify the API key 374 | 375 | | Note: Custom headers with the X- prefix are deprecated as of 376 | | 2012/06/12. See RFC 6648 specification for more details 377 | | 378 | */ 379 | $config['rest_key_name'] = 'X-API-KEY'; 380 | 381 | /* 382 | |-------------------------------------------------------------------------- 383 | | REST Enable Logging 384 | |-------------------------------------------------------------------------- 385 | | 386 | | When set to TRUE, the REST API will log actions based on the column names 'key', 'date', 387 | | 'time' and 'ip_address'. This is a general rule that can be overridden in the 388 | | $this->method array for each controller 389 | | 390 | | Default table schema: 391 | | CREATE TABLE `logs` ( 392 | | `id` INT(11) NOT NULL AUTO_INCREMENT, 393 | | `uri` VARCHAR(255) NOT NULL, 394 | | `method` VARCHAR(6) NOT NULL, 395 | | `params` TEXT DEFAULT NULL, 396 | | `api_key` VARCHAR(40) NOT NULL, 397 | | `ip_address` VARCHAR(45) NOT NULL, 398 | | `time` INT(11) NOT NULL, 399 | | `rtime` FLOAT DEFAULT NULL, 400 | | `authorized` VARCHAR(1) NOT NULL, 401 | | `response_code` smallint(3) DEFAULT '0', 402 | | PRIMARY KEY (`id`) 403 | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 404 | | 405 | */ 406 | $config['rest_enable_logging'] = FALSE; 407 | 408 | /* 409 | |-------------------------------------------------------------------------- 410 | | REST API Logs Table Name 411 | |-------------------------------------------------------------------------- 412 | | 413 | | If not using the default table schema in 'rest_enable_logging', specify the 414 | | table name to match e.g. my_logs 415 | | 416 | */ 417 | $config['rest_logs_table'] = 'logs'; 418 | 419 | /* 420 | |-------------------------------------------------------------------------- 421 | | REST Method Access Control 422 | |-------------------------------------------------------------------------- 423 | | When set to TRUE, the REST API will check the access table to see if 424 | | the API key can access that controller. 'rest_enable_keys' must be enabled 425 | | to use this 426 | | 427 | | Default table schema: 428 | | CREATE TABLE `access` ( 429 | | `id` INT(11) unsigned NOT NULL AUTO_INCREMENT, 430 | | `key` VARCHAR(40) NOT NULL DEFAULT '', 431 | | `all_access` TINYINT(1) NOT NULL DEFAULT '0', 432 | | `controller` VARCHAR(50) NOT NULL DEFAULT '', 433 | | `date_created` DATETIME DEFAULT NULL, 434 | | `date_modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 435 | | PRIMARY KEY (`id`) 436 | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 437 | | 438 | */ 439 | $config['rest_enable_access'] = FALSE; 440 | 441 | /* 442 | |-------------------------------------------------------------------------- 443 | | REST API Access Table Name 444 | |-------------------------------------------------------------------------- 445 | | 446 | | If not using the default table schema in 'rest_enable_access', specify the 447 | | table name to match e.g. my_access 448 | | 449 | */ 450 | $config['rest_access_table'] = 'access'; 451 | 452 | /* 453 | |-------------------------------------------------------------------------- 454 | | REST API Param Log Format 455 | |-------------------------------------------------------------------------- 456 | | 457 | | When set to TRUE, the REST API log parameters will be stored in the database as JSON 458 | | Set to FALSE to log as serialized PHP 459 | | 460 | */ 461 | $config['rest_logs_json_params'] = FALSE; 462 | 463 | /* 464 | |-------------------------------------------------------------------------- 465 | | REST Enable Limits 466 | |-------------------------------------------------------------------------- 467 | | 468 | | When set to TRUE, the REST API will count the number of uses of each method 469 | | by an API key each hour. This is a general rule that can be overridden in the 470 | | $this->method array in each controller 471 | | 472 | | Default table schema: 473 | | CREATE TABLE `limits` ( 474 | | `id` INT(11) NOT NULL AUTO_INCREMENT, 475 | | `uri` VARCHAR(255) NOT NULL, 476 | | `count` INT(10) NOT NULL, 477 | | `hour_started` INT(11) NOT NULL, 478 | | `api_key` VARCHAR(40) NOT NULL, 479 | | PRIMARY KEY (`id`) 480 | | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 481 | | 482 | | To specify the limits within the controller's __construct() method, add per-method 483 | | limits with: 484 | | 485 | | $this->method['METHOD_NAME']['limit'] = [NUM_REQUESTS_PER_HOUR]; 486 | | 487 | | See application/controllers/api/example.php for examples 488 | */ 489 | $config['rest_enable_limits'] = FALSE; 490 | 491 | /* 492 | |-------------------------------------------------------------------------- 493 | | REST API Limits Table Name 494 | |-------------------------------------------------------------------------- 495 | | 496 | | If not using the default table schema in 'rest_enable_limits', specify the 497 | | table name to match e.g. my_limits 498 | | 499 | */ 500 | $config['rest_limits_table'] = 'limits'; 501 | 502 | /* 503 | |-------------------------------------------------------------------------- 504 | | REST Ignore HTTP Accept 505 | |-------------------------------------------------------------------------- 506 | | 507 | | Set to TRUE to ignore the HTTP Accept and speed up each request a little. 508 | | Only do this if you are using the $this->rest_format or /format/xml in URLs 509 | | 510 | */ 511 | $config['rest_ignore_http_accept'] = FALSE; 512 | 513 | /* 514 | |-------------------------------------------------------------------------- 515 | | REST AJAX Only 516 | |-------------------------------------------------------------------------- 517 | | 518 | | Set to TRUE to allow AJAX requests only. Set to FALSE to accept HTTP requests 519 | | 520 | | Note: If set to TRUE and the request is not AJAX, a 505 response with the 521 | | error message 'Only AJAX requests are accepted.' will be returned. 522 | | 523 | | Hint: This is good for production environments 524 | | 525 | */ 526 | $config['rest_ajax_only'] = FALSE; 527 | 528 | /* 529 | |-------------------------------------------------------------------------- 530 | | REST Language File 531 | |-------------------------------------------------------------------------- 532 | | 533 | | Language file to load from the language directory 534 | | 535 | */ 536 | $config['rest_language'] = 'english'; 537 | 538 | /* 539 | |-------------------------------------------------------------------------- 540 | | CORS Check 541 | |-------------------------------------------------------------------------- 542 | | 543 | | Set to TRUE to enable Cross-Origin Resource Sharing (CORS). Useful if you 544 | | are hosting your API on a different domain from the application that 545 | | will access it through a browser 546 | | 547 | */ 548 | $config['check_cors'] = FALSE; 549 | 550 | /* 551 | |-------------------------------------------------------------------------- 552 | | CORS Allowable Headers 553 | |-------------------------------------------------------------------------- 554 | | 555 | | If using CORS checks, set the allowable headers here 556 | | 557 | */ 558 | $config['allowed_cors_headers'] = [ 559 | 'Origin', 560 | 'X-Requested-With', 561 | 'Content-Type', 562 | 'Accept', 563 | 'Access-Control-Request-Method' 564 | ]; 565 | 566 | /* 567 | |-------------------------------------------------------------------------- 568 | | CORS Allowable Methods 569 | |-------------------------------------------------------------------------- 570 | | 571 | | If using CORS checks, you can set the methods you want to be allowed 572 | | 573 | */ 574 | $config['allowed_cors_methods'] = [ 575 | 'GET', 576 | 'POST', 577 | 'OPTIONS', 578 | 'PUT', 579 | 'PATCH', 580 | 'DELETE' 581 | ]; 582 | 583 | /* 584 | |-------------------------------------------------------------------------- 585 | | CORS Allow Any Domain 586 | |-------------------------------------------------------------------------- 587 | | 588 | | Set to TRUE to enable Cross-Origin Resource Sharing (CORS) from any 589 | | source domain 590 | | 591 | */ 592 | $config['allow_any_cors_domain'] = FALSE; 593 | 594 | /* 595 | |-------------------------------------------------------------------------- 596 | | CORS Allowable Domains 597 | |-------------------------------------------------------------------------- 598 | | 599 | | Used if $config['check_cors'] is set to TRUE and $config['allow_any_cors_domain'] 600 | | is set to FALSE. Set all the allowable domains within the array 601 | | 602 | | e.g. $config['allowed_origins'] = ['http://www.example.com', 'https://spa.example.com'] 603 | | 604 | */ 605 | $config['allowed_cors_origins'] = []; 606 | --------------------------------------------------------------------------------