source: Dev/branches/jos-branch/server/api.php @ 266

Last change on this file since 266 was 263, checked in by hendrikvanantwerpen, 13 years ago
  • [Client] Finished page framework. See rft/ui/content.js or test files for details.
  • [Client] Allow login by pressing Enter.
  • [API] On exception include details in json response.
  • [Server Use Exceptions when save() fails, iso return values.
File size: 6.1 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        $data = null;
49        if (!empty($request->data)) {
50            $data = json_decode($request->data, true);
51        }
52        if (!empty($data)) {
53            $user = Auth::login($data['username'], sha1($data['password']));
54            if (!$user) {
55                throw new ResponseException("Incorrect username and password", Response::UNAUTHORIZED);
56            }
57            set_session_cookie($response, $user);
58        } else {
59            $user = restore_session($response);
60        }
61        $response->body = json_encode($user);
62        return $response;
63    }
64
65}
66
67/**
68 * @uri /data/\w+
69 */
70class DataCollectionResource extends Resource {
71
72    function getType($request) {
73        $uri = get_clean_uri($request);
74        $path = explode('/', $uri);
75        $type = $path[2];
76        return $type;
77    }
78
79    function get($request) {
80        $response = new Response($request);
81        restore_session($response);
82
83        $type = $this->getType($request);
84        $objects = $type::get(array());
85        //$objects = array_map(function($val) { return array('uid' => $val->uid); }, $objects);
86
87        $response->body = json_encode($objects);
88        return $response;
89    }
90
91    function post($request) {
92        $response = new Response($request);
93        restore_session($response);
94
95        $type = $this->getType($request);
96        $data = json_decode($request->data);
97        $onlyAdd = $request->ifNoneMatch('*');
98        $onlyUpdate = $request->ifMatch('*');
99
100        $object = FALSE;
101        if (isset($data->uid)) {
102            $objects = $type::get(array('uid' => $data->uid));
103            if (!empty($objects)) {
104                $object = $objects[0];
105            }
106        }
107
108        if (( $onlyUpdate && !$object ) || ( $onlyAdd && $object )) {
109            throw new ResponseException("Update/Create and existing object mismatch", Response::PRECONDITIONFAILED);
110        }
111
112        if (!$object) {
113            $object = new $type(null);
114            $response->code = Response::CREATED;
115        } else {
116            $response->code = Response::OK;
117        }
118        foreach ($data as $key => $val) {
119            $object->$key = $val;
120        }
121        $object->save();
122
123        $response->body = json_encode($object);
124        return $response;
125    }
126
127}
128
129/**
130 * @uri /data/\w+/\w+
131 */
132class DataObjectResource extends Resource {
133
134    function getTypeAndUid($request) {
135        $uri = get_clean_uri($request);
136        $path = explode('/', $uri);
137        $type = $path[2];
138        $uid = $path[3];
139        return array('type' => $type, 'uid' => $uid);
140    }
141
142    function get($request) {
143        $response = new Response($request);
144        restore_session($response);
145
146        $info = $this->getTypeAndUid($request);
147        $objects = $info['type']::get(array('uid' => $info['uid']));
148        if (empty($objects)) {
149            throw new ResponseException("Object not found", Response::NOTFOUND);
150        }
151
152        $response->body = json_encode($objects[0]);
153        return $response;
154    }
155
156    function put($request) {
157        $response = new Response($request);
158        restore_session($response);
159
160        $info = $this->getTypeAndUid($request);
161        $data = json_decode($request->data);
162        $onlyAdd = $request->ifNoneMatch('*');
163        $onlyUpdate = $request->ifMatch('*');
164
165        $object = FALSE;
166        $objects = $info['type']::get(array('uid' => $info['uid']));
167        if (!empty($objects)) {
168            $object = $objects[0];
169        }
170
171        if (( $onlyUpdate && !$object ) || ( $onlyAdd && $object )) {
172            throw new ResponseException("Update/Create and existing object mismatch", Response::PRECONDITIONFAILED);
173        }
174
175        if (!$object) {
176            $object = new $info['type']($info->uid);
177            $response->code = Response::CREATED;
178        } else {
179            $response->code = Response::OK;
180        }
181        foreach ($data as $key => $val) {
182            $object->$key = $val;
183        }
184        $object->save();
185
186        $response->body = json_encode($object);
187        return $response;
188    }
189
190    function delete($request) {
191        restore_session();
192        throw new ReponseException("Delete not implemented", Response::METHODNOTALLOWED);
193    }
194
195}
196
197$request = new Request();
198$path = $request->uri;
199$idx = strrpos($path, 'api.php');
200if ($idx !== FALSE) {
201    $baseUri = substr($path, 0, $idx + 7);
202    $request->baseUri = $baseUri;
203}
204
205try {
206    $resource = $request->loadResource();
207    $response = $resource->exec($request);
208} catch (ResponseException $e) {
209    $response = $e->response($request);
210    $response->body = json_encode(array('errorMsg' => $response->body));
211} catch (Exception $e) {
212    $response = new Response($request);
213    $response->code = Response::INTERNALSERVERERROR;
214    $response->body = json_encode(array('errorMsg' => "Unhandled exception: " . $e));
215}
216add_default_headers($response);
217$response->output();
218?>
Note: See TracBrowser for help on using the repository browser.