2 /***************************************************************************
3 * Copyright (C) 2003-2011 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
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. *
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. *
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 *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
22 define('SIZE_MAX', 32768);
27 /** Virtual class to adapt for every possible implementation.
29 abstract class Validate
37 // Enable the refuse button.
38 public $refuse = true
;
41 public $comments = Array();
42 // Validations rules: comments for administrators.
43 public $rules = 'Mieux vaut laisser une demande de validation à un autre administrateur que de valider une requête illégale ou que de refuser une demande légitime.';
45 // Unless differently stated, a validation must be done by a site administrator.
46 public $requireAdmin = true
;
52 * @param $_user: user object that required the validation.
53 * @param $_unique: set to false if a profile can have multiple requests of this type.
54 * @param $_type: request's type.
56 public function __construct(User
&$_user, $_unique, $_type)
58 $this->user
= &$_user;
59 $this->stamp
= date('YmdHis');
60 $this->unique
= $_unique;
62 $this->promo
= $this->user
->promo();
66 // {{{ function submit()
68 /** Sends data to validation.
69 * It also deletes multiple requests for a couple (profile, type)
70 * when $this->unique is set to true.
72 public function submit()
75 XDB
::execute('DELETE FROM requests
76 WHERE uid = {?} AND type = {?}',
77 $this->user
->id(), $this->type
);
80 $this->stamp
= date('YmdHis');
81 XDB
::execute('INSERT INTO requests (uid, type, data, stamp)
82 VALUES ({?}, {?}, {?}, {?})',
83 $this->user
->id(), $this->type
, $this, $this->stamp
);
86 $globals->updateNbValid();
91 // {{{ function update()
93 protected function update()
95 XDB
::execute('UPDATE requests
96 SET data = {?}, stamp = stamp
97 WHERE uid = {?} AND type = {?} AND stamp = {?}',
98 $this, $this->user
->id(), $this->type
, $this->stamp
);
103 // {{{ function clean()
105 /** Deletes request from 'requests' table.
106 * If $this->unique is set, it deletes every requests of this type.
108 public function clean()
113 $success = XDB
::execute('DELETE FROM requests
114 WHERE uid = {?} AND type = {?}',
115 $this->user
->id(), $this->type
);
117 $success = XDB
::execute('DELETE FROM requests
118 WHERE uid = {?} AND type = {?} AND stamp = {?}',
119 $this->user
->id(), $this->type
, $this->stamp
);
121 $globals->updateNbValid();
126 // {{{ function handle_formu()
128 /** Handles form validation.
130 public function handle_formu()
132 if ($this->requireAdmin
&& !S
::admin()) {
133 $this->trigError('Vous n\'avez pas les permissions nécessaires pour valider cette demande.');
137 if (Env
::has('delete')) {
139 $this->trigSuccess('Requête supprimée.');
144 if (Env
::has('edit')) {
145 if ($this->handle_editor()) {
147 $this->trigSuccess('Requête mise à jour.');
154 if (Env
::has('hold') && Env
::has('comm')) {
155 $formid = Env
::i('formid');
156 foreach ($this->comments
as $comment) {
157 if ($comment[2] === $formid) {
161 if (!strlen(trim(Env
::v('comm')))) {
164 $this->comments
[] = array(S
::user()->login(), Env
::v('comm'), $formid);
166 // Sends email to our hotline.
168 $mailer = new PlMailer();
169 $mailer->setSubject("Commentaires de validation {$this->type}");
170 $mailer->setFrom("validation+{$this->type}@{$globals->mail->domain}");
171 $mailer->addTo($globals->core
->admin_email
);
173 $body = "Validation {$this->type} pour {$this->user->login()}\n\n"
174 . S
::user()->login() . " a ajouté le commentaire :\n\n"
175 . Env
::v('comm') . "\n\n"
176 . "cf la discussion sur : " . $globals->baseurl
. "/admin/validate";
178 $mailer->setTxtBody(wordwrap($body));
182 $this->trigSuccess('Commentaire ajouté.');
186 if (Env
::has('accept')) {
187 if ($this->commit()) {
188 $this->sendmail(true
);
190 $this->trigSuccess('Email de validation envoyé');
193 $this->trigError('Erreur lors de la validation');
198 if (Env
::has('refuse')) {
199 if (Env
::v('comm')) {
200 $this->sendmail(false
);
202 $this->trigSuccess('Email de refus envoyé.');
205 $this->trigError('Pas de motivation pour le refus !!!');
213 // {{{ function sendmail
215 protected function sendmail($isok)
218 $mailer = new PlMailer();
219 $mailer->setSubject($this->_mail_subj());
220 $mailer->setFrom("validation+{$this->type}@{$globals->mail->domain}");
221 $mailer->addTo("\"{$this->user->fullName()}\" <{$this->user->bestEmail()}>");
222 $mailer->addCc("validation+{$this->type}@{$globals->mail->domain}");
224 $body = ($this->user
->isFemale() ?
"Chère camarade,\n\n" : "Cher camarade,\n\n")
225 . $this->_mail_body($isok)
226 . (Env
::has('comm') ?
"\n\n" . Env
::v('comm') : '')
227 . "\n\nCordialement,\n-- \nL'équipe de Polytechnique.org\n"
228 . $this->_mail_ps($isok);
230 $mailer->setTxtBody(wordwrap($body));
235 // {{{ function trig()
237 protected function trigError($msg)
239 Platal
::page()->trigError($msg);
242 protected function trigWarning($msg)
244 Platal
::page()->trigWarning($msg);
247 protected function trigSuccess($msg)
249 Platal
::page()->trigSuccess($msg);
253 // {{{ function get_typed_request()
256 * @param $pid: profile's pid
257 * @param $type: request's type
258 * @param $stamp: request's timestamp
260 * Should only be used to retrieve an object in the databse with Validate::get_typed_request(...)
262 static public function get_typed_request($uid, $type, $stamp = -1)
265 $res = XDB
::query('SELECT data
267 WHERE uid = {?} and type = {?}',
270 $res = XDB
::query('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
272 WHERE uid = {?} AND type = {?} and stamp = {?}',
273 $uid, $type, $stamp);
275 if ($result = $res->fetchOneCell()) {
276 $result = Validate
::unserialize($result);
284 // {{{ function get_request_by_id()
286 static public function get_request_by_id($id)
288 list($uid, $type, $stamp) = explode('_', $id, 3);
289 return Validate
::get_typed_request($uid, $type, $stamp);
293 // {{{ function get_typed_requests()
295 /** Same as get_typed_request() but return an array of objects.
297 static public function get_typed_requests($uid, $type)
299 $res = XDB
::iterRow('SELECT data
301 WHERE uid = {?} and type = {?}',
304 while (list($data) = $res->next()) {
305 $array[] = Validate
::unserialize($data);
311 // {{{ function get_typed_requests_count()
313 /** Same as get_typed_requests() but return the count of available requests.
315 static public function get_typed_requests_count($uid, $type)
317 $res = XDB
::query('SELECT COUNT(data)
319 WHERE uid = {?} and type = {?}',
321 return $res->fetchOneCell();
325 // {{{ function _mail_body
327 abstract protected function _mail_body($isok);
330 // {{{ function _mail_subj
332 abstract protected function _mail_subj();
335 // {{{ function _mail_ps
337 protected function _mail_ps($isok)
343 // {{{ function commit()
345 /** Inserts data in database.
347 abstract public function commit();
350 // {{{ function formu()
352 /** Retunrs the name of the form's template. */
353 abstract public function formu();
356 // {{{ function editor()
358 /** Returns the name of the edition form's template. */
359 public function editor()
365 // {{{ function answers()
367 /** Automatic answers table for this type of validation. */
368 public function answers()
370 static $answers_table;
371 if (!isset($answers_table[$this->type
])) {
372 $r = XDB
::query('SELECT id, title, answer
373 FROM requests_answers
374 WHERE category = {?}',
376 $answers_table[$this->type
] = $r->fetchAllAssoc();
378 return $answers_table[$this->type
];
386 return $this->user
->id() . '_' . $this->type
. '_' . $this->stamp
;
390 // {{{ function ruleText()
392 public function ruleText()
394 return str_replace('\'', '\\\'', $this->rules
);
398 // {{{ function unserialize()
400 public static function unserialize($data)
402 return unserialize($data);
407 /** Return an iterator over the validation concerning the given type
408 * and the given user.
410 * @param type The type of the validations to fetch, null mean "any type"
411 * @param applyTo A User or a Profile object the validation applies to.
413 public static function iterate($type = null
, $applyTo = null
)
415 function toValidation($elt)
417 list($result, $stamp) = $elt;
418 $result = Validate
::unserialize($result);
419 $result->stamp
= $stamp;
425 $where[] = XDB
::format('type = {?}', $type);
428 if ($applyTo instanceof User
) {
429 $where[] = XDB
::format('uid = {?}', $applyTo->id());
430 } else if ($applyTo instanceof Profile
) {
431 $where[] = XDB
::format('pid = {?}', $applyTo->id());
434 if (!empty($where)) {
435 $where = 'WHERE ' . implode('AND', $where);
437 $it = XDB
::iterRow('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
441 return PlIteratorUtils
::map($it, 'toValidation');
445 /** Virtual class for profile related validation.
447 abstract class ProfileValidate
extends Validate
452 public $profileOwner;
453 public $userIsProfileOwner;
454 public $ownerIsRegistered;
460 * @param $_user: user object that required the validation.
461 * @param $_profile: profile object that is to be modified,
462 * its owner (if exists) can differ from $_user.
463 * @param $_unique: set to false if a profile can have multiple requests of this type.
464 * @param $_type: request's type.
466 public function __construct(User
&$_user, Profile
&$_profile, $_unique, $_type)
468 parent
::__construct($_user, $_unique, $_type);
469 $this->profile
= &$_profile;
470 $this->profileOwner
= $this->profile
->owner();
471 $this->userIsProfileOwner
= (!is_null($this->profileOwner
)
472 && $this->profileOwner
->id() == $this->user
->id());
473 $this->ownerIsRegistered
= $this->profile
->isActive();
477 // {{{ function submit()
479 /** Sends data to validation.
480 * It also deletes multiple requests for a couple (profile, type)
481 * when $this->unique is set to true.
483 public function submit()
486 XDB
::execute('DELETE FROM requests
487 WHERE pid = {?} AND type = {?}',
488 $this->profile
->id(), $this->type
);
491 $this->stamp
= date('YmdHis');
492 XDB
::execute('INSERT INTO requests (uid, pid, type, data, stamp)
493 VALUES ({?}, {?}, {?}, {?}, {?})',
494 $this->user
->id(), $this->profile
->id(), $this->type
, $this, $this->stamp
);
497 $globals->updateNbValid();
502 // {{{ function update()
504 protected function update()
506 XDB
::execute('UPDATE requests
507 SET data = {?}, stamp = stamp
508 WHERE pid = {?} AND type = {?} AND stamp = {?}',
509 $this, $this->profile
->id(), $this->type
, $this->stamp
);
514 // {{{ function clean()
516 /** Deletes request from 'requests' table.
517 * If $this->unique is set, it deletes every requests of this type.
519 public function clean()
524 $success = XDB
::execute('DELETE FROM requests
525 WHERE pid = {?} AND type = {?}',
526 $this->profile
->id(), $this->type
);
528 $success = XDB
::execute('DELETE FROM requests
529 WHERE pid = {?} AND type = {?} AND stamp = {?}',
530 $this->profile
->id(), $this->type
, $this->stamp
);
532 $globals->updateNbValid();
537 // {{{ function sendmail
539 protected function sendmail($isok)
541 // Only sends email if the profile's owner exists and is registered.
542 if ($this->ownerIsRegistered
) {
545 $mailer = new PlMailer();
546 $mailer->setSubject($this->_mail_subj());
547 $mailer->setFrom("validation+{$this->type}@{$globals->mail->domain}");
548 $mailer->addTo("\"{$this->profile->fullName()}\" <{$this->profileOwner->bestEmail()}>");
549 $mailer->addCc("validation+{$this->type}@{$globals->mail->domain}");
550 $body = ($this->profile
->isFemale() ?
"Chère camarade,\n\n" : "Cher camarade,\n\n")
551 . $this->_mail_body($isok)
552 . (Env
::has('comm') ?
"\n\n" . Env
::v('comm') : '')
553 . "\n\nCordialement,\n-- \nL'équipe de Polytechnique.org\n"
554 . $this->_mail_ps($isok);
555 $mailer->setTxtBody(wordwrap($body));
561 // {{{ function get_typed_request()
564 * @param $pid: profile's pid
565 * @param $type: request's type
566 * @param $stamp: request's timestamp
568 * Should only be used to retrieve an object in the databse with Validate::get_typed_request(...)
570 static public function get_typed_request($pid, $type, $stamp = -1)
573 $res = XDB
::query('SELECT data
575 WHERE pid = {?} and type = {?}',
578 $res = XDB
::query('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
580 WHERE pid = {?} AND type = {?} and stamp = {?}',
581 $pid, $type, $stamp);
583 if ($result = $res->fetchOneCell()) {
584 $result = Validate
::unserialize($result);
592 // {{{ function get_request_by_id()
594 static public function get_request_by_id($id)
596 list($pid, $type, $stamp) = explode('_', $id, 3);
597 return Validate
::get_typed_request($pid, $type, $stamp);
601 // {{{ function get_typed_requests()
603 /** Same as get_typed_request() but return an array of objects.
605 static public function get_typed_requests($pid, $type)
607 $res = XDB
::iterRow('SELECT data
609 WHERE pid = {?} and type = {?}
613 while (list($data) = $res->next()) {
614 $array[] = Validate
::unserialize($data);
620 // {{{ function get_typed_requests_count()
622 /** Same as get_typed_requests() but returns the count of available requests.
624 static public function get_typed_requests_count($pid, $type)
626 $res = XDB
::query('SELECT COUNT(data)
628 WHERE pid = {?} and type = {?}',
630 return $res->fetchOneCell();
638 return $this->profile
->id() . '_' . $this->type
. '_' . $this->stamp
;
644 foreach (glob(dirname(__FILE__
) . '/validations/*.inc.php') as $file) {
648 /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker enc=utf-8: */