95d904d8d53df4d7e0cd1bed0a166fca53412bd8
[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 $evts[] = $e;
170 }
171
172 $page->assign('evenements', $evts);
173 $page->assign('is_member', is_member());
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 foreach ($subs as $j => $nb) {
231 if ($nb > 0) {
232 XDB::execute(
233 "REPLACE INTO groupex.evenements_participants
234 VALUES ({?}, {?}, {?}, {?}, {?})",
235 $eid, S::v('uid'), $j, $nb, $evt['paid']);
236 $page->assign('updated', true);
237 } else {
238 XDB::execute(
239 "DELETE FROM groupex.evenements_participants
240 WHERE eid = {?} AND uid = {?} AND item_id = {?}",
241 $eid, S::v("uid"), $j);
242 $page->assign('updated', true);
243 }
244 }
245
246 $page->assign('event', get_event_detail($eid));
247 }
248
249 function handler_csv(&$page, $eid = null, $item_id = null)
250 {
251 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
252
253 if (!is_numeric($item_id)) {
254 $item_id = null;
255 }
256
257 $evt = get_event_detail($eid, $item_id);
258 if (!$evt) {
259 return PL_NOT_FOUND;
260 }
261
262 header('Content-type: text/x-csv; encoding=iso-8859-1');
263 header('Pragma: ');
264 header('Cache-Control: ');
265
266 $page->changeTpl('xnetevents/csv.tpl', NO_SKIN);
267
268 $admin = may_update();
269
270 $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
271
272 $page->assign('participants',
273 get_event_participants($evt, $item_id, $tri));
274
275 $page->assign('admin', $admin);
276 $page->assign('moments', $evt['moments']);
277 $page->assign('money', $evt['money']);
278 $page->assign('tout', !Env::v('item_id', false));
279 }
280
281 function handler_ical(&$page, $eid = null)
282 {
283 global $globals;
284
285 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
286 $evt = get_event_detail($eid);
287 if (!$evt) {
288 return PL_NOT_FOUND;
289 }
290 $evt['debut'] = preg_replace('/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/', "\\1\\2\\3T\\4\\5\\6", $evt['debut']);
291 $evt['fin'] = preg_replace('/(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)/', "\\1\\2\\3T\\4\\5\\6", $evt['fin']);
292
293 foreach ($evt['moments'] as $m) {
294 $evt['descriptif'] .= "\n\n** " . $m['titre'] . " **\n" . $m['details'];
295 }
296
297 $page->changeTpl('xnetevents/calendar.tpl', NO_SKIN);
298
299 require_once('ical.inc.php');
300 $page->assign('asso', $globals->asso());
301 $page->assign('timestamp', time());
302 $page->assign('admin', may_update());
303
304 if (may_update()) {
305 $page->assign('participants', get_event_participants($evt, null, 'promo, nom, prenom'));
306 }
307 $page->register_function('display_ical', 'display_ical');
308 $page->assign_by_ref('e', $evt);
309
310 header('Content-Type: text/calendar; charset=utf-8');
311 }
312
313 function handler_edit(&$page, $eid = null)
314 {
315 global $globals;
316
317 // get eid if the the given one is a short name
318 if (!is_null($eid) && !is_numeric($eid)) {
319 $res = XDB::query("SELECT eid
320 FROM groupex.evenements
321 WHERE asso_id = {?} AND short_name = {?}",
322 $globals->asso('id'), $eid);
323 if ($res->numRows()) {
324 $eid = (int)$res->fetchOneCell();
325 }
326 }
327
328 // check the event is in our group
329 if (!is_null($eid)) {
330 $res = XDB::query("SELECT short_name, asso_id
331 FROM groupex.evenements
332 WHERE eid = {?}", $eid);
333 $infos = $res->fetchOneAssoc();
334 if ($infos['asso_id'] != $globals->asso('id')) {
335 return PL_NOT_ALLOWED;
336 }
337 }
338
339 new_groupadmin_page('xnetevents/edit.tpl');
340
341 $moments = range(1, 4);
342 $page->assign('moments', $moments);
343
344 if (Post::v('intitule')) {
345 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
346 $short_name = event_change_shortname($page, $infos['short_name'],
347 Env::v('short_name', ''));
348
349 $evt = array(
350 'eid' => $eid,
351 'asso_id' => $globals->asso('id'),
352 'paiement_id' => Post::v('paiement_id') > 0 ? Post::v('paiement_id') : null,
353 'debut' => Post::v('deb_Year').'-'.Post::v('deb_Month')
354 .'-'.Post::v('deb_Day').' '.Post::v('deb_Hour')
355 .':'.Post::v('deb_Minute').':00',
356 'fin' => Post::v('fin_Year').'-'.Post::v('fin_Month')
357 .'-'.Post::v('fin_Day').' '.Post::v('fin_Hour')
358 .':'.Post::v('fin_Minute').':00',
359 'short_name' => $short_name,
360 );
361
362 $trivial = array('intitule', 'descriptif', 'noinvite',
363 'show_participants', 'accept_nonmembre', 'organisateur_uid');
364 foreach ($trivial as $k) {
365 $evt[$k] = Post::v($k);
366 }
367 if (!$eid) {
368 $evt['organisateur_uid'] = S::v('uid');
369 }
370
371 if (Post::v('deadline')) {
372 $evt['deadline_inscription'] = Post::v('inscr_Year').'-'
373 . Post::v('inscr_Month').'-'
374 . Post::v('inscr_Day');
375 } else {
376 $evt['deadline_inscription'] = null;
377 }
378
379 // Store the modifications in the database
380 XDB::execute('REPLACE INTO groupex.evenements
381 SET eid={?}, asso_id={?}, organisateur_uid={?}, intitule={?},
382 paiement_id = {?}, descriptif = {?}, debut = {?},
383 fin = {?}, show_participants = {?}, short_name = {?},
384 deadline_inscription = {?}, noinvite = {?},
385 accept_nonmembre = {?}',
386 $evt['eid'], $evt['asso_id'], $evt['organisateur_uid'],
387 $evt['intitule'], $evt['paiement_id'], $evt['descriptif'],
388 $evt['debut'], $evt['fin'], $evt['show_participants'],
389 $evt['short_name'], $evt['deadline_inscription'],
390 $evt['noinvite'], $evt['accept_nonmembre']);
391
392 // if new event, get its id
393 if (!$eid) {
394 $eid = mysql_insert_id();
395 }
396
397 $nb_moments = 0;
398 $money_defaut = 0;
399
400 foreach ($moments as $i) {
401 if (Post::v('titre'.$i)) {
402 $nb_moments++;
403
404 $montant = strtr(Post::v('montant'.$i), ',', '.');
405 $money_defaut += (float)$montant;
406 XDB::execute("
407 REPLACE INTO groupex.evenements_items
408 VALUES ({?}, {?}, {?}, {?}, {?})",
409 $eid, $i, Post::v('titre'.$i),
410 Post::v('details'.$i), $montant);
411 } else {
412 XDB::execute("DELETE FROM groupex.evenements_items
413 WHERE eid = {?} AND item_id = {?}", $eid, $i);
414 }
415 }
416
417 // request for a new payment
418 if (Post::v('paiement_id') == -1 && $money_defaut >= 0) {
419 require_once 'validations.inc.php';
420 $p = new PayReq(S::v('uid'),
421 Post::v('intitule')." - ".$globals->asso('nom'),
422 Post::v('site'), $money_defaut,
423 Post::v('confirmation'), 0, 999,
424 $globals->asso('id'), $eid);
425 $p->submit();
426 }
427
428 // events with no sub-event: add a sub-event with no name
429 if ($nb_moments == 0) {
430 XDB::execute("INSERT INTO groupex.evenements_items
431 VALUES ({?}, {?}, '', '', 0)", $eid, 1);
432 }
433
434 # if (is_null($evt['eid'])) {
435 pl_redirect('events');
436 # }
437 }
438
439 // get a list of all the payment for this asso
440 $res = XDB::iterator("SELECT id, text
441 FROM {$globals->money->mpay_tprefix}paiements
442 WHERE asso_id = {?}", $globals->asso('id'));
443 $paiements = array();
444 while ($a = $res->next()) $paiements[$a['id']] = $a['text']; {
445 $page->assign('paiements', $paiements);
446 }
447
448 // when modifying an old event retreive the old datas
449 if ($eid) {
450 $res = XDB::query(
451 "SELECT eid, intitule, descriptif, debut, fin, organisateur_uid,
452 show_participants, paiement_id, short_name,
453 deadline_inscription, noinvite, accept_nonmembre
454 FROM groupex.evenements
455 WHERE eid = {?}", $eid);
456 $evt = $res->fetchOneAssoc();
457 // find out if there is already a request for a payment for this event
458 require_once 'validations.inc.php';
459 $res = XDB::query("SELECT stamp FROM requests
460 WHERE type = 'paiements' AND data LIKE {?}",
461 PayReq::same_event($eid, $globals->asso('id')));
462 $stamp = $res->fetchOneCell();
463 if ($stamp) {
464 $evt['paiement_id'] = -2;
465 $evt['paiement_req'] = $stamp;
466 }
467 $page->assign('evt', $evt);
468 // get all the different moments infos
469 $res = XDB::iterator(
470 "SELECT item_id, titre, details, montant
471 FROM groupex.evenements_items AS ei
472 INNER JOIN groupex.evenements AS e ON(e.eid = ei.eid)
473 WHERE e.eid = {?}
474 ORDER BY item_id", $eid);
475 $items = array();
476 while ($item = $res->next()) {
477 $items[$item['item_id']] = $item;
478 }
479 $page->assign('items', $items);
480 }
481 $page->assign('url_ref', $eid);
482 }
483
484 function handler_admin(&$page, $eid = null, $item_id = null)
485 {
486 global $globals;
487
488 require_once dirname(__FILE__).'/xnetevents/xnetevents.inc.php';
489
490 $evt = get_event_detail($eid, $item_id);
491 if (!$evt) {
492 return PL_NOT_FOUND;
493 }
494
495 if ($evt['show_participants']) {
496 new_group_page('xnetevents/admin.tpl');
497 } else {
498 new_groupadmin_page('xnetevents/admin.tpl');
499 }
500
501 if (may_update() && Post::v('adm')) {
502 $member = get_infos(Post::v('mail'));
503 if (!$member) {
504 $page->trig("Membre introuvable");
505 }
506
507 // change the price paid by a participant
508 if (Env::v('adm') == 'prix' && $member) {
509 XDB::execute("UPDATE groupex.evenements_participants
510 SET paid = IF(paid + {?} > 0, paid + {?}, 0)
511 WHERE uid = {?} AND eid = {?}",
512 strtr(Env::v('montant'), ',', '.'),
513 strtr(Env::v('montant'), ',', '.'),
514 $member['uid'], $eid);
515 }
516
517 // change the number of personns coming with a participant
518 if (Env::v('adm') == 'nbs' && $member) {
519 $res = XDB::query("SELECT paid
520 FROM groupex.evenements_participants
521 WHERE uid = {?} AND eid = {?}",
522 $member['uid'], $eid);
523
524 $paid = intval($res->fetchOneCell());
525 $nbs = Post::v('nb', array());
526
527 foreach ($nbs as $id => $nb) {
528 $nb = max(intval($nb), 0);
529
530 if ($nb) {
531 XDB::execute("REPLACE INTO groupex.evenements_participants
532 VALUES ({?}, {?}, {?}, {?}, {?})",
533 $eid, $member['uid'], $id, $nb, $paid);
534 } else {
535 XDB::execute("DELETE FROM groupex.evenements_participants
536 WHERE uid = {?} AND eid = {?} AND item_id = {?}",
537 $member['uid'], $eid, $id);
538 }
539 }
540
541 $res = XDB::query("SELECT uid FROM groupex.evenements_participants
542 WHERE uid = {?} AND eid = {?}",
543 $member['uid'], $eid);
544 $u = $res->fetchOneCell();
545 subscribe_lists_event($u, $member['uid'], $evt);
546 }
547
548 $evt = get_event_detail($eid, $item_id);
549 }
550
551 $page->assign('admin', may_update());
552 $page->assign('evt', $evt);
553 $page->assign('tout', is_null($item_id));
554
555 if (count($evt['moments'])) {
556 $page->assign('moments', $evt['moments']);
557 }
558
559 $tri = (Env::v('order') == 'alpha' ? 'promo, nom, prenom' : 'nom, prenom, promo');
560 $whereitemid = is_null($item_id) ? '' : "AND ep.item_id = $item_id";
561 $res = XDB::iterRow(
562 'SELECT UPPER(SUBSTRING(IF(u.nom IS NULL, m.nom,
563 IF(u.nom_usage<>"", u.nom_usage, u.nom)), 1, 1)),
564 COUNT(DISTINCT ep.uid)
565 FROM groupex.evenements_participants AS ep
566 INNER JOIN groupex.evenements AS e ON (ep.eid = e.eid)
567 LEFT JOIN groupex.membres AS m ON ( ep.uid = m.uid AND e.asso_id = m.asso_id)
568 LEFT JOIN auth_user_md5 AS u ON ( u.user_id = ep.uid )
569 WHERE ep.eid = {?} '.$whereitemid.'
570 GROUP BY UPPER(SUBSTRING(IF(u.nom IS NULL,m.nom,u.nom), 1, 1))', $eid);
571
572 $alphabet = array();
573 $nb_tot = 0;
574 while (list($char, $nb) = $res->next()) {
575 $alphabet[ord($char)] = $char;
576 $nb_tot += $nb;
577 if (Env::has('initiale') && $char == strtoupper(Env::v('initiale'))) {
578 $tot = $nb;
579 }
580 }
581 ksort($alphabet);
582 $page->assign('alphabet', $alphabet);
583
584 $ofs = Env::i('offset');
585 $tot = Env::v('initiale') ? $tot : $nb_tot;
586 $nbp = intval(($tot-1)/NB_PER_PAGE);
587 $links = array();
588 if ($ofs) {
589 $links['précédent'] = $ofs-1;
590 }
591 for ($i = 0; $i <= $nbp; $i++) {
592 $links[(string)($i+1)] = $i;
593 }
594 if ($ofs < $nbp) {
595 $links['suivant'] = $ofs+1;
596 }
597 if (count($links)>1) {
598 $page->assign('links', $links);
599 }
600
601 if ($evt['paiement_id']) {
602 $res = XDB::iterator(
603 "SELECT IF(u.nom_usage<>'', u.nom_usage, u.nom) AS nom, u.prenom,
604 u.promo, a.alias AS email, t.montant
605 FROM {$globals->money->mpay_tprefix}transactions AS t
606 INNER JOIN auth_user_md5 AS u ON(t.uid = u.user_id)
607 INNER JOIN aliases AS a ON (a.id = t.uid AND a.type='a_vie' )
608 LEFT JOIN groupex.evenements_participants AS ep ON(ep.uid = t.uid AND ep.eid = {?})
609 WHERE t.ref = {?} AND ep.uid IS NULL",
610 $evt['eid'], $evt['paiement_id']);
611 $page->assign('oublis', $res->total());
612 $page->assign('oubliinscription', $res);
613 }
614
615 $page->assign('participants',
616 get_event_participants($evt, $item_id, $tri,
617 "LIMIT ".($ofs*NB_PER_PAGE).", ".NB_PER_PAGE));
618 }
619 }
620
621 ?>