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