Typo.
[readifood.git] / lib / contact.php
1 <?php
2
3   if (isset($_POST['show_add_contact'])) {
4     set_last_selected("city_id", $_POST['city_id']);
5     $city_id = $_POST['city_id'];
6     show_new_contact_form($city_id);
7   }
8   else if (isset($_POST['add_contact'])) {
9     set_last_selected("area_id", $_POST['area_id']);
10     $id = add_contact($displayname);
11     if ($id !== false) {
12       echo "<p>Added contact.</p>\n";
13       $parameters = array($displayname, $id);
14     }
15   }
16   else if (isset($_POST['update_contact'])) {
17     list($name, $id, $args) = parse_parameters($parameters);
18     $q = new ContactQuery;
19     $contact = $q->findOneById($id);
20     if ($contact) {
21       $area = get_contact_area($contact);
22       if ($area) $area_id = $area->getId();
23       if (update_contact($contact, $area_id) !== false) {
24         echo "<p>Updated contact.</p>\n";
25         $parameters = array($contact->getDisplayname(), $contact->getId());
26       }
27     }
28     else {
29       echo "<p>No such contact!</p>\n";
30     }
31   }
32   else if ($_POST['search_contact']) {
33     header(sprintf("Location: http%s://%s/%s/search/%s", ($_SERVER['HTTPS']) ? "s" : "", $_SERVER['HTTP_HOST'], $module, urlencode($_POST['search_contact'])));
34     exit;
35   }
36   else if ($_POST['show_in_area']) {
37     set_last_selected("area_id", $_POST['area_id']);
38     $q = new AreaQuery;
39     $area = $q->findOneById($_POST['area_id']);
40     header(sprintf("Location: http%s://%s/%s/in/area/%s/%d", ($_SERVER['HTTPS']) ? "s" : "", $_SERVER['HTTP_HOST'], $module, urlencode($area->getName()), $_POST['area_id']));
41     exit;
42   }
43   else if ($_POST['show_in_city']) {
44     set_last_selected("city_id", $_POST['city_id']);
45     $q = new CityQuery;
46     $city = $q->findOneById($_POST['city_id']);
47     header(sprintf("Location: http%s://%s/%s/in/city/%s/%d", ($_SERVER['HTTPS']) ? "s" : "", $_SERVER['HTTP_HOST'], $module, urlencode($city->getName()), $_POST['city_id']));
48     exit;
49   }
50
51   function show_contact_summary(&$contact, $editing = false) {
52     if ($editing) echo "<p>Contact: <span class=\"strong\">" . htmlspecialchars($contact->getDisplayname()) . "</span>";
53     else echo "<br>\nContact " . $contact->getStrongLink();
54     $role = $contact->getRole();
55     $role_string = get_contact_role_string($contact);
56     if ($role_string) echo " $role_string";
57     $d = urlencode($contact->getDisplayname());
58     $i = $contact->getId();
59     if ($role & $GLOBALS['ROLE_DONOR']) echo " " . get_small_link("Donations", "/donation/from/contact/%s/%d", $d, $i);
60     if ($role & $GLOBALS['ROLE_REQUESTER']) echo " " . get_small_link("Referred", "/order/from/referrer/%s/%d", $d, $i);
61     if ($role & $GLOBALS['ROLE_BENEFICIARY']) {
62       echo " " . get_small_link("Orders", "/order/to/beneficiary/%s/%d", $d, $contact->getId());
63       if (get_contact_area($contact)) echo " " . get_small_link("Place", "/order/place/for/beneficiary/%s/%d", $d, $i);
64     }
65     if (check_admin(1)) {
66       echo " " . $contact->getDeleteLink();
67     }
68     $area = get_contact_area($contact);
69     echo " in " . $area->getLink();
70     $city = get_contact_city($contact);
71     echo ", " . $city->getLink(get_city_displayname($city));
72   }
73
74   function show_contacts($offset, $per_page, $address_ids) {
75     $q = new ContactQuery;
76     $contacts = $q->filterByAddressId($address_ids)->orderByForename()->orderBySurname()->find();
77     if (count($contacts)) {
78       foreach ($contacts as $contact) show_contact_summary($contact);
79     }
80     else echo " none";
81   }
82
83   function search_contacts($offset, $per_page, $search) {
84     $q = new ContactQuery;
85     $contacts = $q->filterByDisplayname("%$search%")->find();
86     echo "<p>Contacts matching '" . htmlspecialchars($search) . "':";
87     if (count($contacts)) {
88       foreach ($contacts as $contact) show_contact_summary($contact);
89     }
90     else echo "none";
91     echo "</p>\n";
92
93     $address_ids = array();
94     $q = new AddressQuery;
95     $addresses = $q->filterByLine("%$search%")->find();
96     foreach ($addresses as $address) $address_ids[] = $address->getId();
97     $q = new AddressQuery;
98     $addresses = $q->filterByPostcode("%$search%")->find();
99     foreach ($addresses as $address) $address_ids[] = $address->getId();
100
101     $q = new ContactQuery;
102     $contacts = $q->filterByAddressId($address_ids)->find();
103     echo "<p>Contacts in address '" . htmlspecialchars($search) . "':";
104     if (count($contacts)) {
105       foreach ($contacts as $contact) show_contact_summary($contact);
106     }
107     else echo "none";
108     echo "</p>\n";
109   }
110
111   function show_city_contacts($offset, $per_page, $city_name, $city_id = null) {
112     if (isset($city_id)) $city = get_city_by_id($city_id);
113     else if ($city_name) $city = get_city_by_name($city_name);
114     if ($city) {
115       $q = new AreaQuery;
116       $areas = $q->filterByCityId($city->getId())->find();
117       $area_ids = array();
118       foreach ($areas as $area) $area_ids[] = $area->getId();
119
120       $q = new AddressQuery;
121       $addresses = $q->filterByAreaId($area_ids)->find();
122       $address_ids = array();
123       foreach ($addresses as $address) $address_ids[] = $address->getId();
124
125       echo "<p>Contacts in city " . $city->getLink(get_city_displayname($city)) . ":";
126       return show_contacts($offset, $per_page, $address_ids);
127     }
128     else echo "<p>No such city!</p>\n";
129   }
130
131   function show_area_contacts($offset, $per_page, $area_name, $area_id = null) {
132     if (isset($area_id)) $area = get_area_by_id($area_id);
133     else if ($area_name) $area = get_area_by_name($area_name);
134     if ($area) {
135       $q = new AddressQuery;
136       $addresses = $q->filterByAreaId($area->getId())->find();
137       $address_ids = array();
138       foreach ($addresses as $address) $address_ids[] = $address->getId();
139
140       echo "<p>Contacts in area " . $area->getLink() . ":";
141       return show_contacts($offset, $per_page, $address_ids);
142     }
143     else echo "<p>No such area!</p>\n";
144   }
145
146   function show_contact_areas_form($city_id = null) {
147     $areas = get_city_areas($city_id);
148     if (! count($areas)) {
149       echo "<p>No <a href=\"/area\">areas</a>!</p>\n";
150       return;
151     }
152
153     $candidates = array();
154     foreach ($areas as $area) {
155       if (! count(get_area_contacts($area->getId()))) continue;
156       $candidates[] = $area;
157     }
158     if (! count($candidates)) return;
159
160     echo "<p>Show contacts in area\n";
161     echo "<select name=\"area_id\">\n";
162     foreach ($candidates as $area) {
163       option("area_id", $area->getId(), get_area_displayname($area));
164     }
165     echo "</select>\n";
166     submit("show_in_area", "Show");
167   }
168
169   function show_contact_cities_form($city_id = null) {
170     $q = new CityQuery;
171     $cities = $q->orderByName()->find();
172
173     if (! count($cities)) {
174       echo "<p>No <a href=\"/city\">cities</a>!</p>\n";
175       return;
176     }
177
178     $candidates = array();
179     foreach ($cities as $city) {
180       if (! count(get_city_contacts($city->getId()))) continue;
181       $candidates[] = $city;
182     }
183     if (! count($candidates)) return;
184
185     echo "<p>Show contacts in city\n";
186     echo "<select name=\"city_id\">\n";
187     foreach ($candidates as $city) {
188       option("city_id", $city->getId(), get_city_displayname($city), $city_id);
189     }
190     echo "</select>\n";
191     submit("show_in_city", "Show");
192   }
193
194   function show_contact_search_form() {
195     echo "<p>Search for contacts:";
196     input("search_contact");
197     echo "<input type=\"submit\" value=\"Search\">\n";
198   }
199
200   function show_contact_forms($city_id) {
201     form("noprint standout");
202     show_contact_areas_form($city_id);
203     show_contact_cities_form($city_id);
204     show_contact_search_form();
205     end_form();
206   }
207
208   function show_contact_role_form($role) {
209     return show_role_form($role, $GLOBALS['contact_roles']);
210   }
211
212   function show_contact_form($contact = null, $new = false) {
213     global $contact_roles, $parcel_sizes, $parcel_contents;
214
215     if (! $contact) $contact = new Contact;
216     else if ($contact->getRole() & ($GLOBALS['ROLE_BENEFICIARY'] | $GLOBALS['ROLE_REQUESTER'])) {
217       $state_mask = $GLOBALS['STATE_ANY'];
218       $state_mask &= ~$GLOBALS['STATE_DELIVERED'];
219       $state_mask &= ~$GLOBALS['STATE_CANCELLED'];
220
221       $orders = get_contact_orders($contact, $state_mask);
222
223       if (count($orders)) {
224         echo "<tr>\n";
225         echo "  <td colspan=2><strong>Outstanding orders:</strong></td>\n";
226         echo "</tr>\n";
227
228         echo "<tr>\n";
229         echo "  <td colspan=2 class=\"history\">\n";
230         foreach ($orders as $order) {
231           echo "    " . get_order_summary($order) . "<br>\n";
232         }
233         echo "  </td>\n";
234         echo "</tr>\n";
235       }
236     }
237
238     /* Role. */
239     echo "<tr>\n";
240     echo "  <td>Role</td>\n";
241     echo "  <td>"; show_contact_role_form($contact->getRole()); echo "</td>\n";
242     echo "</tr>\n";
243
244     /* Date added. */
245     if (! $new) {
246       echo "<tr>\n";
247       echo "  <td>Registered</td>\n";
248       echo "  <td>" . $contact->getAdded() . "</td>\n";
249       echo "</tr>\n";
250     }
251
252     /* Forename. */
253     echo "<tr>\n";
254     echo "  <td>Forename</td>\n";
255     echo "  <td>"; input("forename", $contact->getForename()); echo "</td>\n";
256     echo "</tr>\n";
257
258     /* Middle names. */
259     echo "<tr>\n";
260     echo "  <td>Middle name(s)</td>\n";
261     echo "  <td>"; input("middle", $contact->getMiddle()); echo "</td>\n";
262     echo "</tr>\n";
263
264     /* Surname. */
265     echo "<tr>\n";
266     echo "  <td>Surname</td>\n";
267     echo "  <td>"; input("surname", $contact->getSurname()); echo "</td>\n";
268     echo "</tr>\n";
269
270     /* Display name. */
271     echo "<tr>\n";
272     echo "  <td>Display name (if not concatenation of above)</td>\n";
273     echo "  <td>"; input("displayname", $contact->getDisplayname()); echo "</td>\n";
274     echo "</tr>\n";
275
276     /* Address. */
277     $address = get_contact_address($contact);
278     if (! $address) $address = new Address;
279     echo "<tr>\n";
280     echo "  <td>Address</td>\n";
281     echo "  <td>"; textarea("address", $address->getLine()); echo "</td>\n";
282     echo "</tr>\n";
283
284     /* Postcode. */
285     echo "<tr>\n";
286     echo "  <td>Postcode</td>\n";
287     $postcode = $address->getPostcode();
288     if (validate_postcode($postcode)) {
289       echo "  <td>"; input("postcode", $postcode); echo get_address_map_link($address); echo "</td>\n";
290     }
291     else {
292       echo "  <td>"; input("postcode", $address->getPostcode()); echo " (invalid)</td>\n";
293     }
294     echo "</tr>\n";
295
296     /* Telephone. */
297     echo "<tr>\n";
298     echo "  <td>Telephone</td>\n";
299     echo "  <td>"; input("telephone1", $contact->getTelephone1()); echo "</td>\n";
300     echo "</tr>\n";
301     echo "<tr>\n";
302     echo "  <td>Alternative telephone</td>\n";
303     echo "  <td>"; input("telephone2", $contact->getTelephone2()); echo "</td>\n";
304     echo "</tr>\n";
305
306     /* Email. */
307     echo "<tr>\n";
308     echo "  <td>Email</td>\n";
309     echo "  <td>"; input("email", $contact->getEmail()); echo "</td>\n";
310     echo "</tr>\n";
311
312     /* Area. */
313     $area = get_contact_area($contact);
314     if ($area) $area_id = $area->getId();
315     echo "<tr>\n";
316     echo "  <td>Area</td>\n";
317     echo "  <td><select name=\"area_id\">\n";
318     $areas = get_city_areas();
319     foreach ($areas as $area) {
320       option("area_id", $area->getId(), get_area_displayname($area), $area_id);
321     }
322     echo "  </select></td>\n";
323     echo "</tr>\n";
324
325     /* Parcel type. */
326     echo "<tr>\n";
327     echo "  <td>Family unit</td>\n";
328     echo "  <td><select name=\"parcel_size\">\n";
329     $mask = 1 << count($parcel_sizes);
330     for ($i = 0; $i < count($parcel_sizes); $i++) {
331       option("parcel_size", 1 << $i, $parcel_sizes[$i], $contact->getParcel() % $mask);
332     }
333     echo "</select></td>\n";
334     echo "</tr>\n";
335
336     /* Parcel contents. */
337     echo "<tr>\n";
338     echo "  <td>Dietary requirements</td>\n";
339     echo "  <td>";
340     for ($i = count($parcel_sizes); $i < count($parcel_contents); $i++) {
341       if (1 << $i == $GLOBALS['PARCEL_TOILETRY']) continue;
342       echo "  <input type=\"checkbox\" id=\"parcel_$i\" name=\"parcel_$i\"";
343       if ($contact->getParcel() & (1 << $i)) echo " checked";
344       echo "><label for=\"parcel_$i\">$parcel_contents[$i]</label>\n";
345     }
346     echo "</td>\n";
347     echo "</tr>\n";
348
349     /* Notes. */
350     echo "<tr>\n";
351     echo "  <td>Notes</td>\n";
352     echo "  <td>"; textarea("notes", $contact->getNotes()); echo "</td>\n";
353     echo "</tr>\n";
354   }
355
356   function show_new_contact_form($city_id = null) {
357     if (! check_admin(1)) return;
358
359     $areas = get_city_areas($city_id);
360     if (! count($areas)) {
361       echo "<p>No <a href=\"/area\">areas</a>!</p>\n";
362       return;
363     }
364
365     form("noprint");
366     echo "<p>Add a new contact:</p>\n";
367
368     echo "<table>\n";
369     show_contact_form($contact, true);
370
371     echo "<tr>\n";
372     echo "  <td colspan=2>"; submit("add_contact", "Add"); echo "</td></tr>\n";
373     echo "</tr>\n";
374     echo "</table>\n";
375     end_form();
376   }
377
378   function show_add_new_contact_form() {
379     if (! check_admin(1)) return;
380
381     $q = new CityQuery;
382     $cities = $q->find();
383     if (! count($cities)) {
384       echo "<p>No <a href=\"/city\">cities</a>!</p>\n";
385       return;
386     }
387
388     form("noprint standout");
389     echo "<p>Add a new contact in <select name=\"city_id\">\n";
390     foreach ($cities as $city) {
391       option("city_id", $city->getId(), get_city_displayname($city));
392     }
393     echo "</select>";
394     submit("show_add_contact", "Proceed");
395     echo "</p>\n";
396     end_form();
397   }
398
399   function update_contact(&$contact, $area_id, $new = false) {
400     global $contact_roles, $parcel_sizes, $parcel_contents;
401
402     $role = 0;
403     for ($i = 0; $i < count($contact_roles); $i++) {
404       if ($_POST['role_' . $i] == "on") $role |= (1 << $i);
405     }
406
407     /* Staff can place orders. */
408     if ($role & (1 << 0)) $role |= (1 << 2);
409
410     $forename = $_POST['forename'];
411     $middle = $_POST['middle'];
412     $surname = $_POST['surname'];
413     $displayname = $_POST['displayname'];
414
415     if (! $forename && ! $surname) {
416       echo "<p>Must have either a forename or surname!</p>\n";
417       return false;
418     }
419     if ($middle && ! ($forename && $surname)) {
420       echo "<p>Must have both a forename or surname for middle name(s) to make sense!</p>\n";
421       return false;
422     }
423
424     if (! $displayname) {
425       $displayname = $forename;
426       if ($middle) $displayname .= " $middle";
427       if ($forename) $displayname .= " ";
428       $displayname .= $surname;
429       echo "<p>Display name will be $displayname.</p>\n";
430     }
431
432     /* Get address. */
433     $area_id = $_POST['area_id'];
434     $line = $_POST['address'];
435     $postcode = trim($_POST['postcode']);
436     if ($postcode) {
437       $postcode = format_postcode($_POST['postcode'], true);
438       if (! $postcode) return false;
439     }
440     $q = new AddressQuery;
441     /* XXX: Finding by area properly? */
442     $address = $q->filterByAreaId($area_id)->filterByLine($line)->filterByPostcode($postcode)->findOneOrCreate();
443     if ($address->isNew()) {
444       /* Changing address. */
445       //if (! $new)
446       /*
447         XXX: Check for other contacts at the old address.
448         Make this a new address if there are others, but
449         provide a link to update other contacts.
450       */
451       try {
452         $address->save();
453       }
454       catch (Exception $e) {
455         echo "<p>Error adding $line.</p>\n";
456         return false;
457       }
458     }
459
460     $telephone1 = $_POST['telephone1'];
461     $telephone2 = $_POST['telephone2'];
462     $email = $_POST['email'];
463     $parcel = $_POST['parcel_size'];
464     for ($i = count($parcel_sizes); $i < count($parcel_contents); $i++) {
465       if ($_POST['parcel_' . $i] == "on") $parcel |= (1 << $i);
466     }
467     $notes = $_POST['notes'];
468
469     $contact->setRole($role);
470     $contact->setForename($forename);
471     $contact->setMiddle($middle);
472     $contact->setSurname($surname);
473     $contact->setDisplayname($displayname);
474     $contact->setTelephone1($telephone1);
475     $contact->setTelephone2($telephone2);
476     $contact->setEmail($email);
477     $contact->setParcel($parcel);
478     $contact->setNotes($notes);
479     $contact->setAddressId($address->getId());
480
481     try {
482       $contact->save();
483     }
484     catch (Exception $e) {
485       if ($new) echo "<p>Error adding $displayname.</p>\n";
486       else echo "<p>Error updating $displayname.</p>\n";
487       return false;
488     }
489
490     return true;
491   }
492
493   function add_contact(&$name) {
494     if (! check_admin(1, "add a contact")) return;
495
496     $area_id = $_POST['area_id'];
497     if (! is_numeric($area_id)) {
498       echo "<p>Invalid area!</p>\n";
499       return false;
500     }
501
502     $area = get_area_by_id($area_id);
503     if (! $area) {
504       echo "<p>No such area!</p>\n";
505       return false;
506     }
507
508     $contact = new Contact;
509     if (! update_contact($contact, $area_id, true)) return false;
510     $name = $contact->getDisplayname();
511     return $contact->getId();
512   }
513
514   function confirm_delete_contact($name, $id = null, &$city_id = null) {
515     if (! check_admin(1, "delete a contact")) return;
516
517     if (isset($id)) $contact = get_contact_by_id($id);
518     else $contact = get_contact_by_name($name);
519     if (! $contact) return false;
520
521     echo "<h3>Confirm deletion</h3>\n";
522     echo "<p>You must confirm deletion of contact " . $contact->getDisplayname() . ": " . $contact->getDeleteLink(true) . "</p>\n";
523   }
524
525   function delete_contact($name, $id = null, &$city_id = null) {
526     if (! check_admin(1, "delete a contact")) return;
527
528     if (isset($id)) $contact = get_contact_by_id($id);
529     else $contact = get_contact_by_name($name);
530     if (! $contact) return false;
531
532     ///* Remember city ID for dropdown. */
533     //$city_id = $area->getCityId();
534
535     try {
536       $contact->delete();
537       echo "<p>Deleted contact.</p>\n";
538     }
539     catch (Exception $e) {
540       echo "<p>Error deleting $name!</p>\n";
541       return false;
542     }
543
544     return true;
545   }
546
547   function show_contact($name, &$id = null) {
548     if (isset($id)) $contact = get_contact_by_id($id);
549     else $contact = get_contact_by_name($name);
550     if (! $contact) return;
551
552     form();
553     show_contact_summary($contact, true);
554     echo ": ";
555     echo "\n</p>";
556
557     echo "<table>\n";
558     show_contact_form($contact);
559
560     if (check_admin(1)) {
561       echo "<tr>\n";
562       echo "  <td colspan=2>";
563       submit("update_contact", "Update");
564       echo "</td>\n";
565       echo "</tr>\n";
566     }
567
568     echo "</table>\n";
569     end_form();
570   }
571
572   /* /contact/in/area/Cambridge/1 */
573   if (count($parameters)) {
574     if ($parameters[0] == "in") {
575       switch ($parameters[1]) {
576         case "area":
577           $area_id = $parameters[3];
578           $_POST['area_id'] = $area_id;
579           $q = new AreaQuery;
580           $area = $q->findOneById($area_id);
581           $city = get_area_city($area);
582           if ($city) $city_id = $city->getId();
583           show_area_contacts(0, 10, $parameters[2], $area_id);
584         break;
585
586         case "city":
587           $city_id = $parameters[3];
588           $_POST['city_id'] = $city_id;
589           $q = new CityQuery;
590           $city = $q->findOneById($city_id);
591           show_city_contacts(0, 10, $parameters[2], $city_id);
592         break;
593       }
594     }
595     else if ($parameters[0] == "search") {
596       search_contacts(0, 10, urldecode($parameters[1]));
597     }
598   }
599   list($name, $id, $args) = parse_parameters($parameters);
600   //echo "<p>$name($id) " . print_r($args, true) . "</p>\n";
601   if (count($args)) {
602     switch ($args[0]) {
603       case "delete":
604         confirm_delete_contact($name, $id);
605       break;
606
607       case "confirmdelete":
608         delete_contact($name, $id);
609       break;
610     }
611   }
612   else if (isset($name)) show_contact($name, $id);
613
614   show_contact_forms($city_id);
615   show_add_new_contact_form($city_id);
616
617 ?>