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