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