X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=include%2Fvalidations.inc.php;h=d5678bd4567e8b2f2ff8bfd4a3d815baa7196b5b;hb=7b094a73666cee7650946254c82800e25965db41;hp=d72ec3d3a1a131709dc13ed906381999674e950b;hpb=90862af65777b54eb2830b501729236fe50aa110;p=platal.git diff --git a/include/validations.inc.php b/include/validations.inc.php index d72ec3d..d5678bd 100644 --- a/include/validations.inc.php +++ b/include/validations.inc.php @@ -1,6 +1,6 @@ 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 { @@ -63,21 +34,21 @@ 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.'; // }}} // {{{ 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) { @@ -85,27 +56,28 @@ abstract class Validate $this->stamp = date('YmdHis'); $this->unique = $_unique; $this->type = $_type; - $res = XDB::query("SELECT promo_display AS promo - FROM profile_display - WHERE uid={?}", $this->user->id()); - $this->promo = $res->fetchOneCell(); + $this->promo = $this->user->promo(); } // }}} // {{{ 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(); @@ -117,8 +89,9 @@ abstract class Validate 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; } @@ -126,18 +99,20 @@ abstract class Validate // }}} // {{{ 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(); @@ -147,27 +122,27 @@ abstract class Validate // }}} // {{{ function handle_formu() - /** fonction à réaliser en cas de validation du formulaire + /** Handles form validation. */ public function handle_formu() { 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) { @@ -178,9 +153,9 @@ abstract class Validate 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}"); @@ -196,7 +171,7 @@ abstract class Validate $mailer->send(); $this->update(); - $this->trigSuccess('Commentaire ajouté'); + $this->trigSuccess('Commentaire ajouté.'); return true; } @@ -216,10 +191,10 @@ abstract class Validate 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 !!!'); } } @@ -240,8 +215,9 @@ abstract class Validate $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(); @@ -268,20 +244,25 @@ abstract class Validate // }}} // {{{ 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); @@ -303,11 +284,14 @@ abstract class Validate // }}} // {{{ 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); @@ -318,11 +302,14 @@ abstract class Validate // }}} // {{{ 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(); } @@ -337,22 +324,30 @@ abstract class Validate 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; @@ -361,19 +356,22 @@ abstract class Validate // }}} // {{{ 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() { @@ -390,20 +388,252 @@ abstract class Validate // }}} // {{{ 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); } - /* XXX: End temporary block */ - return $obj; + $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(); + } + } + + // }}} + // {{{ 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 = {?}', + $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: */