Moving to GitHub.
[platal.git] / include / validations.inc.php
index c3af12e..9bcde80 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /***************************************************************************
- *  Copyright (C) 2003-2010 Polytechnique.org                              *
+ *  Copyright (C) 2003-2014 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;
-        }
-
-        return null;
-    }
-
-    // }}}
-}
 
 /** Virtual class to adapt for every possible implementation.
  */
@@ -62,6 +31,7 @@ abstract class Validate
     // {{{ properties
 
     public $user;
+    public $formal;
 
     public $stamp;
     public $unique;
@@ -73,6 +43,9 @@ abstract class Validate
     // 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
 
@@ -81,9 +54,10 @@ abstract class Validate
      * @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)
+    public function __construct(User $_user, $_unique, $_type)
     {
         $this->user   = &$_user;
+        $this->formal = !$this->user->hasProfile();
         $this->stamp  = date('YmdHis');
         $this->unique = $_unique;
         $this->type   = $_type;
@@ -157,6 +131,11 @@ abstract class Validate
      */
     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.');
@@ -244,8 +223,13 @@ abstract class Validate
         $mailer->addTo("\"{$this->user->fullName()}\" <{$this->user->bestEmail()}>");
         $mailer->addCc("validation+{$this->type}@{$globals->mail->domain}");
 
-        $body = ($this->user->isFemale() ? "Chère camarade,\n\n" : "Cher camarade,\n\n")
-              . $this->_mail_body($isok)
+        // If the user has no profile, we should be more formal as if she has one.
+        if ($this->formal) {
+            $body = ($this->user->isFemale() ? 'Bonjour Madame' : 'Bonjour Monsieur');
+        } else {
+            $body = ($this->user->isFemale() ? 'Chère camarade' : 'Cher camarade');
+        }
+        $body .= ",\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);
@@ -406,7 +390,7 @@ abstract class Validate
 
     public function id()
     {
-        return $this->user->id() . '_' . $this->type . '_' . $this->stamp;
+        return str_replace(" ", "_", $this->user->id() . '_' . $this->type . '_' . $this->stamp);
     }
 
     // }}}
@@ -426,6 +410,45 @@ abstract class Validate
     }
 
     // }}}
+
+    /** 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);
+        } else {
+            $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.
@@ -437,6 +460,7 @@ abstract class ProfileValidate extends Validate
     public $profile;
     public $profileOwner;
     public $userIsProfileOwner;
+    public $ownerIsRegistered;
 
     // }}}
     // {{{ constructor
@@ -448,16 +472,14 @@ abstract class ProfileValidate extends Validate
      * @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)
+    public function __construct(User $_user, Profile $_profile, $_unique, $_type)
     {
         parent::__construct($_user, $_unique, $_type);
         $this->profile = &$_profile;
         $this->profileOwner = $this->profile->owner();
-        if (!is_null($this->profileOwner) && $this->profileOwner->id() == $this->user->id()) {
-            $this->userIsProfileOwner = true;
-        } else {
-            $this->userIsProfileOwner = false;
-        }
+        $this->userIsProfileOwner = (!is_null($this->profileOwner)
+                                     && $this->profileOwner->id() == $this->user->id());
+        $this->ownerIsRegistered = $this->profile->isActive();
     }
 
     // }}}
@@ -525,24 +547,23 @@ abstract class ProfileValidate extends Validate
 
     protected function sendmail($isok)
     {
-        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()}>");
-        if (!$this->userIsProfileOwner) {
-            $mailer->addCc("\"{$this->user->fullName()}\" <{$this->user->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);
+        // Only sends email if the profile's owner exists and is registered.
+        if ($this->ownerIsRegistered) {
+            global $globals;
 
-        $mailer->setTxtBody(wordwrap($body));
-        $mailer->send();
+            $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();
+        }
     }
 
     // }}}
@@ -594,7 +615,8 @@ abstract class ProfileValidate extends Validate
     {
         $res = XDB::iterRow('SELECT  data
                                FROM  requests
-                              WHERE  pid = {?} and type = {?}',
+                              WHERE  pid = {?} and type = {?}
+                           ORDER BY  stamp',
                             $pid, $type);
         $array = array();
         while (list($data) = $res->next()) {
@@ -604,6 +626,25 @@ abstract class ProfileValidate extends Validate
     }
 
     // }}}
+    // {{{ function get_all_typed_requests()
+
+    /** Same as get_typed_request() but return an array of objects.
+     */
+    static public function get_all_typed_requests($type)
+    {
+        $res = XDB::iterRow('SELECT  data
+                               FROM  requests
+                              WHERE  type = {?}
+                           ORDER BY  stamp',
+                            $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.
@@ -632,5 +673,5 @@ 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: */
+/* vim:set expandtab shiftwidth=4 tabstop=4 softtabstop=4 foldmethod=marker fenc=utf-8: */
 ?>