2 /***************************************************************************
3 * Copyright (C) 2003-2013 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
38 // Enable the refuse button.
39 public $refuse = true
;
42 public $comments = Array();
43 // Validations rules: comments for administrators.
44 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.';
46 // Unless differently stated, a validation must be done by a site administrator.
47 public $requireAdmin = true
;
53 * @param $_user: user object that required the validation.
54 * @param $_unique: set to false if a profile can have multiple requests of this type.
55 * @param $_type: request's type.
57 public function __construct(User
$_user, $_unique, $_type)
59 $this->user
= &$_user;
60 $this->formal
= !$this->user
->hasProfile();
61 $this->stamp
= date('YmdHis');
62 $this->unique
= $_unique;
64 $this->promo
= $this->user
->promo();
68 // {{{ function submit()
70 /** Sends data to validation.
71 * It also deletes multiple requests for a couple (profile, type)
72 * when $this->unique is set to true.
74 public function submit()
77 XDB
::execute('DELETE FROM requests
78 WHERE uid = {?} AND type = {?}',
79 $this->user
->id(), $this->type
);
82 $this->stamp
= date('YmdHis');
83 XDB
::execute('INSERT INTO requests (uid, type, data, stamp)
84 VALUES ({?}, {?}, {?}, {?})',
85 $this->user
->id(), $this->type
, $this, $this->stamp
);
88 $globals->updateNbValid();
93 // {{{ function update()
95 protected function update()
97 XDB
::execute('UPDATE requests
98 SET data = {?}, stamp = stamp
99 WHERE uid = {?} AND type = {?} AND stamp = {?}',
100 $this, $this->user
->id(), $this->type
, $this->stamp
);
105 // {{{ function clean()
107 /** Deletes request from 'requests' table.
108 * If $this->unique is set, it deletes every requests of this type.
110 public function clean()
115 $success = XDB
::execute('DELETE FROM requests
116 WHERE uid = {?} AND type = {?}',
117 $this->user
->id(), $this->type
);
119 $success = XDB
::execute('DELETE FROM requests
120 WHERE uid = {?} AND type = {?} AND stamp = {?}',
121 $this->user
->id(), $this->type
, $this->stamp
);
123 $globals->updateNbValid();
128 // {{{ function handle_formu()
130 /** Handles form validation.
132 public function handle_formu()
134 if ($this->requireAdmin
&& !S
::admin()) {
135 $this->trigError('Vous n\'avez pas les permissions nécessaires pour valider cette demande.');
139 if (Env
::has('delete')) {
141 $this->trigSuccess('Requête supprimée.');
146 if (Env
::has('edit')) {
147 if ($this->handle_editor()) {
149 $this->trigSuccess('Requête mise à jour.');
156 if (Env
::has('hold') && Env
::has('comm')) {
157 $formid = Env
::i('formid');
158 foreach ($this->comments
as $comment) {
159 if ($comment[2] === $formid) {
163 if (!strlen(trim(Env
::v('comm')))) {
166 $this->comments
[] = array(S
::user()->login(), Env
::v('comm'), $formid);
168 // Sends email to our hotline.
170 $mailer = new PlMailer();
171 $mailer->setSubject("Commentaires de validation {$this->type}");
172 $mailer->setFrom("validation+{$this->type}@{$globals->mail->domain}");
173 $mailer->addTo($globals->core
->admin_email
);
175 $body = "Validation {$this->type} pour {$this->user->login()}\n\n"
176 . S
::user()->login() . " a ajouté le commentaire :\n\n"
177 . Env
::v('comm') . "\n\n"
178 . "cf la discussion sur : " . $globals->baseurl
. "/admin/validate";
180 $mailer->setTxtBody(wordwrap($body));
184 $this->trigSuccess('Commentaire ajouté.');
188 if (Env
::has('accept')) {
189 if ($this->commit()) {
190 $this->sendmail(true
);
192 $this->trigSuccess('Email de validation envoyé');
195 $this->trigError('Erreur lors de la validation');
200 if (Env
::has('refuse')) {
201 if (Env
::v('comm')) {
202 $this->sendmail(false
);
204 $this->trigSuccess('Email de refus envoyé.');
207 $this->trigError('Pas de motivation pour le refus !!!');
215 // {{{ function sendmail
217 protected function sendmail($isok)
220 $mailer = new PlMailer();
221 $mailer->setSubject($this->_mail_subj());
222 $mailer->setFrom("validation+{$this->type}@{$globals->mail->domain}");
223 $mailer->addTo("\"{$this->user->fullName()}\" <{$this->user->bestEmail()}>");
224 $mailer->addCc("validation+{$this->type}@{$globals->mail->domain}");
226 // If the user has no profile, we should be more formal as if she has one.
228 $body = ($this->user
->isFemale() ?
'Bonjour Madame' : 'Bonjour Monsieur');
230 $body = ($this->user
->isFemale() ?
'Chère camarade' : 'Cher camarade');
232 $body .= ",\n\n" . $this->_mail_body($isok)
233 . (Env
::has('comm') ?
"\n\n" . Env
::v('comm') : '')
234 . "\n\nCordialement,\n-- \nL'équipe de Polytechnique.org\n"
235 . $this->_mail_ps($isok);
237 $mailer->setTxtBody(wordwrap($body));
242 // {{{ function trig()
244 protected function trigError($msg)
246 Platal
::page()->trigError($msg);
249 protected function trigWarning($msg)
251 Platal
::page()->trigWarning($msg);
254 protected function trigSuccess($msg)
256 Platal
::page()->trigSuccess($msg);
260 // {{{ function get_typed_request()
263 * @param $pid: profile's pid
264 * @param $type: request's type
265 * @param $stamp: request's timestamp
267 * Should only be used to retrieve an object in the databse with Validate::get_typed_request(...)
269 static public function get_typed_request($uid, $type, $stamp = -1)
272 $res = XDB
::query('SELECT data
274 WHERE uid = {?} and type = {?}',
277 $res = XDB
::query('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
279 WHERE uid = {?} AND type = {?} and stamp = {?}',
280 $uid, $type, $stamp);
282 if ($result = $res->fetchOneCell()) {
283 $result = Validate
::unserialize($result);
291 // {{{ function get_request_by_id()
293 static public function get_request_by_id($id)
295 list($uid, $type, $stamp) = explode('_', $id, 3);
296 return Validate
::get_typed_request($uid, $type, $stamp);
300 // {{{ function get_typed_requests()
302 /** Same as get_typed_request() but return an array of objects.
304 static public function get_typed_requests($uid, $type)
306 $res = XDB
::iterRow('SELECT data
308 WHERE uid = {?} and type = {?}',
311 while (list($data) = $res->next()) {
312 $array[] = Validate
::unserialize($data);
318 // {{{ function get_typed_requests_count()
320 /** Same as get_typed_requests() but return the count of available requests.
322 static public function get_typed_requests_count($uid, $type)
324 $res = XDB
::query('SELECT COUNT(data)
326 WHERE uid = {?} and type = {?}',
328 return $res->fetchOneCell();
332 // {{{ function _mail_body
334 abstract protected function _mail_body($isok);
337 // {{{ function _mail_subj
339 abstract protected function _mail_subj();
342 // {{{ function _mail_ps
344 protected function _mail_ps($isok)
350 // {{{ function commit()
352 /** Inserts data in database.
354 abstract public function commit();
357 // {{{ function formu()
359 /** Retunrs the name of the form's template. */
360 abstract public function formu();
363 // {{{ function editor()
365 /** Returns the name of the edition form's template. */
366 public function editor()
372 // {{{ function answers()
374 /** Automatic answers table for this type of validation. */
375 public function answers()
377 static $answers_table;
378 if (!isset($answers_table[$this->type
])) {
379 $r = XDB
::query('SELECT id, title, answer
380 FROM requests_answers
381 WHERE category = {?}',
383 $answers_table[$this->type
] = $r->fetchAllAssoc();
385 return $answers_table[$this->type
];
393 return str_replace(" ", "_", $this->user
->id() . '_' . $this->type
. '_' . $this->stamp
);
397 // {{{ function ruleText()
399 public function ruleText()
401 return str_replace('\'', '\\\'', $this->rules
);
405 // {{{ function unserialize()
407 public static function unserialize($data)
409 return unserialize($data);
414 /** Return an iterator over the validation concerning the given type
415 * and the given user.
417 * @param type The type of the validations to fetch, null mean "any type"
418 * @param applyTo A User or a Profile object the validation applies to.
420 public static function iterate($type = null
, $applyTo = null
)
422 function toValidation($elt)
424 list($result, $stamp) = $elt;
425 $result = Validate
::unserialize($result);
426 $result->stamp
= $stamp;
432 $where[] = XDB
::format('type = {?}', $type);
435 if ($applyTo instanceof User
) {
436 $where[] = XDB
::format('uid = {?}', $applyTo->id());
437 } else if ($applyTo instanceof Profile
) {
438 $where[] = XDB
::format('pid = {?}', $applyTo->id());
441 if (!empty($where)) {
442 $where = 'WHERE ' . implode('AND', $where);
444 $it = XDB
::iterRow('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
448 return PlIteratorUtils
::map($it, 'toValidation');
452 /** Virtual class for profile related validation.
454 abstract class ProfileValidate
extends Validate
459 public $profileOwner;
460 public $userIsProfileOwner;
461 public $ownerIsRegistered;
467 * @param $_user: user object that required the validation.
468 * @param $_profile: profile object that is to be modified,
469 * its owner (if exists) can differ from $_user.
470 * @param $_unique: set to false if a profile can have multiple requests of this type.
471 * @param $_type: request's type.
473 public function __construct(User
$_user, Profile
$_profile, $_unique, $_type)
475 parent
::__construct($_user, $_unique, $_type);
476 $this->profile
= &$_profile;
477 $this->profileOwner
= $this->profile
->owner();
478 $this->userIsProfileOwner
= (!is_null($this->profileOwner
)
479 && $this->profileOwner
->id() == $this->user
->id());
480 $this->ownerIsRegistered
= $this->profile
->isActive();
484 // {{{ function submit()
486 /** Sends data to validation.
487 * It also deletes multiple requests for a couple (profile, type)
488 * when $this->unique is set to true.
490 public function submit()
493 XDB
::execute('DELETE FROM requests
494 WHERE pid = {?} AND type = {?}',
495 $this->profile
->id(), $this->type
);
498 $this->stamp
= date('YmdHis');
499 XDB
::execute('INSERT INTO requests (uid, pid, type, data, stamp)
500 VALUES ({?}, {?}, {?}, {?}, {?})',
501 $this->user
->id(), $this->profile
->id(), $this->type
, $this, $this->stamp
);
504 $globals->updateNbValid();
509 // {{{ function update()
511 protected function update()
513 XDB
::execute('UPDATE requests
514 SET data = {?}, stamp = stamp
515 WHERE pid = {?} AND type = {?} AND stamp = {?}',
516 $this, $this->profile
->id(), $this->type
, $this->stamp
);
521 // {{{ function clean()
523 /** Deletes request from 'requests' table.
524 * If $this->unique is set, it deletes every requests of this type.
526 public function clean()
531 $success = XDB
::execute('DELETE FROM requests
532 WHERE pid = {?} AND type = {?}',
533 $this->profile
->id(), $this->type
);
535 $success = XDB
::execute('DELETE FROM requests
536 WHERE pid = {?} AND type = {?} AND stamp = {?}',
537 $this->profile
->id(), $this->type
, $this->stamp
);
539 $globals->updateNbValid();
544 // {{{ function sendmail
546 protected function sendmail($isok)
548 // Only sends email if the profile's owner exists and is registered.
549 if ($this->ownerIsRegistered
) {
552 $mailer = new PlMailer();
553 $mailer->setSubject($this->_mail_subj());
554 $mailer->setFrom("validation+{$this->type}@{$globals->mail->domain}");
555 $mailer->addTo("\"{$this->profile->fullName()}\" <{$this->profileOwner->bestEmail()}>");
556 $mailer->addCc("validation+{$this->type}@{$globals->mail->domain}");
557 $body = ($this->profile
->isFemale() ?
"Chère camarade,\n\n" : "Cher camarade,\n\n")
558 . $this->_mail_body($isok)
559 . (Env
::has('comm') ?
"\n\n" . Env
::v('comm') : '')
560 . "\n\nCordialement,\n-- \nL'équipe de Polytechnique.org\n"
561 . $this->_mail_ps($isok);
562 $mailer->setTxtBody(wordwrap($body));
568 // {{{ function get_typed_request()
571 * @param $pid: profile's pid
572 * @param $type: request's type
573 * @param $stamp: request's timestamp
575 * Should only be used to retrieve an object in the databse with Validate::get_typed_request(...)
577 static public function get_typed_request($pid, $type, $stamp = -1)
580 $res = XDB
::query('SELECT data
582 WHERE pid = {?} and type = {?}',
585 $res = XDB
::query('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
587 WHERE pid = {?} AND type = {?} and stamp = {?}',
588 $pid, $type, $stamp);
590 if ($result = $res->fetchOneCell()) {
591 $result = Validate
::unserialize($result);
599 // {{{ function get_request_by_id()
601 static public function get_request_by_id($id)
603 list($pid, $type, $stamp) = explode('_', $id, 3);
604 return Validate
::get_typed_request($pid, $type, $stamp);
608 // {{{ function get_typed_requests()
610 /** Same as get_typed_request() but return an array of objects.
612 static public function get_typed_requests($pid, $type)
614 $res = XDB
::iterRow('SELECT data
616 WHERE pid = {?} and type = {?}
620 while (list($data) = $res->next()) {
621 $array[] = Validate
::unserialize($data);
627 // {{{ function get_all_typed_requests()
629 /** Same as get_typed_request() but return an array of objects.
631 static public function get_all_typed_requests($type)
633 $res = XDB
::iterRow('SELECT data
639 while (list($data) = $res->next()) {
640 $array[] = Validate
::unserialize($data);
646 // {{{ function get_typed_requests_count()
648 /** Same as get_typed_requests() but returns the count of available requests.
650 static public function get_typed_requests_count($pid, $type)
652 $res = XDB
::query('SELECT COUNT(data)
654 WHERE pid = {?} and type = {?}',
656 return $res->fetchOneCell();
664 return $this->profile
->id() . '_' . $this->type
. '_' . $this->stamp
;
670 foreach (glob(dirname(__FILE__
) . '/validations/*.inc.php') as $file) {
674 /* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker enc=utf-8: */