bug 374, ergo de l'inscription aux evenements
[platal.git] / modules / xnetevents.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2006 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22 define('NB_PER_PAGE', 25);
23
24 class XnetEventsModule extends PLModule
25 {
26 function handlers()
27 {
28 return array(
29 '%grp/events' => $this->make_hook('events', AUTH_MDP),
30 '%grp/events/sub' => $this->make_hook('sub', AUTH_MDP),
31 '%grp/events/csv' => $this->make_hook('csv', AUTH_MDP),
32 '%grp/events/ical' => $this->make_hook('ical', AUTH_MDP),
33 '%grp/events/edit' => $this->make_hook('edit', AUTH_MDP),
34 '%grp/events/admin' => $this->make_hook('admin', AUTH_MDP),
35 );
36 }
37
38 function handler_events(&$page, $archive = null)
39 {
40 global $globals;
41
42 if ($archive == 'archive') {
43 $archive = true;
44 new_groupadmin_page('xnetevents/index.tpl');
45 } else {
46 $archive = false;
47 new_group_open_page('xnetevents/index.tpl');
48 }
49
50 $action = null;
51 if (Post::has('del')) {
52 $action = 'del';
53 $eid = Post::v('del');
54 } elseif (Post::has('archive')) {
55 $action = 'archive';
56 $eid = Post::v('archive');
57 } elseif (Post::has('unarchive')) {
58 $action = 'unarchive';
59 $eid = Post::v('unarchive');
60 }
61
62 if (!is_null($action)) {
63 if (!may_update()) {
64 return PL_NOT_ALLOWED;
65 }
66
67 $res = XDB::query("SELECT asso_id, short_name FROM groupex.evenements
68 WHERE eid = {?} AND asso_id = {?}",
69 $eid, $globals->asso('id'));
70
71 $tmp = $res->fetchOneRow();
72 if (!$tmp) {
73 return PL_NOT_ALLOWED;
74 }
75 }
76
77 if ($action == 'del') {
78 // deletes the event mailing aliases
79 if ($tmp[1]) {
80 XDB::execute(
81 "DELETE FROM virtual WHERE type = 'evt' AND alias LIKE {?}",
82 $tmp[1].'-absents@%');
83 XDB::execute(
84 "DELETE FROM virtual WHERE type = 'evt' AND alias LIKE {?}",
85 $tmp[1].'-participants@%');
86 }
87
88 // deletes the event items
89 XDB::execute("DELETE FROM groupex.evenements_items WHERE eid = {?}", $eid);
90
91 // deletes the event participants
92 XDB::execute("DELETE FROM groupex.evenements_participants
93 WHERE eid = {?}", $eid);
94
95 // deletes the event
96 XDB::execute("DELETE FROM groupex.evenements
97 WHERE eid = {?} AND asso_id = {?}",
98 $eid, $globals->asso('id'));
99
100 // delete the requests for payments
101 require_once 'validations.inc.php';
102 XDB::execute("DELETE FROM requests
103 WHERE type = 'paiements' AND data LIKE {?}",
104 PayReq::same_event($eid, $globals->asso('id')));
105 }
106
107 if ($action == 'archive') {
108 XDB::execute("UPDATE groupex.evenements
109 SET archive = 1
110 WHERE eid = {?} AND asso_id = {?}",
111 $eid, $globals->asso('id'));
112 }
113
114 if ($action == 'unarchive') {
115 XDB::execute("UPDATE groupex.evenements
116 SET archive = 0
117 WHERE eid = {?} AND asso_id = {?}",
118 $eid, $globals->asso('id'));
119 }
120
121 $page->assign('archive', $archive);
122 $page->assign('admin', may_update());
123
124 $evenements = XDB::iterator(
125 "SELECT e.*, LEFT(10, e.debut) AS debut_day, LEFT(10, e.fin) AS fin_day,
126 IF(e.deadline_inscription, e.deadline_inscription >= LEFT(NOW(), 10),
127 1) AS inscr_open, e.deadline_inscription,
128 u.nom, u.prenom, u.promo, a.alias,
129 MAX(ep.nb) AS inscrit, MAX(ep.paid) AS paid
130 FROM groupex.evenements AS e
131 INNER JOIN x4dat.auth_user_md5 AS u ON u.user_id = e.organisateur_uid
132 INNER JOIN x4dat.aliases AS a ON (a.type = 'a_vie' AND a.id = u.user_id)
133 LEFT JOIN groupex.evenements_participants AS ep ON (ep.eid = e.eid AND ep.uid = {?})
134 WHERE asso_id = {?}
135 AND archive = " . ($archive ? "1 " : "0 ")
136 . (is_member() || may_update() ? "" : " AND accept_nonmembre != 0 ")
137 . "GROUP BY e.eid
138 ORDER BY inscr_open DESC, debut DESC", S::v('uid'), $globals->asso('id'));
139
140 $evts = array();
141
142 while ($e = $evenements->next()) {
143 $e['show_participants'] = ($e['show_participants'] && (is_member() || may_update()));
144 $res = XDB::query(
145 "SELECT titre, details, montant, ei.item_id, nb
146 FROM groupex.evenements_items AS ei
147 LEFT JOIN groupex.evenements_participants AS ep
148 ON (ep.eid = ei.eid AND ep.item_id = ei.item_id AND uid = {?})
149 WHERE ei.eid = {?}",
150 S::v('uid'), $e['eid']);
151 $e['moments'] = $res->fetchAllAssoc();
152
153 $e['topay'] = 0;
154 foreach ($e['moments'] as $m) {
155 $e['topay'] += $m['nb'] * $m['montant'];
156 }
157
158 $query = XDB::query(
159 "SELECT montant
160 FROM {$globals->money->mpay_tprefix}transactions AS t
161 WHERE ref = {?} AND uid = {?}", $e['paiement_id'], S::v('uid'));
162 $montants = $query->fetchColumn();
163
164 foreach ($montants as $m) {
165 $p = strtr(substr($m, 0, strpos($m, 'EUR')), ',', '.');
166 $e['paid'] += trim($p);
167 }
168
169 if (Env::has('updated') && $e['eid'] == Env::i('updated')) {
170 $page->assign('updated', $e);
171 }
172 $evts[] = $e;
173 }
174
175 $page->assign('evenements', $evts);
176 $page->assign('is_member', is_member());
177 }
178
179 function handler_sub(&$page, $eid = null)
180 {
181 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
182
183 new_group_open_page('xnetevents/subscribe.tpl');
184
185 $evt = get_event_detail($eid);
186 if (!$evt) {
187 return PL_NOT_FOUND;
188 }
189
190 if (!$evt['inscr_open']) {
191 $page->kill('Les inscriptions pour cet événement sont closes');
192 }
193 if (!$evt['accept_nonmembre'] && !is_member() && !may_update()) {
194 $page->kill('Cet événement est fermé aux non-membres du groupe');
195 }
196
197 $page->assign('event', $evt);
198
199 if (!Post::has('submit')) {
200 return;
201 }
202
203 $moments = Post::v('moment', array());
204 $pers = Post::v('personnes', array());
205 $subs = array();
206
207 foreach ($moments as $j => $v) {
208 $subs[$j] = intval($v);
209
210 // retreive ohter field when more than one person
211 if ($subs[$j] == 2) {
212 if (!isset($pers[$j]) || !is_numeric($pers[$j])
213 || $pers[$j] < 0)
214 {
215 $page->trig('Tu dois choisir un nombre d\'invités correct !');
216 return;
217 }
218 $subs[$j] = 1 + $pers[$j];
219 }
220 }
221
222 // impossible to unsubscribe if you already paid sthing
223 if (array_sum($subs) && $evt['paid'] != 0) {
224 $page->trig("Impossible de te désinscrire complètement ".
225 "parce que tu as fait un paiement par ".
226 "chèque ou par liquide. Contacte un ".
227 "administrateur du groupe si tu es sûr de ".
228 "ne pas venir");
229 return;
230 }
231
232 // update actual inscriptions
233 $updated = false;
234 foreach ($subs as $j => $nb) {
235 if ($nb > 0) {
236 XDB::execute(
237 "REPLACE INTO groupex.evenements_participants
238 VALUES ({?}, {?}, {?}, {?}, {?})",
239 $eid, S::v('uid'), $j, $nb, $evt['paid']);
240 $updated = $eid;
241 } else {
242 XDB::execute(
243 "DELETE FROM groupex.evenements_participants
244 WHERE eid = {?} AND uid = {?} AND item_id = {?}",
245 $eid, S::v("uid"), $j);
246 $updated = $eid;
247 }
248 }
249 if ($updated !== false) {
250 pl_redirect('events?updated='.$updated);
251 }
252 $page->assign('event', get_event_detail($eid));
253 }
254
255 function handler_csv(&$page, $eid = null, $item_id = null)
256 {
257 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
258
259 if (!is_numeric($item_id)) {
260 $item_id = null;
261 }
262
263 $evt = get_event_detail($eid, $item_id);
264 if (!$evt) {
265 return PL_NOT_FOUND;
266 }
267
268 header('Content-type: text/x-csv; encoding=iso-8859-1');
269 header('Pragma: ');
270 header('Cache-Control: ');
271
272 $page->changeTpl('xnetevents/csv.tpl', NO_SKIN);
273
274 $admin = may_update();
275
276 $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
277
278 $page->assign('participants',
279 get_event_participants($evt, $item_id, $tri));
280
281 $page->assign('admin', $admin);
282 $page->assign('moments', $evt['moments']);
283 $page->assign('money', $evt['money']);
284 $page->assign('tout', !Env::v('item_id', false));
285 }
286
287 function handler_ical(&$page, $eid = null)
288 {
289 global $globals;
290
291 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
292 $evt = get_event_detail($eid);
293 if (!$evt) {
294 return PL_NOT_FOUND;
295 }
296 $evt['debut'] = preg_replace('/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/', "\\1\\2\\3T\\4\\5\\6", $evt['debut']);
297 $evt['fin'] = preg_replace('/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/', "\\1\\2\\3T\\4\\5\\6", $evt['fin']);
298
299 foreach ($evt['moments'] as $m) {
300 $evt['descriptif'] .= "\n\n** " . $m['titre'] . " **\n" . $m['details'];
301 }
302
303 $page->changeTpl('xnetevents/calendar.tpl', NO_SKIN);
304
305 require_once('ical.inc.php');
306 $page->assign('asso', $globals->asso());
307 $page->assign('timestamp', time());
308 $page->assign('admin', may_update());
309
310 if (may_update()) {
311 $page->assign('participants', get_event_participants($evt, null, 'promo, nom, prenom'));
312 }
313 $page->register_function('display_ical', 'display_ical');
314 $page->assign_by_ref('e', $evt);
315
316 header('Content-Type: text/calendar; charset=utf-8');
317 }
318
319 function handler_edit(&$page, $eid = null)
320 {
321 global $globals;
322
323 // get eid if the the given one is a short name
324 if (!is_null($eid) && !is_numeric($eid)) {
325 $res = XDB::query("SELECT eid
326 FROM groupex.evenements
327 WHERE asso_id = {?} AND short_name = {?}",
328 $globals->asso('id'), $eid);
329 if ($res->numRows()) {
330 $eid = (int)$res->fetchOneCell();
331 }
332 }
333
334 // check the event is in our group
335 if (!is_null($eid)) {
336 $res = XDB::query("SELECT short_name, asso_id
337 FROM groupex.evenements
338 WHERE eid = {?}", $eid);
339 $infos = $res->fetchOneAssoc();
340 if ($infos['asso_id'] != $globals->asso('id')) {
341 return PL_NOT_ALLOWED;
342 }
343 }
344
345 new_groupadmin_page('xnetevents/edit.tpl');
346
347 $moments = range(1, 4);
348 $page->assign('moments', $moments);
349
350 if (Post::v('intitule')) {
351 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
352 $short_name = event_change_shortname($page, $infos['short_name'],
353 Env::v('short_name', ''));
354
355 $evt = array(
356 'eid' => $eid,
357 'asso_id' => $globals->asso('id'),
358 'paiement_id' => Post::v('paiement_id') > 0 ? Post::v('paiement_id') : null,
359 'debut' => Post::v('deb_Year').'-'.Post::v('deb_Month')
360 .'-'.Post::v('deb_Day').' '.Post::v('deb_Hour')
361 .':'.Post::v('deb_Minute').':00',
362 'fin' => Post::v('fin_Year').'-'.Post::v('fin_Month')
363 .'-'.Post::v('fin_Day').' '.Post::v('fin_Hour')
364 .':'.Post::v('fin_Minute').':00',
365 'short_name' => $short_name,
366 );
367
368 $trivial = array('intitule', 'descriptif', 'noinvite',
369 'show_participants', 'accept_nonmembre', 'organisateur_uid');
370 foreach ($trivial as $k) {
371 $evt[$k] = Post::v($k);
372 }
373 if (!$eid) {
374 $evt['organisateur_uid'] = S::v('uid');
375 }
376
377 if (Post::v('deadline')) {
378 $evt['deadline_inscription'] = Post::v('inscr_Year').'-'
379 . Post::v('inscr_Month').'-'
380 . Post::v('inscr_Day');
381 } else {
382 $evt['deadline_inscription'] = null;
383 }
384
385 // Store the modifications in the database
386 XDB::execute('REPLACE INTO groupex.evenements
387 SET eid={?}, asso_id={?}, organisateur_uid={?}, intitule={?},
388 paiement_id = {?}, descriptif = {?}, debut = {?},
389 fin = {?}, show_participants = {?}, short_name = {?},
390 deadline_inscription = {?}, noinvite = {?},
391 accept_nonmembre = {?}',
392 $evt['eid'], $evt['asso_id'], $evt['organisateur_uid'],
393 $evt['intitule'], $evt['paiement_id'], $evt['descriptif'],
394 $evt['debut'], $evt['fin'], $evt['show_participants'],
395 $evt['short_name'], $evt['deadline_inscription'],
396 $evt['noinvite'], $evt['accept_nonmembre']);
397
398 // if new event, get its id
399 if (!$eid) {
400 $eid = mysql_insert_id();
401 }
402
403 $nb_moments = 0;
404 $money_defaut = 0;
405
406 foreach ($moments as $i) {
407 if (Post::v('titre'.$i)) {
408 $nb_moments++;
409
410 $montant = strtr(Post::v('montant'.$i), ',', '.');
411 $money_defaut += (float)$montant;
412 XDB::execute("
413 REPLACE INTO groupex.evenements_items
414 VALUES ({?}, {?}, {?}, {?}, {?})",
415 $eid, $i, Post::v('titre'.$i),
416 Post::v('details'.$i), $montant);
417 } else {
418 XDB::execute("DELETE FROM groupex.evenements_items
419 WHERE eid = {?} AND item_id = {?}", $eid, $i);
420 }
421 }
422
423 // request for a new payment
424 if (Post::v('paiement_id') == -1 && $money_defaut >= 0) {
425 require_once 'validations.inc.php';
426 $p = new PayReq(S::v('uid'),
427 Post::v('intitule')." - ".$globals->asso('nom'),
428 Post::v('site'), $money_defaut,
429 Post::v('confirmation'), 0, 999,
430 $globals->asso('id'), $eid);
431 $p->submit();
432 }
433
434 // events with no sub-event: add a sub-event with no name
435 if ($nb_moments == 0) {
436 XDB::execute("INSERT INTO groupex.evenements_items
437 VALUES ({?}, {?}, '', '', 0)", $eid, 1);
438 }
439
440 pl_redirect('events');
441 }
442
443 // get a list of all the payment for this asso
444 $res = XDB::iterator("SELECT id, text
445 FROM {$globals->money->mpay_tprefix}paiements
446 WHERE asso_id = {?}", $globals->asso('id'));
447 $paiements = array();
448 while ($a = $res->next()) $paiements[$a['id']] = $a['text']; {
449 $page->assign('paiements', $paiements);
450 }
451
452 // when modifying an old event retreive the old datas
453 if ($eid) {
454 $res = XDB::query(
455 "SELECT eid, intitule, descriptif, debut, fin, organisateur_uid,
456 show_participants, paiement_id, short_name,
457 deadline_inscription, noinvite, accept_nonmembre
458 FROM groupex.evenements
459 WHERE eid = {?}", $eid);
460 $evt = $res->fetchOneAssoc();
461 // find out if there is already a request for a payment for this event
462 require_once 'validations.inc.php';
463 $res = XDB::query("SELECT stamp FROM requests
464 WHERE type = 'paiements' AND data LIKE {?}",
465 PayReq::same_event($eid, $globals->asso('id')));
466 $stamp = $res->fetchOneCell();
467 if ($stamp) {
468 $evt['paiement_id'] = -2;
469 $evt['paiement_req'] = $stamp;
470 }
471 $page->assign('evt', $evt);
472 // get all the different moments infos
473 $res = XDB::iterator(
474 "SELECT item_id, titre, details, montant
475 FROM groupex.evenements_items AS ei
476 INNER JOIN groupex.evenements AS e ON(e.eid = ei.eid)
477 WHERE e.eid = {?}
478 ORDER BY item_id", $eid);
479 $items = array();
480 while ($item = $res->next()) {
481 $items[$item['item_id']] = $item;
482 }
483 $page->assign('items', $items);
484 }
485 $page->assign('url_ref', $eid);
486 }
487
488 function handler_admin(&$page, $eid = null, $item_id = null)
489 {
490 global $globals;
491
492 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
493
494 $evt = get_event_detail($eid, $item_id);
495 if (!$evt) {
496 return PL_NOT_FOUND;
497 }
498
499 if ($evt['show_participants']) {
500 new_group_page('xnetevents/admin.tpl');
501 } else {
502 new_groupadmin_page('xnetevents/admin.tpl');
503 }
504
505 if (may_update() && Post::v('adm')) {
506 $member = get_infos(Post::v('mail'));
507 if (!$member) {
508 $page->trig("Membre introuvable");
509 }
510
511 // change the price paid by a participant
512 if (Env::v('adm') == 'prix' && $member) {
513 XDB::execute("UPDATE groupex.evenements_participants
514 SET paid = IF(paid + {?} > 0, paid + {?}, 0)
515 WHERE uid = {?} AND eid = {?}",
516 strtr(Env::v('montant'), ',', '.'),
517 strtr(Env::v('montant'), ',', '.'),
518 $member['uid'], $evt['eid']);
519 }
520
521 // change the number of personns coming with a participant
522 if (Env::v('adm') == 'nbs' && $member) {
523 $res = XDB::query("SELECT paid
524 FROM groupex.evenements_participants
525 WHERE uid = {?} AND eid = {?}",
526 $member['uid'], $evt['eid']);
527
528 $paid = intval($res->fetchOneCell());
529 $nbs = Post::v('nb', array());
530
531 foreach ($nbs as $id => $nb) {
532 $nb = max(intval($nb), 0);
533
534 if ($nb) {
535 XDB::execute("REPLACE INTO groupex.evenements_participants
536 VALUES ({?}, {?}, {?}, {?}, {?})",
537 $evt['eid'], $member['uid'], $id, $nb, $paid);
538 } else {
539 XDB::execute("DELETE FROM groupex.evenements_participants
540 WHERE uid = {?} AND eid = {?} AND item_id = {?}",
541 $member['uid'], $evt['eid'], $id);
542 }
543 }
544
545 $res = XDB::query("SELECT uid
546 FROM groupex.evenements_participants
547 WHERE uid = {?} AND eid = {?}",
548 $member['uid'], $evt['eid']);
549 $u = $res->fetchOneCell();
550 subscribe_lists_event($u, $member['uid'], $evt);
551 }
552
553 $evt = get_event_detail($eid, $item_id);
554 }
555
556 $page->assign('admin', may_update());
557 $page->assign('evt', $evt);
558 $page->assign('tout', is_null($item_id));
559
560 if (count($evt['moments'])) {
561 $page->assign('moments', $evt['moments']);
562 }
563
564 $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
565 $whereitemid = is_null($item_id) ? '' : "AND ep.item_id = $item_id";
566 $res = XDB::iterRow(
567 'SELECT UPPER(SUBSTRING(IF(u.nom IS NULL, m.nom,
568 IF(u.nom_usage<>"", u.nom_usage, u.nom)), 1, 1)),
569 COUNT(DISTINCT ep.uid)
570 FROM groupex.evenements_participants AS ep
571 INNER JOIN groupex.evenements AS e ON (ep.eid = e.eid)
572 LEFT JOIN groupex.membres AS m ON ( ep.uid = m.uid AND e.asso_id = m.asso_id)
573 LEFT JOIN auth_user_md5 AS u ON ( u.user_id = ep.uid )
574 WHERE ep.eid = {?} '.$whereitemid.'
575 GROUP BY UPPER(SUBSTRING(IF(u.nom IS NULL,m.nom,u.nom), 1, 1))', $evt['eid']);
576
577 $alphabet = array();
578 $nb_tot = 0;
579 while (list($char, $nb) = $res->next()) {
580 $alphabet[ord($char)] = $char;
581 $nb_tot += $nb;
582 if (Env::has('initiale') && $char == strtoupper(Env::v('initiale'))) {
583 $tot = $nb;
584 }
585 }
586 ksort($alphabet);
587 $page->assign('alphabet', $alphabet);
588
589 $ofs = Env::i('offset');
590 $tot = Env::v('initiale') ? $tot : $nb_tot;
591 $nbp = intval(($tot-1)/NB_PER_PAGE);
592 $links = array();
593 if ($ofs) {
594 $links['précédent'] = $ofs-1;
595 }
596 for ($i = 0; $i <= $nbp; $i++) {
597 $links[(string)($i+1)] = $i;
598 }
599 if ($ofs < $nbp) {
600 $links['suivant'] = $ofs+1;
601 }
602 if (count($links)>1) {
603 $page->assign('links', $links);
604 }
605
606 if ($evt['paiement_id']) {
607 $res = XDB::iterator(
608 "SELECT IF(u.nom_usage<>'', u.nom_usage, u.nom) AS nom, u.prenom,
609 u.promo, a.alias AS email, t.montant
610 FROM {$globals->money->mpay_tprefix}transactions AS t
611 INNER JOIN auth_user_md5 AS u ON(t.uid = u.user_id)
612 INNER JOIN aliases AS a ON (a.id = t.uid AND a.type='a_vie' )
613 LEFT JOIN groupex.evenements_participants AS ep ON(ep.uid = t.uid AND ep.eid = {?})
614 WHERE t.ref = {?} AND ep.uid IS NULL",
615 $evt['eid'], $evt['paiement_id']);
616 $page->assign('oublis', $res->total());
617 $page->assign('oubliinscription', $res);
618 }
619
620 $page->assign('participants',
621 get_event_participants($evt, $item_id, $tri,
622 "LIMIT ".($ofs*NB_PER_PAGE).", ".NB_PER_PAGE));
623 }
624 }
625
626 ?>