Homogenize the code of the pages of the groups
[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_FORBIDDEN;
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_FORBIDDEN;
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 $evenements = XDB::iterator(
123 "SELECT e.*, LEFT(10, e.debut) AS debut_day, LEFT(10, e.fin) AS fin_day,
124 IF(e.deadline_inscription, e.deadline_inscription >= LEFT(NOW(), 10),
125 1) AS inscr_open, e.deadline_inscription,
126 u.nom, u.prenom, u.promo, a.alias,
127 MAX(ep.nb) IS NOT NULL AS inscrit, MAX(ep.paid) AS paid
128 FROM groupex.evenements AS e
129 INNER JOIN x4dat.auth_user_md5 AS u ON u.user_id = e.organisateur_uid
130 INNER JOIN x4dat.aliases AS a ON (a.type = 'a_vie' AND a.id = u.user_id)
131 LEFT JOIN groupex.evenements_participants AS ep ON (ep.eid = e.eid AND ep.uid = {?})
132 WHERE asso_id = {?}
133 AND archive = " . ($archive ? "1 " : "0 ")
134 . (is_member() || may_update() ? "" : " AND accept_nonmembre != 0 ")
135 . "GROUP BY e.eid
136 ORDER BY inscr_open DESC, debut DESC", S::v('uid'), $globals->asso('id'));
137
138 $evts = array();
139
140 while ($e = $evenements->next()) {
141 $e['show_participants'] = ($e['show_participants'] && (is_member() || may_update()));
142 $res = XDB::query(
143 "SELECT titre, details, montant, ei.item_id, nb
144 FROM groupex.evenements_items AS ei
145 LEFT JOIN groupex.evenements_participants AS ep
146 ON (ep.eid = ei.eid AND ep.item_id = ei.item_id AND uid = {?})
147 WHERE ei.eid = {?}",
148 S::v('uid'), $e['eid']);
149 $e['moments'] = $res->fetchAllAssoc();
150
151 $e['topay'] = 0;
152 foreach ($e['moments'] as $m) {
153 $e['topay'] += $m['nb'] * $m['montant'];
154 }
155
156 $query = XDB::query(
157 "SELECT montant
158 FROM {$globals->money->mpay_tprefix}transactions AS t
159 WHERE ref = {?} AND uid = {?}", $e['paiement_id'], S::v('uid'));
160 $montants = $query->fetchColumn();
161
162 foreach ($montants as $m) {
163 $p = strtr(substr($m, 0, strpos($m, 'EUR')), ',', '.');
164 $e['paid'] += trim($p);
165 }
166
167 if (Env::has('updated') && $e['eid'] == Env::i('updated')) {
168 $page->assign('updated', $e);
169 }
170 $evts[] = $e;
171 }
172
173 $page->assign('evenements', $evts);
174 }
175
176 function handler_sub(&$page, $eid = null)
177 {
178 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
179
180 new_group_open_page('xnetevents/subscribe.tpl');
181
182 $evt = get_event_detail($eid);
183 if (!$evt) {
184 return PL_NOT_FOUND;
185 }
186
187 if (!$evt['inscr_open']) {
188 $page->kill('Les inscriptions pour cet événement sont closes');
189 }
190 if (!$evt['accept_nonmembre'] && !is_member() && !may_update()) {
191 $page->kill('Cet événement est fermé aux non-membres du groupe');
192 }
193
194 $page->assign('event', $evt);
195
196 if (!Post::has('submit')) {
197 return;
198 }
199
200 $moments = Post::v('moment', array());
201 $pers = Post::v('personnes', array());
202 $subs = array();
203
204 foreach ($moments as $j => $v) {
205 $subs[$j] = intval($v);
206
207 // retreive ohter field when more than one person
208 if ($subs[$j] == 2) {
209 if (!isset($pers[$j]) || !is_numeric($pers[$j])
210 || $pers[$j] < 0)
211 {
212 $page->trig('Tu dois choisir un nombre d\'invités correct !');
213 return;
214 }
215 $subs[$j] = 1 + $pers[$j];
216 }
217 }
218
219 // impossible to unsubscribe if you already paid sthing
220 if (array_sum($subs) && $evt['paid'] != 0) {
221 $page->trig("Impossible de te désinscrire complètement ".
222 "parce que tu as fait un paiement par ".
223 "chèque ou par liquide. Contacte un ".
224 "administrateur du groupe si tu es sûr de ".
225 "ne pas venir");
226 return;
227 }
228
229 // update actual inscriptions
230 $updated = false;
231 $total = 0;
232 foreach ($subs as $j => $nb) {
233 if ($nb >= 0) {
234 XDB::execute(
235 "REPLACE INTO groupex.evenements_participants
236 VALUES ({?}, {?}, {?}, {?}, {?})",
237 $eid, S::v('uid'), $j, $nb, $evt['paid']);
238 $updated = $eid;
239 } else {
240 XDB::execute(
241 "DELETE FROM groupex.evenements_participants
242 WHERE eid = {?} AND uid = {?} AND item_id = {?}",
243 $eid, S::v("uid"), $j);
244 $updated = $eid;
245 }
246 $total += $nb;
247 }
248 if ($updated !== false) {
249 subscribe_lists_event($total, S::i('uid'), $evt);
250 }
251 $page->assign('event', get_event_detail($eid));
252 }
253
254 function handler_csv(&$page, $eid = null, $item_id = null)
255 {
256 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
257
258 if (!is_numeric($item_id)) {
259 $item_id = null;
260 }
261
262 $evt = get_event_detail($eid, $item_id);
263 if (!$evt) {
264 return PL_NOT_FOUND;
265 }
266
267 header('Content-type: text/x-csv; encoding=iso-8859-1');
268 header('Pragma: ');
269 header('Cache-Control: ');
270
271 $page->changeTpl('xnetevents/csv.tpl', NO_SKIN);
272
273 $admin = may_update();
274
275 $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
276
277 $page->assign('participants',
278 get_event_participants($evt, $item_id, $tri));
279
280 $page->assign('admin', $admin);
281 $page->assign('moments', $evt['moments']);
282 $page->assign('money', $evt['money']);
283 $page->assign('tout', !Env::v('item_id', false));
284 }
285
286 function handler_ical(&$page, $eid = null)
287 {
288 global $globals;
289
290 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
291 $evt = get_event_detail($eid);
292 if (!$evt) {
293 return PL_FORBIDDEN;
294 }
295 $evt['debut'] = preg_replace('/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/', "\\1\\2\\3T\\4\\5\\6", $evt['debut']);
296 $evt['fin'] = preg_replace('/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/', "\\1\\2\\3T\\4\\5\\6", $evt['fin']);
297
298 foreach ($evt['moments'] as $m) {
299 $evt['descriptif'] .= "\n\n** " . $m['titre'] . " **\n" . $m['details'];
300 }
301
302 $page->changeTpl('xnetevents/calendar.tpl', NO_SKIN);
303
304 require_once('ical.inc.php');
305 $page->assign('asso', $globals->asso());
306 $page->assign('timestamp', time());
307 $page->assign('admin', may_update());
308
309 if (may_update()) {
310 $page->assign('participants', get_event_participants($evt, null, 'promo, nom, prenom'));
311 }
312 $page->register_function('display_ical', 'display_ical');
313 $page->assign_by_ref('e', $evt);
314
315 header('Content-Type: text/calendar; charset=utf-8');
316 }
317
318 function handler_edit(&$page, $eid = null)
319 {
320 global $globals;
321
322 // get eid if the the given one is a short name
323 if (!is_null($eid) && !is_numeric($eid)) {
324 $res = XDB::query("SELECT eid
325 FROM groupex.evenements
326 WHERE asso_id = {?} AND short_name = {?}",
327 $globals->asso('id'), $eid);
328 if ($res->numRows()) {
329 $eid = (int)$res->fetchOneCell();
330 }
331 }
332
333 // check the event is in our group
334 if (!is_null($eid)) {
335 $res = XDB::query("SELECT short_name
336 FROM groupex.evenements
337 WHERE eid = {?} AND asso_id = {?}",
338 $eid, $globals->asso('id'));
339 if ($res->numRows()) {
340 $infos = $res->fetchOneAssoc();
341 } else {
342 return PL_FORBIDDEN;
343 }
344 }
345
346 new_groupadmin_page('xnetevents/edit.tpl');
347
348 $moments = range(1, 4);
349 $page->assign('moments', $moments);
350
351 if (Post::v('intitule')) {
352 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
353 $short_name = event_change_shortname($page, $infos['short_name'],
354 Env::v('short_name', ''));
355
356 $evt = array(
357 'eid' => $eid,
358 'asso_id' => $globals->asso('id'),
359 'paiement_id' => Post::v('paiement_id') > 0 ? Post::v('paiement_id') : null,
360 'debut' => Post::v('deb_Year').'-'.Post::v('deb_Month')
361 .'-'.Post::v('deb_Day').' '.Post::v('deb_Hour')
362 .':'.Post::v('deb_Minute').':00',
363 'fin' => Post::v('fin_Year').'-'.Post::v('fin_Month')
364 .'-'.Post::v('fin_Day').' '.Post::v('fin_Hour')
365 .':'.Post::v('fin_Minute').':00',
366 'short_name' => $short_name,
367 );
368
369 $trivial = array('intitule', 'descriptif', 'noinvite',
370 'show_participants', 'accept_nonmembre', 'organisateur_uid');
371 foreach ($trivial as $k) {
372 $evt[$k] = Post::v($k);
373 }
374 if (!$eid) {
375 $evt['organisateur_uid'] = S::v('uid');
376 }
377
378 if (Post::v('deadline')) {
379 $evt['deadline_inscription'] = Post::v('inscr_Year').'-'
380 . Post::v('inscr_Month').'-'
381 . Post::v('inscr_Day');
382 } else {
383 $evt['deadline_inscription'] = null;
384 }
385
386 // Store the modifications in the database
387 XDB::execute('REPLACE INTO groupex.evenements
388 SET eid={?}, asso_id={?}, organisateur_uid={?}, intitule={?},
389 paiement_id = {?}, descriptif = {?}, debut = {?},
390 fin = {?}, show_participants = {?}, short_name = {?},
391 deadline_inscription = {?}, noinvite = {?},
392 accept_nonmembre = {?}',
393 $evt['eid'], $evt['asso_id'], $evt['organisateur_uid'],
394 $evt['intitule'], $evt['paiement_id'], $evt['descriptif'],
395 $evt['debut'], $evt['fin'], $evt['show_participants'],
396 $evt['short_name'], $evt['deadline_inscription'],
397 $evt['noinvite'], $evt['accept_nonmembre']);
398
399 // if new event, get its id
400 if (!$eid) {
401 $eid = XDB::insertId();
402 }
403
404 $nb_moments = 0;
405 $money_defaut = 0;
406
407 foreach ($moments as $i) {
408 if (Post::v('titre'.$i)) {
409 $nb_moments++;
410
411 $montant = strtr(Post::v('montant'.$i), ',', '.');
412 $money_defaut += (float)$montant;
413 XDB::execute("
414 REPLACE INTO groupex.evenements_items
415 VALUES ({?}, {?}, {?}, {?}, {?})",
416 $eid, $i, Post::v('titre'.$i),
417 Post::v('details'.$i), $montant);
418 } else {
419 XDB::execute("DELETE FROM groupex.evenements_items
420 WHERE eid = {?} AND item_id = {?}", $eid, $i);
421 }
422 }
423
424 // request for a new payment
425 if (Post::v('paiement_id') == -1 && $money_defaut >= 0) {
426 require_once 'validations.inc.php';
427 $p = new PayReq(S::v('uid'),
428 Post::v('intitule')." - ".$globals->asso('nom'),
429 Post::v('site'), $money_defaut,
430 Post::v('confirmation'), 0, 999,
431 $globals->asso('id'), $eid);
432 $p->submit();
433 }
434
435 // events with no sub-event: add a sub-event with no name
436 if ($nb_moments == 0) {
437 XDB::execute("INSERT INTO groupex.evenements_items
438 VALUES ({?}, {?}, '', '', 0)", $eid, 1);
439 }
440
441 pl_redirect('events');
442 }
443
444 // get a list of all the payment for this asso
445 $res = XDB::iterator("SELECT id, text
446 FROM {$globals->money->mpay_tprefix}paiements
447 WHERE asso_id = {?}", $globals->asso('id'));
448 $paiements = array();
449 while ($a = $res->next()) $paiements[$a['id']] = $a['text']; {
450 $page->assign('paiements', $paiements);
451 }
452
453 // when modifying an old event retreive the old datas
454 if ($eid) {
455 $res = XDB::query(
456 "SELECT eid, intitule, descriptif, debut, fin, organisateur_uid,
457 show_participants, paiement_id, short_name,
458 deadline_inscription, noinvite, accept_nonmembre
459 FROM groupex.evenements
460 WHERE eid = {?}", $eid);
461 $evt = $res->fetchOneAssoc();
462 // find out if there is already a request for a payment for this event
463 require_once 'validations.inc.php';
464 $res = XDB::query("SELECT stamp FROM requests
465 WHERE type = 'paiements' AND data LIKE {?}",
466 PayReq::same_event($eid, $globals->asso('id')));
467 $stamp = $res->fetchOneCell();
468 if ($stamp) {
469 $evt['paiement_id'] = -2;
470 $evt['paiement_req'] = $stamp;
471 }
472 $page->assign('evt', $evt);
473 // get all the different moments infos
474 $res = XDB::iterator(
475 "SELECT item_id, titre, details, montant
476 FROM groupex.evenements_items AS ei
477 INNER JOIN groupex.evenements AS e ON(e.eid = ei.eid)
478 WHERE e.eid = {?}
479 ORDER BY item_id", $eid);
480 $items = array();
481 while ($item = $res->next()) {
482 $items[$item['item_id']] = $item;
483 }
484 $page->assign('items', $items);
485 }
486 $page->assign('url_ref', $eid);
487 }
488
489 function handler_admin(&$page, $eid = null, $item_id = null)
490 {
491 global $globals;
492
493 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
494
495 $evt = get_event_detail($eid, $item_id);
496 if (!$evt) {
497 return PL_NOT_FOUND;
498 }
499
500 if ($evt['show_participants']) {
501 new_group_page('xnetevents/admin.tpl');
502 } else {
503 new_groupadmin_page('xnetevents/admin.tpl');
504 }
505
506 if (may_update() && Post::v('adm')) {
507 $member = get_infos(Post::v('mail'));
508 if (!$member) {
509 $page->trig("Membre introuvable");
510 }
511
512 // change the price paid by a participant
513 if (Env::v('adm') == 'prix' && $member) {
514 XDB::execute("UPDATE groupex.evenements_participants
515 SET paid = IF(paid + {?} > 0, paid + {?}, 0)
516 WHERE uid = {?} AND eid = {?}",
517 strtr(Env::v('montant'), ',', '.'),
518 strtr(Env::v('montant'), ',', '.'),
519 $member['uid'], $evt['eid']);
520 }
521
522 // change the number of personns coming with a participant
523 if (Env::v('adm') == 'nbs' && $member) {
524 $res = XDB::query("SELECT paid
525 FROM groupex.evenements_participants
526 WHERE uid = {?} AND eid = {?}",
527 $member['uid'], $evt['eid']);
528
529 $paid = intval($res->fetchOneCell());
530 $nbs = Post::v('nb', array());
531
532 foreach ($nbs as $id => $nb) {
533 $nb = max(intval($nb), 0);
534
535 if ($nb) {
536 XDB::execute("REPLACE INTO groupex.evenements_participants
537 VALUES ({?}, {?}, {?}, {?}, {?})",
538 $evt['eid'], $member['uid'], $id, $nb, $paid);
539 }
540 }
541
542 $res = XDB::query("SELECT COUNT(uid) AS cnt, SUM(nb) AS nb
543 FROM groupex.evenements_participants
544 WHERE uid = {?} AND eid = {?}
545 GROUP BY uid",
546 $member['uid'], $evt['eid']);
547 $u = $res->fetchOneAssoc();
548 $u = $u['cnt'] ? null : $u['nb'];
549 subscribe_lists_event($u, $member['uid'], $evt);
550 }
551
552 $evt = get_event_detail($eid, $item_id);
553 }
554
555 $page->assign('evt', $evt);
556 $page->assign('tout', is_null($item_id));
557
558 if (count($evt['moments'])) {
559 $page->assign('moments', $evt['moments']);
560 }
561
562 $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
563 $whereitemid = is_null($item_id) ? '' : "AND ep.item_id = $item_id";
564 $res = XDB::iterRow(
565 'SELECT UPPER(SUBSTRING(IF(u.nom IS NULL, m.nom,
566 IF(u.nom_usage<>"", u.nom_usage, u.nom)), 1, 1)),
567 COUNT(DISTINCT ep.uid)
568 FROM groupex.evenements_participants AS ep
569 INNER JOIN groupex.evenements AS e ON (ep.eid = e.eid)
570 LEFT JOIN groupex.membres AS m ON ( ep.uid = m.uid AND e.asso_id = m.asso_id)
571 LEFT JOIN auth_user_md5 AS u ON ( u.user_id = ep.uid )
572 WHERE ep.eid = {?} '.$whereitemid.'
573 GROUP BY UPPER(SUBSTRING(IF(u.nom IS NULL,m.nom,u.nom), 1, 1))', $evt['eid']);
574
575 $alphabet = array();
576 $nb_tot = 0;
577 while (list($char, $nb) = $res->next()) {
578 $alphabet[ord($char)] = $char;
579 $nb_tot += $nb;
580 if (Env::has('initiale') && $char == strtoupper(Env::v('initiale'))) {
581 $tot = $nb;
582 }
583 }
584 ksort($alphabet);
585 $page->assign('alphabet', $alphabet);
586
587 $ofs = Env::i('offset');
588 $tot = Env::v('initiale') ? $tot : $nb_tot;
589 $nbp = intval(($tot-1)/NB_PER_PAGE);
590 $links = array();
591 if ($ofs) {
592 $links['précédent'] = $ofs-1;
593 }
594 for ($i = 0; $i <= $nbp; $i++) {
595 $links[(string)($i+1)] = $i;
596 }
597 if ($ofs < $nbp) {
598 $links['suivant'] = $ofs+1;
599 }
600 if (count($links)>1) {
601 $page->assign('links', $links);
602 }
603
604 if ($evt['paiement_id']) {
605 $res = XDB::iterator(
606 "SELECT IF(u.nom_usage<>'', u.nom_usage, u.nom) AS nom, u.prenom,
607 u.promo, a.alias AS email, t.montant
608 FROM {$globals->money->mpay_tprefix}transactions AS t
609 INNER JOIN auth_user_md5 AS u ON(t.uid = u.user_id)
610 INNER JOIN aliases AS a ON (a.id = t.uid AND a.type='a_vie' )
611 LEFT JOIN groupex.evenements_participants AS ep ON(ep.uid = t.uid AND ep.eid = {?})
612 WHERE t.ref = {?} AND ep.uid IS NULL",
613 $evt['eid'], $evt['paiement_id']);
614 $page->assign('oublis', $res->total());
615 $page->assign('oubliinscription', $res);
616 }
617
618 $page->assign('participants',
619 get_event_participants($evt, $item_id, $tri,
620 "LIMIT ".($ofs*NB_PER_PAGE).", ".NB_PER_PAGE));
621 }
622 }
623
624 ?>