Skip to content

Commit 00a1a82

Browse files
committed
Initial Commit. Needs work ;)
0 parents  commit 00a1a82

File tree

5 files changed

+439
-0
lines changed

5 files changed

+439
-0
lines changed

classes/controller/api.php

+251
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
<?php
2+
abstract class Controller_API extends OAuth2_Controller
3+
{
4+
/**
5+
* @var Object Request Payload
6+
*/
7+
protected $_request_payload = NULL;
8+
9+
/**
10+
* @var Object Response Payload
11+
*/
12+
protected $_response_payload = NULL;
13+
14+
/**
15+
* @var array Response Metadata
16+
*/
17+
protected $_response_metadata = array('error' => FALSE);
18+
19+
/**
20+
* @var array Response Links
21+
*/
22+
protected $_response_links = array();
23+
24+
/**
25+
* @var array Map of HTTP methods -> actions
26+
*/
27+
protected $_action_map = array
28+
(
29+
Http_Request::POST => 'post', // Typically Create..
30+
Http_Request::GET => 'get',
31+
Http_Request::PUT => 'put', // Typically Update..
32+
Http_Request::DELETE => 'delete',
33+
);
34+
35+
/**
36+
* @var array List of HTTP methods which support body content
37+
*/
38+
protected $_methods_with_body_content = array
39+
(
40+
Http_Request::POST,
41+
Http_Request::PUT,
42+
);
43+
44+
/**
45+
* @var array List of HTTP methods which may be cached
46+
*/
47+
protected $_cacheable_methods = array
48+
(
49+
Http_Request::GET,
50+
);
51+
52+
public function before()
53+
{
54+
parent::before();
55+
56+
$this->_parse_request();
57+
}
58+
59+
public function after()
60+
{
61+
$this->_prepare_response();
62+
63+
parent::after();
64+
}
65+
66+
/**
67+
* Parse the request...
68+
*/
69+
protected function _parse_request()
70+
{
71+
// Override the method if needed.
72+
$this->request->method(Arr::get(
73+
$_SERVER,
74+
'HTTP_X_HTTP_METHOD_OVERRIDE',
75+
$this->request->method()
76+
));
77+
78+
// Is that a valid method?
79+
if ( ! isset($this->_action_map[$this->request->method()]))
80+
{
81+
// TODO .. add to the if (maybe??) .. method_exists($this, 'action_'.$this->request->method())
82+
throw new Http_Exception_405('The :method method is not supported. Supported methods are :allowed_methods', array(
83+
':method' => $method,
84+
':allowed_methods' => implode(', ', array_keys($this->_action_map)),
85+
));
86+
}
87+
88+
// Are we be expecting body content as part of the request?
89+
if (in_array($this->request->method(), $this->_methods_with_body_content))
90+
{
91+
$this->_parse_request_body();
92+
}
93+
}
94+
95+
/**
96+
* @todo Support more than just JSON
97+
*/
98+
protected function _parse_request_body()
99+
{
100+
if ($this->request->body() == '')
101+
return;
102+
103+
try
104+
{
105+
$this->_request_payload = json_decode($this->request->body(), TRUE);
106+
107+
if ( ! is_array($this->_request_payload) AND ! is_object($this->_request_payload))
108+
throw new Http_Exception_400('Invalid json supplied. \':json\'', array(
109+
':json' => $this->request->body(),
110+
));
111+
}
112+
catch (Exception $e)
113+
{
114+
throw new Http_Exception_400('Invalid json supplied. \':json\'', array(
115+
':json' => $this->request->body(),
116+
));
117+
}
118+
}
119+
120+
protected function _prepare_response()
121+
{
122+
// Should we prevent this request from being cached?
123+
if ( ! in_array($this->request->method(), $this->_cacheable_methods))
124+
{
125+
$this->response->headers('cache-control', 'no-cache, no-store, max-age=0, must-revalidate');
126+
}
127+
128+
$this->_prepare_response_body();
129+
}
130+
131+
/**
132+
* @todo Support more than just JSON
133+
*/
134+
protected function _prepare_response_body()
135+
{
136+
try
137+
{
138+
// Set the correct content-type header
139+
$this->response->headers('Content-Type', 'application/json');
140+
141+
$response = array (
142+
'metadata' => $this->_response_metadata,
143+
'links' => $this->_response_links,
144+
'payload' => $this->_response_payload
145+
);
146+
147+
// Format the reponse as JSON
148+
$this->response->body(json_encode($response));
149+
}
150+
catch (Exception $e)
151+
{
152+
Kohana::$log->add(Log::ERROR, 'Error while formatting response: '.$e->getMessage());
153+
throw new Http_Exception_500('Error while formatting response');
154+
}
155+
}
156+
157+
/**
158+
* Execute the API call..
159+
*/
160+
public function action_index()
161+
{
162+
// Get the basic verb based action..
163+
$action = $this->_action_map[$this->request->method()];
164+
165+
// If this is a custom action, lets make sure we use it.
166+
if ($this->request->param('custom', FALSE) !== FALSE)
167+
{
168+
$action .= '_'.$this->request->param('custom');
169+
}
170+
171+
// If we are acting on a collection, append _collection to the action name.
172+
if ($this->request->param('id', FALSE) === FALSE)
173+
{
174+
$action .= '_collection';
175+
}
176+
177+
// Execute the request
178+
if (method_exists($this, $action))
179+
{
180+
try
181+
{
182+
$this->_execute($action);
183+
}
184+
catch (Exception $e)
185+
{
186+
$this->response->status(500);
187+
$this->_response_payload = NULL;
188+
}
189+
}
190+
else
191+
{
192+
/**
193+
* @todo .. HTTP_Exception_405 is more approperiate, sometimes.
194+
* Need to figure out a way to decide which to send...
195+
*/
196+
throw new HTTP_Exception_404('The requested URL :uri was not found on this server.', array(
197+
':uri' => $this->request->uri()
198+
));
199+
}
200+
}
201+
202+
protected function _execute($action)
203+
{
204+
try
205+
{
206+
$this->{$action}();
207+
}
208+
catch (Exception $e)
209+
{
210+
$this->response->status(500);
211+
212+
$this->_response_metadata = array(
213+
'error' => TRUE,
214+
'type' => 'error_exception',
215+
);
216+
217+
$this->_response_payload = array(
218+
'message' => $e->getMessage(),
219+
'code' => $e->getCode(),
220+
);
221+
222+
$this->_response_links = NULL;
223+
}
224+
}
225+
226+
protected function _generate_link($method, $uri, $parameters = NULL)
227+
{
228+
$link = array(
229+
'method' => $method,
230+
'url' => $uri,
231+
'parameters' => array(),
232+
);
233+
234+
if ($parameters !== NULL)
235+
{
236+
foreach ($parameters as $search => $replace)
237+
{
238+
if (is_numeric($search))
239+
{
240+
$link['parameters'][':'.$replace] = $replace;
241+
}
242+
else
243+
{
244+
$link['parameters'][$search] = $replace;
245+
}
246+
}
247+
}
248+
249+
return $link;
250+
}
251+
}

config/userguide.php

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php defined('SYSPATH') or die('No direct script access.');
2+
3+
return array(
4+
// Leave this alone
5+
'modules' => array(
6+
7+
// This should be the path to this modules userguide pages, without the 'guide/'. Ex: '/guide/modulename/' would be 'modulename'
8+
'modapi' => array(
9+
10+
// Whether this modules userguide pages should be shown
11+
'enabled' => TRUE,
12+
13+
// The name that should show up on the userguide index page
14+
'name' => 'API',
15+
16+
// A short description of this module, shown on the index page
17+
'description' => 'API',
18+
19+
// Copyright message, shown in the footer for this module
20+
'copyright' => '&copy; 201'.date('Y').' Managed I.T.',
21+
)
22+
)
23+
);

0 commit comments

Comments
 (0)