source: Dev/branches/rest-dojo-ui/server/api.php @ 274

Last change on this file since 274 was 274, checked in by hendrikvanantwerpen, 13 years ago
  • [Client] Moved pages in subtree of rft/, allowing controllers next to them.
  • [Client] Created questions page, gives overview and allows adding.
  • [Client] Page controllers inherit from _Page, because the previous mechanism w

asn't working.

  • [Client] Added new user registration.
  • [Server] Changed user passwords to passwordHash/passwordSalt combination.
  • [Server] Added simple object marshalling and unmarshalling to preserve types.
  • [Server] Added ResearchToolObjectInterface? with static create() method. Implemented for all model classes.
File size: 6.6 KB
Line 
1<?php
2
3error_reporting(E_ALL);
4ini_set('display_errors', True);
5
6require_once 'tonic/lib/tonic.php';
7require_once 'classes/master.php';
8
9use Tonic\Request as Request;
10use Tonic\Response as Response;
11use Tonic\ResponseException as ResponseException;
12use Tonic\Resource as Resource;
13
14function set_session_cookie($response, $user) {
15    $response->addHeader('Set-Cookie', 'rft_uid=' . $user->uid . '; Max-Age: 3600; Path=' . $response->request->baseUri);
16}
17
18function restore_session($response) {
19    if (isset($_COOKIE['rft_uid'])) {
20        $user = Auth::restore($_COOKIE['rft_uid']);
21        if ($user) {
22            set_session_cookie($response, $user);
23            return $user;
24        }
25    }
26    throw new ResponseException("No valid session found", Response::UNAUTHORIZED);
27}
28
29function get_clean_uri($request) {
30    return substr($request->uri, strlen($request->baseUri));
31}
32
33function add_default_headers($response) {
34    $response->addHeader('Content-Type', 'application/json');
35    $response->addHeader('Cache-Control', 'no-cache, must-revalidate');
36    $response->addHeader('Expires', 'Sat, 26 Jul 1997 05:00:00 GMT');
37}
38
39/**
40 *  @uri /login
41 */
42class LoginResource extends Resource {
43
44    function post($request) {
45        $response = new Response($request);
46
47        $user = null;
48        if (!empty($request->data)) {
49            $user = Auth::login($request->data['email'], $request->data['password']);
50            if (!$user) {
51                throw new ResponseException("Incorrect email and password", Response::UNAUTHORIZED);
52            }
53            set_session_cookie($response, $user);
54        } else {
55            $user = restore_session($response);
56        }
57        $response->body = $user;
58        return $response;
59    }
60
61}
62
63/**
64 *  @uri /register
65 */
66class RegisterResource extends Resource {
67
68    function post($request) {
69        $response = new Response($request);
70
71        $user = null;
72        if (!empty($request->data)) {
73            $user = Auth::register($request->data['email'], $request->data['password']);
74            set_session_cookie($response, $user);
75        } else {
76            throw new ResponseException("No email and password provided.",Response::BADREQUEST);
77        }
78        $response->body = $user;
79        return $response;
80    }
81
82}
83
84/**
85 * @uri /data/\w+
86 */
87class DataCollectionResource extends Resource {
88
89    function getType($request) {
90        $uri = get_clean_uri($request);
91        $path = explode('/', $uri);
92        $type = $path[2];
93        return $type;
94    }
95
96    function get($request) {
97        $response = new Response($request);
98        restore_session($response);
99
100        $type = $this->getType($request);
101        $objects = $type::get(array());
102
103        $response->body = $objects;
104        return $response;
105    }
106
107    function post($request) {
108        $response = new Response($request);
109        restore_session($response);
110
111        $type = $this->getType($request);
112        $onlyAdd = $request->ifNoneMatch('*');
113        $onlyUpdate = $request->ifMatch('*');
114
115        $object = FALSE;
116        if (isset($request->data->uid)) {
117            $objects = $type::get(array('uid' => $request->data->uid));
118            if (!empty($objects)) {
119                $object = $objects[0];
120            }
121        }
122
123        if (( $onlyUpdate && !$object ) || ( $onlyAdd && $object )) {
124            throw new ResponseException("Update/Create and existing object mismatch", Response::PRECONDITIONFAILED);
125        }
126
127        if (!$object) {
128            $object = new $type(null);
129            $response->code = Response::CREATED;
130        } else {
131            $response->code = Response::OK;
132        }
133        foreach ($request->data as $key => $val) {
134            $object->$key = $val;
135        }
136        if (!$object->save()) {
137            throw new ResponseException("Save failed", Response::INTERNALSERVERERROR);
138        }
139
140        $response->body = $object;
141        return $response;
142    }
143
144}
145
146/**
147 * @uri /data/\w+/\w+
148 */
149class DataObjectResource extends Resource {
150
151    function getTypeAndUid($request) {
152        $uri = get_clean_uri($request);
153        $path = explode('/', $uri);
154        $type = $path[2];
155        $uid = $path[3];
156        return array('type' => $type, 'uid' => $uid);
157    }
158
159    function get($request) {
160        $response = new Response($request);
161        restore_session($response);
162
163        $info = $this->getTypeAndUid($request);
164        $objects = $info['type']::get(array('uid' => $info['uid']));
165        if (empty($objects)) {
166            throw new ResponseException("Object not found", Response::NOTFOUND);
167        }
168
169        $response->body = $objects[0];
170        return $response;
171    }
172
173    function put($request) {
174        $response = new Response($request);
175        restore_session($response);
176
177        $info = $this->getTypeAndUid($request);
178        $onlyAdd = $request->ifNoneMatch('*');
179        $onlyUpdate = $request->ifMatch('*');
180
181        $object = FALSE;
182        $objects = $info['type']::get(array('uid' => $info['uid']));
183        if (!empty($objects)) {
184            $object = $objects[0];
185        }
186
187        if (( $onlyUpdate && !$object ) || ( $onlyAdd && $object )) {
188            throw new ResponseException("Update/Create and existing object mismatch", Response::PRECONDITIONFAILED);
189        }
190
191        if (!$object) {
192            $object = new $info['type']($info->uid);
193            $response->code = Response::CREATED;
194        } else {
195            $response->code = Response::OK;
196        }
197        foreach ($request->data as $key => $val) {
198            $object->$key = $val;
199        }
200        if (!$object->save()) {
201            throw new ResponseException("Save failed", Response::INTERNALSERVERERROR);
202        }
203
204        $response->body = $object;
205        return $response;
206    }
207
208    function delete($request) {
209        restore_session(new Response($request));
210        throw new ReponseException("Delete not implemented", Response::METHODNOTALLOWED);
211    }
212
213}
214
215$request = new Request();
216$path = $request->uri;
217$idx = strrpos($path, 'api.php');
218if ($idx !== FALSE) {
219    $baseUri = substr($path, 0, $idx + 7);
220    $request->baseUri = $baseUri;
221}
222$request->data = Marshaller::unmarshall(json_decode($request->data));
223try {
224    $resource = $request->loadResource();
225    $response = $resource->exec($request);
226} catch (ResponseException $e) {
227    $response = $e->response($request);
228    $response->body = array('errorMsg' => $response->body);
229} catch (Exception $e) {
230    $response = new Response($request);
231    $response->code = Response::INTERNALSERVERERROR;
232    $response->body = array('errorMsg' => "Unhandled exception: " . $e);
233}
234add_default_headers($response);
235$response->body = json_encode(Marshaller::marshall($response->body));
236$response->output();
237
238?>
Note: See TracBrowser for help on using the repository browser.