]> dev.renevier.net Git - syp.git/blob - api.php
multi user administration
[syp.git] / api.php
1 <?php
2 /* Copyright (c) 2009 Arnaud Renevier, Inc, published under the modified BSD
3    license. */
4
5 require_once ("./inc/settings.php");
6 require_once ("./inc/db/mysql.php");
7 require_once ("./inc/utils.php");
8
9 function exit_document ($body) {
10     exit ("<html><head></head><body>$body</body></html>");
11 }
12
13 function success_auth ($user) {
14     $res = "<success request=\"$reason\"><user>" . 
15             htmlspecialchars ($user) .
16             "</user></success>";
17     exit_document ($res);
18 }
19
20 function success_feature ($feature, $request) {
21     $res = "<success request=\"$request\"><feature>";
22     $res .= "<id>" .  $feature->id .  "</id>";
23
24     $res .= "<imgurl>" .
25              ($feature->imgpath ? 
26                     image_url_from_imgpath ($feature->imgpath)
27                     : "") .
28              "</imgurl>";
29
30     $res .= "<description>" .
31                  htmlspecialchars ($feature->description) .
32                  "</description>";
33
34     // XXX: we do not use <title> because that would be interpreted and
35     // altered by browers html parser
36     $res .= "<heading>" . 
37             htmlspecialchars ($feature->title) .
38             "</heading>";
39
40     $res .= "<lon>" . $feature->lon . "</lon>";
41     $res .= "<lat>" . $feature->lat . "</lat>";
42     $res .= "</feature></success>";
43     exit_document ($res);
44 }
45
46 function success_delete_feature ($feature) {
47     $res = "<success request=\"del\"><feature>";
48     $res .= "<id>" .  $feature->id .  "</id>";
49     $res .= "</feature></success>";
50     exit_document ($res);
51 }
52
53 function success ($reason) {
54     exit_document ("<success request=\"$reason\"></success>");
55 }
56
57 function error ($reason) {
58     exit_document ("<error reason=\"$reason\"></error>");
59 }
60
61 function error_feature ($id, $reason) {
62     $res = "<error reason=\"$reason\"><feature>";
63     $res .= "<id>" .  $id .  "</id>";
64     $res .= "</feature></error>";
65     exit_document ($res);
66 }
67
68 function nochange_error ($id) {
69     error_feature ($id, "nochange");
70 }
71 function unreferenced_error ($id) {
72     error_feature ($id, "unreferenced");
73 }
74
75 function server_error () {
76     error ("server");
77 }
78
79 function unauthorized_error () {
80     error ("unauthorized");
81 }
82
83 function request_error () {
84     error ("request");
85 }
86
87 function file_too_big_error () {
88     error ("toobig");
89 }
90
91 function notanimage_error () {
92     error ("notimage");
93 }
94
95 function save_uploaded_file ($file, $con) {
96     $dest = "";
97     if (isset ($file) && ($file ["error"] != UPLOAD_ERR_NO_FILE)) {
98         img_check_upload ($file);
99         $dest = unique_file (UPLOADDIR, $file ["name"], $con);
100         if (!isset ($dest) || 
101                 (!move_uploaded_file ($file ["tmp_name"], $dest))) {
102             server_error ();
103         }
104         $mini_dest = getthumbsdir () . "/mini_" . basename_safe ($dest);
105
106         if (!create_thumbnail_or_copy ($dest, $mini_dest)) {
107             server_error ();
108         }
109     }
110     return basename_safe ($dest);
111 }
112
113 function img_check_upload ($file) {
114     if (!is_uploaded_file ($file ["tmp_name"])) {
115         if ($file ["error"] ==  UPLOAD_ERR_INI_SIZE) {
116             file_too_big_error ();
117         } else {
118             server_error ();
119         }
120     }
121     if (!getimagesize ($file ["tmp_name"])) {
122         notanimage_error ();
123     }
124 }
125
126 function delete_image_if_unused ($imgpath, $con) {
127     if (!isset ($imgpath) || (strlen ($imgpath) == 0)) {
128         return;
129     }
130     if ($con->imgpath_exists ($imgpath)) {
131         return;
132     }
133
134     $path = UPLOADDIR . "/" . $imgpath;
135     if (file_exists ($path)) {
136         unlink ($path);
137     }
138
139     $thumb_path = getthumbsdir () . "/mini_" . $imgpath;
140     if (file_exists ($thumb_path)) {
141         unlink ($thumb_path);
142     }
143 }
144
145 function unique_file ($dirname, $relpath, $con) {
146    $relpath = str_replace ('/', '', $relpath); // strip slashes from path
147    $relpath = str_replace ('\\', '', $relpath); // strip antislashes from path
148    $filename = $dirname . '/' . $relpath;
149    $counter = 1;
150
151    $dotpos = strrpos ($relpath, '.');
152    if ($dotpos) {
153        $base = substr ($relpath, 0, $dotpos);
154        $ext = substr ($relpath, $dotpos + 1);
155    } else {
156        $base = $relpath;
157        $ext = "";
158    }
159
160    while ($counter < 1000) {
161        if (!file_exists ($filename) && 
162            !($con->imgpath_exists (basename_safe ($filename)))) {
163            return $filename;
164        } else {
165             $counter++;
166             $filename = $dirname . '/' . $base . '_' . $counter . '.' . $ext;
167        }
168    }
169    // we tried to find an unused filename 1000 times. Give up now.
170    return null;
171 }
172
173 function check_auth ($con, $user, $pwd, $auth_only) {
174     $authentificated = false;
175
176     if (isset ($pwd)) {
177         if ($con->checkpwdmd5 ($user, md5 ($pwd))) {
178             // cookie will be valid for 2 weeks. I've chosen that value
179             // arbitrarily, and it may change in the future.
180             $time = time () + 14 * 60 * 24 * 60;
181             setcookie (sprintf ("%sauth", DBPREFIX), md5 ($pwd), $time, "" , "", false, true);
182             setcookie (sprintf ("%suser", DBPREFIX), $user, $time, "" , "", false, true);
183             $authentificated = true;
184             if ($auth_only) {
185                 success_auth ($user);
186             }
187         } else {
188             unauthorized_error ();
189         }
190     }
191
192     if (!$authentificated && !($con->checkpwdmd5 (
193                              $_COOKIE [sprintf ("%suser",  DBPREFIX)],
194                              $_COOKIE [sprintf ("%sauth",  DBPREFIX)]))) {
195         unauthorized_error ();
196     }
197 }
198
199 function main ($con) {
200     if (!isset ($_POST ["request"])) {
201         request_error ();
202     }
203
204     $pwd = unquote ($_POST ["password"]);
205     $user = unquote ($_POST ["user"]);
206     // does user only want authentication or does he want to do other things
207     $auth_only = ($_POST ["request"] == "auth");
208     check_auth ($con, $user, $pwd, $auth_only);
209     if (!$user) {
210         $user = $_COOKIE [sprintf ("%suser",  DBPREFIX)];
211     }
212
213     switch ($_POST ["request"]) {
214         case "update":
215             $id = $_POST ["fid"];
216             $feature = $con->getfeature ($id);
217             if (!isset ($feature)) {
218                 unreferenced_error ($id);
219             }
220             if ($feature->user != $user) {
221                 unauthorized_error ();
222             }
223
224             // no file uploaded, but editor currently has an image: it means
225             // image was not changed
226             if ($_POST ["keep_img"] == "yes") {
227                 $imgpath = $feature->imgpath;
228             } else {
229                 $imgpath = save_uploaded_file ($_FILES ["image_file"], $con);
230             }
231
232             $lon = $_POST ["lon"];
233             $lat = $_POST ["lat"];
234             $title = unquote ($_POST ["title"]);
235             $description = unquote ($_POST ["description"]);
236
237             try {
238                 $new_feature = new feature ($id, $lon, $lat, $imgpath, $title, $description, 0, $user);
239             } catch (Exception $e) {
240                 request_error ();
241             }
242
243             if (($new_feature->lon == $feature->lon) &&
244                 ($new_feature->lat == $feature->lat) &&
245                 ($new_feature->title == $feature->title) &&
246                 ($new_feature->imgpath == $feature->imgpath) &&
247                 ($new_feature->description == $feature->description)) {
248                 nochange_error ($feature->id);
249             }
250
251             $old_imgpath = "";
252             if ($feature->imgpath && ($feature->imgpath != $new_feature->imgpath)) {
253                 $old_imgpath = $feature->imgpath;
254             }
255
256             try {
257                 $con->save_feature ($new_feature);
258             } catch (Exception $e) {
259                 server_error ();
260             }
261             if ($old_imgpath) {
262                 try {
263                     delete_image_if_unused ($old_imgpath, $con); 
264                 } catch (Exception $e) {}
265             }
266             success_feature ($new_feature, "update");
267         break;
268         case "add":
269             $imgpath = save_uploaded_file ($_FILES ["image_file"], $con);
270
271             $lon = $_POST ["lon"];
272             $lat = $_POST ["lat"];
273             $title = unquote ($_POST ["title"]);
274             $description = unquote ($_POST ["description"]);
275             try {
276                 $feature = new feature (null, $lon, $lat, $imgpath, $title, $description, 0, $user);
277             } catch (Exception $e) {
278                 request_error ();
279             }
280             try {
281                 $feature = $con->save_feature ($feature);
282             } catch (Exception $e) {
283                 server_error ();
284             }
285             success_feature ($feature, "add");
286         break;
287         case "del":
288             $id = $_POST ["fid"];
289             $feature = $con->getfeature ($id);
290             if (!isset ($feature)) {
291                 unreferenced_error ($id);
292             }
293             if ($feature->user != $user) {
294                 unauthorized_error ();
295             }
296             $imgpath = $feature->imgpath;
297
298             try {
299                 $con->delete_feature ($feature);
300             } catch (Exception $e) {
301                 server_error ();
302             }
303
304             try {
305                 delete_image_if_unused ($imgpath, $con);
306             } catch (Exception $e) {}
307
308             success_delete_feature ($feature);
309         default:
310             request_error();
311         break;
312     }
313
314     server_error ();
315 }
316
317 try {
318     $connection->connect (DBHOST, DBUSER, DBPWD, DBNAME, DBPREFIX);
319 } catch (Exception $e) {
320     server_error ();
321 }
322
323 main ($connection);
324 ?>