<?php
/***************************************************************************
- * Copyright (C) 2003-2009 Polytechnique.org *
+ * Copyright (C) 2003-2011 Polytechnique.org *
* http://opensource.polytechnique.org/ *
* *
* This program is free software; you can redistribute it and/or modify *
define('SIZE_MAX', 32768);
global $globals;
-require_once $globals->spoolroot . '/core/classes/xdb.php';
-/**
- * Iterator class, that lists objects through the database
- */
-class ValidateIterator extends XOrgDBIterator
-{
- // {{{ constuctor
-
- public function __construct ()
- {
- parent::__construct('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s") FROM requests ORDER BY stamp', MYSQL_NUM);
- }
-
- // }}}
- // {{{ function next()
-
- public function next ()
- {
- if (list($result, $stamp) = parent::next()) {
- $result = Validate::unserialize($result);
- $result->stamp = $stamp;
- return($result);
- } else {
- return null;
- }
- }
-
- // }}}
-}
-/** classe "virtuelle" à dériver pour chaque nouvelle implémentation
+/** Virtual class to adapt for every possible implementation.
*/
abstract class Validate
{
public $stamp;
public $unique;
- // enable the refuse button
+ // Enable the refuse button.
public $refuse = true;
public $type;
public $comments = Array();
- // the validations rules : comments for admins
- public $rules = "Mieux vaut laisser une demande de validation à un autre admin que de valider une requête illégale ou que de refuser une demande légitime";
+ // Validations rules: comments for administrators.
+ 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.';
+
+ // Unless differently stated, a validation must be done by a site administrator.
+ public $requireAdmin = true;
// }}}
// {{{ constructor
- /** constructeur
- * @param $_user user object
- * @param $_unique requête pouvant être multiple ou non
- * @param $_type type de la donnée comme dans le champ type de x4dat.requests
+ /** Constructor
+ * @param $_user: user object that required the validation.
+ * @param $_unique: set to false if a profile can have multiple requests of this type.
+ * @param $_type: request's type.
*/
public function __construct(User &$_user, $_unique, $_type)
{
// }}}
// {{{ function submit()
- /** fonction à utiliser pour envoyer les données à la modération
- * cette fonction supprimme les doublons sur un couple ($user,$type) si $this->unique est vrai
+ /** Sends data to validation.
+ * It also deletes multiple requests for a couple (profile, type)
+ * when $this->unique is set to true.
*/
public function submit()
{
if ($this->unique) {
- XDB::execute('DELETE FROM requests WHERE user_id={?} AND type={?}', $this->user->id(), $this->type);
+ XDB::execute('DELETE FROM requests
+ WHERE uid = {?} AND type = {?}',
+ $this->user->id(), $this->type);
}
$this->stamp = date('YmdHis');
- XDB::execute('INSERT INTO requests (user_id, type, data, stamp) VALUES ({?}, {?}, {?}, {?})',
- $this->user->id(), $this->type, $this, $this->stamp);
+ XDB::execute('INSERT INTO requests (uid, type, data, stamp)
+ VALUES ({?}, {?}, {?}, {?})',
+ $this->user->id(), $this->type, $this, $this->stamp);
global $globals;
$globals->updateNbValid();
protected function update()
{
- XDB::execute('UPDATE requests SET data={?}, stamp=stamp
- WHERE user_id={?} AND type={?} AND stamp={?}',
+ XDB::execute('UPDATE requests
+ SET data = {?}, stamp = stamp
+ WHERE uid = {?} AND type = {?} AND stamp = {?}',
$this, $this->user->id(), $this->type, $this->stamp);
return true;
}
// }}}
// {{{ function clean()
- /** fonction à utiliser pour nettoyer l'entrée de la requête dans la table requests
- * attention, tout est supprimé si c'est un unique
+ /** Deletes request from 'requests' table.
+ * If $this->unique is set, it deletes every requests of this type.
*/
public function clean()
{
global $globals;
if ($this->unique) {
- $success = XDB::execute('DELETE FROM requests WHERE user_id={?} AND type={?}',
+ $success = XDB::execute('DELETE FROM requests
+ WHERE uid = {?} AND type = {?}',
$this->user->id(), $this->type);
} else {
- $success = XDB::execute('DELETE FROM requests WHERE user_id={?} AND type={?} AND stamp={?}',
+ $success = XDB::execute('DELETE FROM requests
+ WHERE uid = {?} AND type = {?} AND stamp = {?}',
$this->user->id(), $this->type, $this->stamp);
}
$globals->updateNbValid();
// }}}
// {{{ function handle_formu()
- /** fonction à réaliser en cas de validation du formulaire
+ /** Handles form validation.
*/
public function handle_formu()
{
+ if ($this->requireAdmin && !S::admin()) {
+ $this->trigError('Vous n\'avez pas les permissions nécessaires pour valider cette demande.');
+ return false;
+ }
+
if (Env::has('delete')) {
$this->clean();
- $this->trigSuccess('Requête supprimée');
+ $this->trigSuccess('Requête supprimée.');
return true;
}
- // mise à jour des informations
+ // Data updates.
if (Env::has('edit')) {
if ($this->handle_editor()) {
$this->update();
- $this->trigSuccess('Requête mise à jour');
+ $this->trigSuccess('Requête mise à jour.');
return true;
}
return false;
}
- // ajout d'un commentaire
+ // Comment addition.
if (Env::has('hold') && Env::has('comm')) {
$formid = Env::i('formid');
foreach ($this->comments as $comment) {
if (!strlen(trim(Env::v('comm')))) {
return true;
}
- $this->comments[] = Array(S::user()->login(), Env::v('comm'), $formid);
+ $this->comments[] = array(S::user()->login(), Env::v('comm'), $formid);
- // envoi d'un mail à hotliners
+ // Sends email to our hotline.
global $globals;
$mailer = new PlMailer();
$mailer->setSubject("Commentaires de validation {$this->type}");
$mailer->send();
$this->update();
- $this->trigSuccess('Commentaire ajouté');
+ $this->trigSuccess('Commentaire ajouté.');
return true;
}
if (Env::v('comm')) {
$this->sendmail(false);
$this->clean();
- $this->trigSuccess('Email de refus envoyé');
+ $this->trigSuccess('Email de refus envoyé.');
return true;
} else {
- $this->trigError('pas de motivation pour le refus !!!');
+ $this->trigError('Pas de motivation pour le refus !!!');
}
}
$body = ($this->user->isFemale() ? "Chère camarade,\n\n" : "Cher camarade,\n\n")
. $this->_mail_body($isok)
- . (Env::has('comm') ? "\n\n".Env::v('comm') : '')
- . "\n\nCordialement,\n\n-- \nL'équipe de Polytechnique.org\n";
+ . (Env::has('comm') ? "\n\n" . Env::v('comm') : '')
+ . "\n\nCordialement,\n-- \nL'équipe de Polytechnique.org\n"
+ . $this->_mail_ps($isok);
$mailer->setTxtBody(wordwrap($body));
$mailer->send();
// }}}
// {{{ function get_typed_request()
- /** fonction statique qui renvoie la requête de l'utilisateur d'id $uidau timestamp $t
- * @param $uid l'id de l'utilisateur concerné
- * @param $type le type de la requête
- * @param $stamp le timestamp de la requête
+ /**
+ * @param $pid: profile's pid
+ * @param $type: request's type
+ * @param $stamp: request's timestamp
*
- * XXX fonction "statique" XXX
- * à utiliser uniquement pour récupérer un objet dans la BD avec Validate::get_typed_request(...)
+ * Should only be used to retrieve an object in the databse with Validate::get_typed_request(...)
*/
static public function get_typed_request($uid, $type, $stamp = -1)
{
if ($stamp == -1) {
- $res = XDB::query('SELECT data FROM requests WHERE user_id={?} and type={?}', $uid, $type);
+ $res = XDB::query('SELECT data
+ FROM requests
+ WHERE uid = {?} and type = {?}',
+ $uid, $type);
} else {
- $res = XDB::query('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s") FROM requests WHERE user_id={?} AND type={?} and stamp={?}', $uid, $type, $stamp);
+ $res = XDB::query('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
+ FROM requests
+ WHERE uid = {?} AND type = {?} and stamp = {?}',
+ $uid, $type, $stamp);
}
if ($result = $res->fetchOneCell()) {
$result = Validate::unserialize($result);
// }}}
// {{{ function get_typed_requests()
- /** same as get_typed_request() but return an array of objects
+ /** Same as get_typed_request() but return an array of objects.
*/
static public function get_typed_requests($uid, $type)
{
- $res = XDB::iterRow('SELECT data FROM requests WHERE user_id={?} and type={?}', $uid, $type);
+ $res = XDB::iterRow('SELECT data
+ FROM requests
+ WHERE uid = {?} and type = {?}',
+ $uid, $type);
$array = array();
while (list($data) = $res->next()) {
$array[] = Validate::unserialize($data);
// }}}
// {{{ function get_typed_requests_count()
- /** same as get_typed_requests() but return the count of available requests.
+ /** Same as get_typed_requests() but return the count of available requests.
*/
static public function get_typed_requests_count($uid, $type)
{
- $res = XDB::query('SELECT COUNT(data) FROM requests WHERE user_id={?} and type={?}', $uid, $type);
+ $res = XDB::query('SELECT COUNT(data)
+ FROM requests
+ WHERE uid = {?} and type = {?}',
+ $uid, $type);
return $res->fetchOneCell();
}
abstract protected function _mail_subj();
// }}}
+ // {{{ function _mail_ps
+
+ protected function _mail_ps($isok)
+ {
+ return '';
+ }
+
+ // }}}
// {{{ function commit()
- /** fonction à utiliser pour insérer les données dans x4dat
+ /** Inserts data in database.
*/
abstract public function commit();
// }}}
// {{{ function formu()
- /** nom du template qui contient le formulaire */
+ /** Retunrs the name of the form's template. */
abstract public function formu();
// }}}
// {{{ function editor()
- /** nom du formulaire d'édition */
+ /** Returns the name of the edition form's template. */
public function editor()
{
return null;
// }}}
// {{{ function answers()
- /** automatic answers table for this type of validation */
+ /** Automatic answers table for this type of validation. */
public function answers()
{
static $answers_table;
if (!isset($answers_table[$this->type])) {
- $r = XDB::query("SELECT id, title, answer FROM requests_answers WHERE category = {?}", $this->type);
- $answers_table[$this->type] = $r->fetchAllAssoc($r);
+ $r = XDB::query('SELECT id, title, answer
+ FROM requests_answers
+ WHERE category = {?}',
+ $this->type);
+ $answers_table[$this->type] = $r->fetchAllAssoc();
}
return $answers_table[$this->type];
}
// }}}
- // {{{ function id()
+ // {{{ function id()
public function id()
{
// }}}
// {{{ function unserialize()
+
public static function unserialize($data)
{
- $obj = unserialize($data);
- /* XXX: Temporary for hruid migration */
- if (!isset($obj->user) || !is_object($obj)) {
- $obj->user =& User::get($obj->forlife);
+ return unserialize($data);
+ }
+
+ // }}}
+
+ /** Return an iterator over the validation concerning the given type
+ * and the given user.
+ *
+ * @param type The type of the validations to fetch, null mean "any type"
+ * @param applyTo A User or a Profile object the validation applies to.
+ */
+ public static function iterate($type = null, $applyTo = null)
+ {
+ function toValidation($elt)
+ {
+ list($result, $stamp) = $elt;
+ $result = Validate::unserialize($result);
+ $result->stamp = $stamp;
+ return $result;
+ }
+
+ $where = array();
+ if ($type) {
+ $where[] = XDB::format('type = {?}', $type);
+ }
+ if ($applyTo) {
+ if ($applyTo instanceof User) {
+ $where[] = XDB::format('uid = {?}', $applyTo->id());
+ } else if ($applyTo instanceof Profile) {
+ $where[] = XDB::format('pid = {?}', $applyTo->id());
+ }
+ }
+ if (!empty($where)) {
+ $where = 'WHERE ' . implode('AND', $where);
+ }
+ $it = XDB::iterRow('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
+ FROM requests
+ ' . $where . '
+ ORDER BY stamp');
+ return PlIteratorUtils::map($it, 'toValidation');
+ }
+}
+
+/** Virtual class for profile related validation.
+ */
+abstract class ProfileValidate extends Validate
+{
+ // {{{ properties
+
+ public $profile;
+ public $profileOwner;
+ public $userIsProfileOwner;
+ public $ownerIsRegistered;
+
+ // }}}
+ // {{{ constructor
+
+ /** Constructor
+ * @param $_user: user object that required the validation.
+ * @param $_profile: profile object that is to be modified,
+ * its owner (if exists) can differ from $_user.
+ * @param $_unique: set to false if a profile can have multiple requests of this type.
+ * @param $_type: request's type.
+ */
+ public function __construct(User &$_user, Profile &$_profile, $_unique, $_type)
+ {
+ parent::__construct($_user, $_unique, $_type);
+ $this->profile = &$_profile;
+ $this->profileOwner = $this->profile->owner();
+ $this->userIsProfileOwner = (!is_null($this->profileOwner)
+ && $this->profileOwner->id() == $this->user->id());
+ $this->ownerIsRegistered = $this->profile->isActive();
+ }
+
+ // }}}
+ // {{{ function submit()
+
+ /** Sends data to validation.
+ * It also deletes multiple requests for a couple (profile, type)
+ * when $this->unique is set to true.
+ */
+ public function submit()
+ {
+ if ($this->unique) {
+ XDB::execute('DELETE FROM requests
+ WHERE pid = {?} AND type = {?}',
+ $this->profile->id(), $this->type);
+ }
+
+ $this->stamp = date('YmdHis');
+ XDB::execute('INSERT INTO requests (uid, pid, type, data, stamp)
+ VALUES ({?}, {?}, {?}, {?}, {?})',
+ $this->user->id(), $this->profile->id(), $this->type, $this, $this->stamp);
+
+ global $globals;
+ $globals->updateNbValid();
+ return true;
+ }
+
+ // }}}
+ // {{{ function update()
+
+ protected function update()
+ {
+ XDB::execute('UPDATE requests
+ SET data = {?}, stamp = stamp
+ WHERE pid = {?} AND type = {?} AND stamp = {?}',
+ $this, $this->profile->id(), $this->type, $this->stamp);
+ return true;
+ }
+
+ // }}}
+ // {{{ function clean()
+
+ /** Deletes request from 'requests' table.
+ * If $this->unique is set, it deletes every requests of this type.
+ */
+ public function clean()
+ {
+ global $globals;
+
+ if ($this->unique) {
+ $success = XDB::execute('DELETE FROM requests
+ WHERE pid = {?} AND type = {?}',
+ $this->profile->id(), $this->type);
+ } else {
+ $success = XDB::execute('DELETE FROM requests
+ WHERE pid = {?} AND type = {?} AND stamp = {?}',
+ $this->profile->id(), $this->type, $this->stamp);
+ }
+ $globals->updateNbValid();
+ return $success;
+ }
+
+ // }}}
+ // {{{ function sendmail
+
+ protected function sendmail($isok)
+ {
+ // Only sends email if the profile's owner exists and is registered.
+ if ($this->ownerIsRegistered) {
+ global $globals;
+
+ $mailer = new PlMailer();
+ $mailer->setSubject($this->_mail_subj());
+ $mailer->setFrom("validation+{$this->type}@{$globals->mail->domain}");
+ $mailer->addTo("\"{$this->profile->fullName()}\" <{$this->profileOwner->bestEmail()}>");
+ $mailer->addCc("validation+{$this->type}@{$globals->mail->domain}");
+ $body = ($this->profile->isFemale() ? "Chère camarade,\n\n" : "Cher camarade,\n\n")
+ . $this->_mail_body($isok)
+ . (Env::has('comm') ? "\n\n" . Env::v('comm') : '')
+ . "\n\nCordialement,\n-- \nL'équipe de Polytechnique.org\n"
+ . $this->_mail_ps($isok);
+ $mailer->setTxtBody(wordwrap($body));
+ $mailer->send();
}
- /* XXX: End temporary block */
- return $obj;
}
+
+ // }}}
+ // {{{ function get_typed_request()
+
+ /**
+ * @param $pid: profile's pid
+ * @param $type: request's type
+ * @param $stamp: request's timestamp
+ *
+ * Should only be used to retrieve an object in the databse with Validate::get_typed_request(...)
+ */
+ static public function get_typed_request($pid, $type, $stamp = -1)
+ {
+ if ($stamp == -1) {
+ $res = XDB::query('SELECT data
+ FROM requests
+ WHERE pid = {?} and type = {?}',
+ $pid, $type);
+ } else {
+ $res = XDB::query('SELECT data, DATE_FORMAT(stamp, "%Y%m%d%H%i%s")
+ FROM requests
+ WHERE pid = {?} AND type = {?} and stamp = {?}',
+ $pid, $type, $stamp);
+ }
+ if ($result = $res->fetchOneCell()) {
+ $result = Validate::unserialize($result);
+ } else {
+ $result = false;
+ }
+ return $result;
+ }
+
+ // }}}
+ // {{{ function get_request_by_id()
+
+ static public function get_request_by_id($id)
+ {
+ list($pid, $type, $stamp) = explode('_', $id, 3);
+ return Validate::get_typed_request($pid, $type, $stamp);
+ }
+
+ // }}}
+ // {{{ function get_typed_requests()
+
+ /** Same as get_typed_request() but return an array of objects.
+ */
+ static public function get_typed_requests($pid, $type)
+ {
+ $res = XDB::iterRow('SELECT data
+ FROM requests
+ WHERE pid = {?} and type = {?}
+ ORDER BY stamp',
+ $pid, $type);
+ $array = array();
+ while (list($data) = $res->next()) {
+ $array[] = Validate::unserialize($data);
+ }
+ return $array;
+ }
+
+ // }}}
+ // {{{ function get_typed_requests_count()
+
+ /** Same as get_typed_requests() but returns the count of available requests.
+ */
+ static public function get_typed_requests_count($pid, $type)
+ {
+ $res = XDB::query('SELECT COUNT(data)
+ FROM requests
+ WHERE pid = {?} and type = {?}',
+ $pid, $type);
+ return $res->fetchOneCell();
+ }
+
+ // }}}
+ // {{{ function id()
+
+ public function id()
+ {
+ return $this->profile->id() . '_' . $this->type . '_' . $this->stamp;
+ }
+
+ // }}}
}
-foreach (glob(dirname(__FILE__).'/validations/*.inc.php') as $file) {
- require_once($file);
+foreach (glob(dirname(__FILE__) . '/validations/*.inc.php') as $file) {
+ require_once $file;
}
/* vim: set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker enc=utf-8: */