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