Merge branch 'xorg/maint' into xorg/master
authorStéphane Jacob <sj@m4x.org>
Sat, 16 Apr 2011 16:45:42 +0000 (18:45 +0200)
committerStéphane Jacob <sj@m4x.org>
Sat, 16 Apr 2011 16:45:42 +0000 (18:45 +0200)
52 files changed:
ChangeLog
Makefile
README [new file with mode: 0644]
banana
classes/direnum.php
classes/profile.php
classes/userfilter.php
classes/userfilter/conditions.inc.php
configs/mails.conf
configs/platal.ini
core
htdocs/url_redirect.php [new file with mode: 0644]
include/emails.combobox.inc.php
include/emails.inc.php
include/name.func.inc.php
include/ufbuilder.inc.php
include/validations.inc.php
include/validations/broken.inc.php
include/validations/evts.inc.php
include/validations/marketing.inc.php
include/validations/nl.inc.php
include/validations/paiements.inc.php
include/validations/surveys.inc.php
include/vcard.inc.php
modules/admin.php
modules/email.php
modules/lists.php
modules/profile.php
modules/profile/general.inc.php
modules/profile/jobs.inc.php
modules/search.php
modules/urlshortener.php
modules/xnet.php
modules/xnetgrp.php
modules/xnetlists.php
templates/admin/index.tpl
templates/googleapps/admin.user.tpl
templates/include/emails.combobox.tpl
templates/lists/admin_aliases.tpl [new file with mode: 0644]
templates/lists/admin_edit_alias.tpl [new file with mode: 0644]
templates/profile/jobs.job.tpl
templates/search/adv.form.tpl
templates/urlshortener/admin.tpl
templates/xnetgrp/mail.tpl
templates/xnetlists/index.tpl
upgrade/1.1.1/01_languages.sql [new file with mode: 0644]
upgrade/1.1.1/02_emails.sql [new file with mode: 0644]
upgrade/1.1.1/03_url.sql [new file with mode: 0644]
upgrade/1.1.1/04_jobs.sql [new file with mode: 0644]
upgrade/1.1.1/README [new file with mode: 0644]
upgrade/1.1.1/connect.db.inc.php [new symlink]
upgrade/1.1.1/update.sh [new file with mode: 0755]

index 5f77a84..0516778 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,28 @@
 ================================================================================
+VERSION 1.1.1                                                         XX XX XXXX
+
+Bug/Wish:
+
+    * Emails:
+        - #1110: Improves email combobox                                   -JAC
+        - #1459: Lists and administrates aliases on main domain            -JAC
+
+    * Profile:
+        - #1445: Add job entry year                                        -JAC
+
+    * Search:
+        - #911: Adds search on corps                                       -JAC
+        - #990: Adds search on broken redirections                         -JAC
+
+    * XnetList:
+        - #957: Allows xnet list sorting by description and members count  -JAC
+
+From 1.1.0 branch:
+
+    * Search:
+        - #1449: Load json2 on IE because IE<=7 do not implement JSON      -FRU
+
+================================================================================
 VERSION 1.1.0                                                         26 03 2011
 
 New:
index d63ab9b..84edd6f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -139,25 +139,8 @@ get-wiki:
 ## openid
 ##
 
-openid: get-openid spool/openid/store
-
-# There is no obvious way to automatically use the latest version
-OPENID_VERSION = 2.2.2
-OPENID_COMMIT  = 782224d
-get-openid:
-       @if ! test -d include/Auth; then                                  \
-               wget --no-check-certificate                                   \
-                       https://github.com/openid/php-openid/tarball/$(OPENID_VERSION) \
-                       -O php-openid-$(OPENID_VERSION).tar.gz; \
-               tar -xzf php-openid-$(OPENID_VERSION).tar.gz;                \
-               mv openid-php-openid-$(OPENID_COMMIT)/Auth include/;                \
-               rm php-openid-$(OPENID_VERSION).tar.gz;                      \
-               rm -r openid-php-openid-$(OPENID_COMMIT);                           \
-       fi
-
-spool/openid/store:
-       mkdir -p $@
-       chmod o+w $@
+openid:
+       -rm -rf include/Auth
 
 ##
 ## banana
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..8c46db2
--- /dev/null
+++ b/README
@@ -0,0 +1,34 @@
+Deps
+====
+
+Debian
+------
+* php5-cli
+* php5-tidy
+* php5-mysql
+* php5-xmlrpc
+* php5-curl
+* php5-gd
+* php-date
+* php-fpdf
+* php-mail
+* php-mail-mime
+* smarty
+* apache2
+* libapache2-mod-php5
+* python
+* mysql-server
+* mysql-client
+* phpunit
+
+Recommended
+-----------
+* php5-xdebug
+* php5-xcache
+
+Languages and countries administration
+--------------------------------------
+* pkg-isocodes
+* isoquery
+
+// vim:ft=asciidoc:
diff --git a/banana b/banana
index de2d442..212ada1 160000 (submodule)
--- a/banana
+++ b/banana
@@ -1 +1 @@
-Subproject commit de2d442deb5be66b2bbe677b490588e470cfce8c
+Subproject commit 212ada1babbd46d48b44e47f24bb129370c24b6a
index 5ed7807..e45164c 100644 (file)
@@ -40,7 +40,8 @@ class DirEnum
     const EDUDEGREES     = 'educationdegrees';
     const EDUFIELDS      = 'educationfields';
 
-    const CORPS          = 'corps';
+    const CURRENTCORPS   = 'currentcorps';
+    const ORIGINCORPS    = 'origincorps';
     const CORPSRANKS     = 'corpsranks';
 
     const NATIONALITIES  = 'nationalities';
@@ -533,18 +534,32 @@ class DE_EducationFields extends DirEnumeration
 }
 // }}}
 
-// {{{ class DE_Corps
-class DE_Corps extends DirEnumeration
+// {{{ class DE_CurrentCorps
+class DE_CurrentCorps extends DirEnumeration
 {
     protected $idfield   = 'profile_corps_enum.id';
     protected $valfield  = 'profile_corps_enum.name';
     protected $valfield2 = 'profile_corps_enum.abbrev';
     protected $from      = 'profile_corps_enum';
+    protected $where     = 'WHERE profile_corps_enum.still_exists = 1';
 
     protected $ac_unique = 'profile_corps.pid';
     protected $ac_join   = 'INNER JOIN profile_corps ON (profile_corps.current_corpsid = profile_corps_enum.id)';
 }
 // }}}
+//
+// {{{ class DE_OriginCorps
+class DE_OriginCorps extends DirEnumeration
+{
+    protected $idfield   = 'profile_corps_enum.id';
+    protected $valfield  = 'profile_corps_enum.name';
+    protected $valfield2 = 'profile_corps_enum.abbrev';
+    protected $from      = 'profile_corps_enum';
+
+    protected $ac_unique = 'profile_corps.pid';
+    protected $ac_join   = 'INNER JOIN profile_corps ON (profile_corps.original_corpsid = profile_corps_enum.id)';
+}
+// }}}
 
 // {{{ class DE_CorpsRanks
 class DE_CorpsRanks extends DirEnumeration
index d9b55b0..73a9fff 100644 (file)
@@ -1087,8 +1087,8 @@ class Profile implements PlExportable
                 continue;
             }
             $pid   = $key['pid'];
-            $toks  = preg_split('/[ \'\-]+/', strtolower(replace_accent($key['name'])),
-                                -1, PREG_SPLIT_NO_EMPTY);
+            require_once 'name.func.inc.php';
+            $toks = split_name_for_search($key['name']);
             $toks = array_reverse($toks);
 
             /* Split the score between the tokens to avoid the user to be over-rated.
index 51f715d..83cf251 100644 (file)
@@ -937,12 +937,22 @@ class UserFilter extends PlFilter
      *  that email as a source email.
      * @return Suffix to use to access the adequate table.
      */
-     public function addAliasFilter($email = null)
+    public function addAliasFilter($email = null)
     {
         $this->requireAccounts();
         return $this->register_optional($this->sa, $email);
     }
 
+    private $with_rf = false;
+    /** Allows filtering by active redirection.
+     * @return Suffix to use to access the adequate table.
+     */
+    public function addActiveEmailRedirectFilter($email = null)
+    {
+        $this->requireAccounts();
+        $this->with_rf = true;
+    }
+
     protected function emailJoins()
     {
         global $globals;
@@ -974,6 +984,9 @@ class UserFilter extends PlFilter
                 $joins['sa' . $sub] = PlSqlJoin::left('email_source_account', '$ME.uid = $UID AND $ME.email IN {?}', $emails);
             }
         }
+        if ($this->with_rf) {
+            $joins['rf'] = PlSqlJoin::left('email_redirect_account', '$ME.uid = $UID AND $ME.type != \'imap\' AND $ME.flags = \'active\'');;
+        }
         return $joins;
     }
 
@@ -1033,10 +1046,10 @@ class UserFilter extends PlFilter
         $this->requireProfiles();
         $this->pc = true;
         if ($type == UFC_Corps::CURRENT) {
-            $pce['pcec'] = 'current_corpsid';
+            $this->pce['pcec'] = 'current_corpsid';
             return 'pcec';
         } else if ($type == UFC_Corps::ORIGIN) {
-            $pce['pceo'] = 'original_corpsid';
+            $this->pce['pceo'] = 'original_corpsid';
             return 'pceo';
         }
     }
index e445d21..c689f0b 100644 (file)
@@ -339,8 +339,8 @@ class UFC_HasEmailRedirect extends UserFilterCondition
 {
     public function buildCondition(PlFilter $uf)
     {
-        $sub_redirect = $uf->addEmailRedirectFilter();
-        return 'ra' . $sub_redirect . '.flags = \'active\'';
+        $sub_redirect = $uf->addActiveEmailRedirectFilter();
+        return 'rf.redirect IS NOT NULL';
     }
 
     public function export()
@@ -1198,11 +1198,13 @@ class UFC_Corps extends UserFilterCondition
     const ORIGIN    = 2;
 
     private $corps;
+    private $id;
     private $type;
 
-    public function __construct($corps, $type = self::CURRENT)
+    public function __construct($corps, $id = null, $type = self::CURRENT)
     {
         $this->corps = $corps;
+        $this->id    = $id;
         $this->type  = $type;
     }
 
@@ -1214,8 +1216,14 @@ class UFC_Corps extends UserFilterCondition
          * pcec for profile_corps_enum - current
          */
         $sub = $uf->addCorpsFilter($this->type);
-        $cond = $sub . '.abbreviation = ' . $corps;
-        $cond .= ' AND ' . $uf->getVisibilityCondition($sub . '.corps_pub');
+        if (is_null($this->id)) {
+            $cond = $sub . '.abbreviation = ' . $this->corps;
+        } else {
+            $cond = $sub . '.id = ' . $this->id;
+        }
+        // XXX(x2006barrois): find a way to get rid of that hardcoded
+        // reference to 'pc'.
+        $cond .= ' AND ' . $uf->getVisibilityCondition('pc.corps_pub');
         return $cond;
     }
 }
@@ -1227,9 +1235,12 @@ class UFC_Corps extends UserFilterCondition
 class UFC_Corps_Rank extends UserFilterCondition
 {
     private $rank;
-    public function __construct($rank)
+    private $id;
+
+    public function __construct($rank, $id = null)
     {
         $this->rank = $rank;
+        $this->id   = $id;
     }
 
     public function buildCondition(PlFilter $uf)
@@ -1239,7 +1250,11 @@ class UFC_Corps_Rank extends UserFilterCondition
          * pcr for profile_corps_rank
          */
         $sub = $uf->addCorpsRankFilter();
-        $cond = $sub . '.abbreviation = ' . $rank;
+        if (is_null($this->id)) {
+            $cond = $sub . '.abbreviation = ' . $this->rank;
+        } else {
+            $cond = $sub . '.id = ' . $this->id;
+        }
         // XXX(x2006barrois): find a way to get rid of that hardcoded
         // reference to 'pc'.
         $cond .= ' AND ' . $uf->getVisibilityCondition('pc.corps_pub');
index 6e04953..1bde9a6 100644 (file)
@@ -84,5 +84,5 @@ to=br@staff.polytechnique.org
 
 [xnet_registration]
 from=register@polytechnique.org
-cc=register@polytechnique.org
+cc=validation+xnet_account@polytechnique.org
 subject="Inscription à Polytechnique.net"
index c7e159e..a057415 100644 (file)
@@ -104,6 +104,9 @@ secure_domain = ""
 ; command line. The value is computed automatically when php serves a web page.
 baseurl = "https://www.example.org/"
 
+; The base url of the url shortener.
+baseurl_shortener = ""
+
 ; $globals->sitename
 ; The name of the site
 ;
diff --git a/core b/core
index cab6c1c..36b41c6 160000 (submodule)
--- a/core
+++ b/core
@@ -1 +1 @@
-Subproject commit cab6c1c15dfa75c04b433447e608edb59171c376
+Subproject commit 36b41c6c79c3a434b7e5b374befb3090105dd3aa
diff --git a/htdocs/url_redirect.php b/htdocs/url_redirect.php
new file mode 100644 (file)
index 0000000..f4e25bd
--- /dev/null
@@ -0,0 +1,55 @@
+<?php
+/***************************************************************************
+ *  Copyright (C) 2003-2011 Polytechnique.org                              *
+ *  http://opensource.polytechnique.org/                                   *
+ *                                                                         *
+ *  This program is free software; you can redistribute it and/or modify   *
+ *  it under the terms of the GNU General Public License as published by   *
+ *  the Free Software Foundation; either version 2 of the License, or      *
+ *  (at your option) any later version.                                    *
+ *                                                                         *
+ *  This program is distributed in the hope that it will be useful,        *
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          *
+ *  GNU General Public License for more details.                           *
+ *                                                                         *
+ *  You should have received a copy of the GNU General Public License      *
+ *  along with this program; if not, write to the Free Software            *
+ *  Foundation, Inc.,                                                      *
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
+ ***************************************************************************/
+
+require_once 'xorg.inc.php';
+
+$platal = new Xorg('core');
+
+global $globals;
+$alias = ltrim($platal->pl_self(), '/');
+
+if (preg_match('/^[a-zA-Z0-9\-\/]+$/i', $alias)) {
+    $url = XDB::fetchOneCell('SELECT  url
+                                FROM  url_shortener
+                               WHERE  alias = {?}',
+                             $alias);
+    if ($url) {
+        http_redirect($url);
+    }
+}
+
+header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');
+?>
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
+<html>
+  <head>
+    <title>404 Not Found</title>
+  </head>
+  <body>
+    <h1>Not Found</h1>
+    The requested URL <?php echo $_SERVER['REQUEST_URI'] ?> was not found on this server.<p>
+    <hr>
+    <address><?php echo $_SERVER['SERVER_SIGNATURE'] ?></address>
+  </body>
+</html>
+<?php
+// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
+?>
index 3965ea9..0e53f1b 100644 (file)
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-function fill_email_combobox(PlPage $page, $user = null, $profile = null)
+function fill_email_combobox(PlPage $page, array $retrieve, $user = null)
 {
+    require_once 'emails.inc.php';
     if (is_null($user)) {
         $user = S::user();
     }
-    if (is_null($profile)) {
-        /* Always refetch the profile. */
-        $profile = $user->profile(true);
-    }
-    $email_type = 'directory';
+    /* Always refetch the profile. */
+    $profile = $user->profile(true);
 
-    if ($profile) {
-        $email_directory = $profile->email_directory;
-        $page->assign('email_directory', $email_directory);
+    $emails = array();
+    if (in_array('source', $retrieve)) {
+        $emails['Emails polytechniciens'] = XDB::fetchColumn('SELECT  CONCAT(s.email, \'@\', d.name)
+                                                                FROM  email_source_account  AS s
+                                                          INNER JOIN  email_virtual_domains AS m ON (s.domain = m.id)
+                                                          INNER JOIN  email_virtual_domains AS d ON (d.aliasing = m.id)
+                                                               WHERE  s.uid = {?}
+                                                            ORDER BY  s.email, d.name',
+                                                             $user->id());
+    }
 
-        $res = XDB::fetchAllAssoc('SELECT  email
-                                     FROM  profile_job
-                                    WHERE  pid = {?}', $profile->id());
-        $pro = array();
-        foreach ($res as $res_it) {
-            if ($res_it['email'] != '') {
-                $pro[] = $res_it['email'];
-                if ($email_directory == $res_it['email']) {
-                    $email_type = "pro";
-                }
+    if (in_array('redirect', $retrieve)) {
+        $redirect = new Redirect($user);
+        $emails['Redirections'] = array();
+        foreach ($redirect->emails as $redirect_it) {
+            if ($redirect_it->is_redirection()) {
+                $emails['Redirections'] = $redirect_it->email;
             }
         }
-        $page->assign('list_email_pro', $pro);
     }
 
-    if ($user) {
-        $res = XDB::fetchAllAssoc('SELECT  CONCAT(s.email, \'@\', d.name)
-                                     FROM  email_source_account  AS s
-                               INNER JOIN  email_virtual_domains AS m ON (s.domain = m.id)
-                               INNER JOIN  email_virtual_domains AS d ON (d.aliasing = m.id)
-                                    WHERE  s.uid = {?}
-                                 ORDER BY  s.email, d.name', $user->id());
-        $page->assign('list_email_X', $res);
-        foreach ($res as $res_it) {
-            if ($email_directory == $res_it) {
-                $email_type = 'X';
-            }
+    if ($profile) {
+        if (in_array('job', $retrieve)) {
+            $emails['Emails professionels'] = XDB::fetchColumn('SELECT  email
+                                                                  FROM  profile_job
+                                                                 WHERE  pid = {?} AND email IS NOT NULL AND email != \'\'',
+                                                               $profile->id());
         }
 
-        require_once 'emails.inc.php';
-        $redirect = new Redirect($user);
-        $redir    = array();
-        foreach ($redirect->emails as $redirect_it) {
-            if ($redirect_it->is_redirection()) {
-                $redir[] = $redirect_it->email;
-                if ($email_directory == $redirect_it->email) {
-                    $email_type = 'redir';
+        if ($profile->email_directory) {
+            if (in_array('directory', $retrieve)) {
+                foreach ($emails as &$email_list) {
+                    foreach ($email_list as $key => $email) {
+                        if ($profile->email_directory == $email) {
+                            unset($email_list[$key]);
+                        }
+                    }
+                }
+                $emails['Email annuaire AX'] = array($profile->email_directory);
+            } elseif (in_array('stripped_directory', $retrieve)) {
+                if (User::isForeignEmailAddress($profile->email_directory)) {
+                    $is_redirect = XDB::fecthOneCell('SELECT  COUNT(*)
+                                                        FROM  email_redirect_account
+                                                       WHERE  uid = {?} AND redirect = {?}',
+                                                     $user->id(), $profile->email_directory);
+                    if ($is_redirect == 0) {
+                        $emails['Email annuaire AX'] = array($profile->email_directory);
+                    }
                 }
             }
         }
-        $page->assign('list_email_redir', $redir);
-        $page->assign('email_type', $email_type);
-    } else {
-        $page->assign('list_email_X', array());
-        $page->assign('list_email_redir', array());
-        $page->assign('list_email_pro', array());
+
+        if (isset($emails['Emails professionels']) && isset($emails['Redirections'])) {
+            $intersect = array_intersect($emails['Emails professionels'], $emails['Redirections']);
+            foreach ($intersect as $key => $email) {
+                unset($emails['Emails professionels'][$key]);
+            }
+        }
+    }
+
+    $emails_count = 0;
+    foreach ($emails as $email_list) {
+        $emails_count += count($email_list);
     }
+    $page->assign('emails_count', $emails_count);
+    $page->assign('email_lists', $emails);
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index b2ddb4b..19c172e 100644 (file)
@@ -24,6 +24,15 @@ define('ERROR_INACTIVE_REDIRECTION', 2);
 define('ERROR_INVALID_EMAIL', 3);
 define('ERROR_LOOP_EMAIL', 4);
 
+// Checks if an email update is required in MLs and aliases.
+// This occurs when the user don't have email permissions and her email has changed.
+function require_email_update(User $user, $new_email)
+{
+    Platal::assert(!is_null($user), 'User cannot be null.');
+
+    return !$user->checkPerms(User::PERM_MAIL) && $new_email != $user->forlifeEmail();
+}
+
 function format_email_alias($email)
 {
     if ($user = User::getSilent($email)) {
@@ -81,6 +90,15 @@ function update_list_alias($email, $former_email, $local_part, $domain, $type =
     return true;
 }
 
+// Updates an email in all aliases (groups and events).
+function update_alias_user($former_email, $new_email)
+{
+    XDB::execute('UPDATE  email_virtual
+                     SET  redirect = {?}
+                   WHERE  redirect = {?} AND (type = \'alias\' OR type = \'event\')',
+                 $new_email, $former_email);
+}
+
 function list_alias_members($local_part, $domain)
 {
     $emails = XDB::fetchColumn('SELECT  DISTINCT(redirect)
index 8ac831d..d2cbe65 100644 (file)
@@ -228,6 +228,14 @@ function build_sn_pub($pid)
     return $sn_old;
 }
 
+/** Splits a name into tokens, as used in search_name.
+ * Used for search_name rebuilding and for queries.
+ */
+function split_name_for_search($name) {
+    return preg_split('/[[:space:]\'\-]+/', strtolower(replace_accent($name)),
+                      -1, PREG_SPLIT_NO_EMPTY);
+}
+
 /** Transform a name to its canonical value so it can be compared
  * to another form (different case, with accents or with - instead
  * of blanks).
index d46d0af..13cb8fc 100644 (file)
@@ -344,6 +344,7 @@ class UFB_AdvancedSearch extends UserFilterBuilder
             new UFBF_Promo('promo2', 'Promotion', 'egal2'),
             new UFBF_Sex('woman', 'Sexe'),
             new UFBF_Registered('subscriber', 'Inscrit'),
+            new UFBF_HasEmailRedirect('has_email_redirect', 'A une redirection active'),
             new UFBF_Dead('alive', 'En vie'),
 
             new UFBF_Town('city', 'Ville / Code Postal'),
@@ -356,6 +357,10 @@ class UFB_AdvancedSearch extends UserFilterBuilder
             new UFBF_JobCv('cv', 'CV'),
             new UFBF_JobTerms('jobterm', 'Mots-clefs'),
 
+            new UFBF_OriginCorps('origin_corps', 'Corps d\'origine'),
+            new UFBF_CurrentCorps('current_corps', 'Corps actuel'),
+            new UFBF_CorpsRank('corps_rank', 'Grade'),
+
             new UFBF_Nationality('nationaliteTxt', 'nationalite', 'Nationalité'),
             new UFBF_Binet('binetTxt', 'binet', 'Binet'),
             new UFBF_Group('groupexTxt', 'groupex', 'Groupe X'),
@@ -831,7 +836,9 @@ class UFBF_Name extends UFBF_Text
             return false;
         }
 
-        $this->val = preg_split('/[[:space:]]/', $this->val);
+        require_once 'name.func.inc.php';
+
+        $this->val = split_name_for_search($this->val);
         if (count($this->val) == 0) {
             $this->empty = true;
         }
@@ -954,6 +961,25 @@ class UFBF_Registered extends UFBF_Enum
 }
 // }}}
 
+// {{{ class UFBF_HasEmailRedirect
+class UFBF_HasEmailRedirect extends UFBF_Enum
+{
+    public function __construct($envfield, $formtext = '')
+    {
+        parent::__construct($envfield, $formtext, array(1, 2));
+    }
+
+    protected function buildUFC(UserFilterBuilder $ufb)
+    {
+        if ($this->val == 1) {
+            return new UFC_HasEmailRedirect();
+        } else if ($this->val == 2) {
+            return new PFC_Not(new UFC_HasEmailRedirect());
+        }
+    }
+}
+// }}}
+
 // {{{ class UFBF_Dead
 class UFBF_Dead extends UFBF_Enum
 {
@@ -1309,6 +1335,42 @@ class UFBF_EducationField extends UFBF_Mixed
 }
 // }}}
 
+// {{{ class UFBF_OriginCorps
+class UFBF_OriginCorps extends UFBF_Index
+{
+    protected $direnum = DirEnum::ORIGINCORPS;
+
+    protected function buildUFC(UserFilterBuilder $ufb)
+    {
+        return new UFC_Corps(null, $this->val, UFC_Corps::ORIGIN);
+    }
+}
+// }}}
+
+// {{{ class UFBF_CurrentCorps
+class UFBF_CurrentCorps extends UFBF_Index
+{
+    protected $direnum = DirEnum::CURRENTCORPS;
+
+    protected function buildUFC(UserFilterBuilder $ufb)
+    {
+        return new UFC_Corps(null, $this->val, UFC_Corps::CURRENT);
+    }
+}
+// }}}
+
+// {{{ class UFBF_CorpsRank
+class UFBF_CorpsRank extends UFBF_Index
+{
+    protected $direnum = DirEnum::CORPSRANKS;
+
+    protected function buildUFC(UserFilterBuilder $ufb)
+    {
+        return new UFC_Corps_Rank(null, $this->val);
+    }
+}
+// }}}
+
 // {{{ class UFBF_Comment
 class UFBF_Comment extends UFBF_Text
 {
index 7c87d4c..eb2cd4c 100644 (file)
@@ -31,6 +31,7 @@ abstract class Validate
     // {{{ properties
 
     public $user;
+    public $formal;
 
     public $stamp;
     public $unique;
@@ -56,6 +57,7 @@ abstract class Validate
     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;
@@ -221,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);
index 70d02bd..2cb486d 100644 (file)
@@ -66,15 +66,16 @@ class BrokenReq extends Validate
 
     protected function _mail_body($isok)
     {
+        $your = ($this->formal ? 'votre' : 'ta');
         if ($isok && !$this->m_reactive) {
             return "  Un email de contact vient d'être envoyé à {$this->m_user->fullName()}"
                 . " ({$this->m_user->promo()})  pour confirmer sa volonté de"
                 . " mettre à jour sa redirection Polytechnique.org !\n\n"
-                . "Merci de ta participation !\n";
+                . "Merci de $your participation !\n";
         } elseif ($isok) {
             return "  L'adresse de redirection {$this->m_email} de {$this->m_user->fullName()} ({$this->m_user->promo()}) "
                 ."vient d'être réactivée. Un email lui a été envoyé pour l'en informer.\n\n"
-                ."Merci de ta participation !\n";
+                ."Merci de $your participation !\n";
         } else {
             return "  Nous n'utiliserons pas cette adresse pour contacter {$this->m_user->fullName()} ({$this->m_user->promo()}).";
         }
index 67076a0..7dcbce0 100644 (file)
@@ -122,10 +122,11 @@ class EvtReq extends Validate
 
     protected function _mail_body($isok)
     {
+        $you_have = ($this->formal ? 'vous aviez' : 'tu avais');
         if ($isok) {
-            return "  L'annonce que tu avais proposée ({$this->titre}) vient d'être validée.";
+            return "  L'annonce que $you_have proposée ({$this->titre}) vient d'être validée.";
         } else {
-            return "  L'annonce que tu avais proposée ({$this->titre}) a été refusée.";
+            return "  L'annonce que $you_have proposée ({$this->titre}) a été refusée.";
         }
     }
 
index 9154526..6915606 100644 (file)
@@ -79,12 +79,14 @@ class MarkReq extends Validate
 
     protected function _mail_body($isok)
     {
+        $your1 = ($this->formal ? 'votre' : 'ton');
+        $your2 = ($this->formal ? 'votre' : 'ta');
         if ($isok) {
             return "  Un email de marketing vient d'être envoyé "
-                . ($this->perso ? 'en ton nom' : 'en notre nom')
+                . ($this->perso ? "en $your1 nom" : 'en notre nom')
                 . " à {$this->m_user->fullName()} ({$this->m_user->promo()}) "
                 . "pour l'encourager à s'inscrire !\n\n"
-                . "Merci de ta participation !\n";
+                . "Merci de $your2 participation !\n";
         } else {
             return "  Nous n'avons pas jugé bon d'envoyer d'email de marketing à "
                 . "{$this->m_user->fullName()} ({$this->m_user->promo()}).";
index 8361cc6..728bf38 100644 (file)
@@ -79,10 +79,11 @@ class NLReq extends Validate
 
     protected function _mail_body($isok)
     {
+        $you_have = ($this->formal ? 'vous aviez' : 'tu avais');
         if ($isok) {
-            return "  L'article que tu avais proposé (" . $this->art->title() . ") vient d'être validé.";
+            return "  L'article que $you_have proposé (" . $this->art->title() . ") vient d'être validé.";
         } else {
-            return "  L'article que tu avais proposé a été refusé.";
+            return "  L'article que $you_have proposé a été refusé.";
         }
     }
 
index 83e2689..afbead3 100644 (file)
@@ -154,9 +154,9 @@ Si le télépaiement n'est pas lié à un groupe ou supérieur à 51 euros, lais
     protected function _mail_body($isok)
     {
         if ($isok) {
-            return "  Le paiement que tu avais demandé pour {$this->titre} vient d'être créé.".($this->evt?" Il a bien été associé à la gestion de l'événement du groupe":"");
+            return "  Le paiement demandé pour {$this->titre} vient d'être créé.".($this->evt?" Il a bien été associé à la gestion de l'événement du groupe":"");
         } else {
-            return "  La demande que tu avais faite pour le paiement de {$this->intitule} a été refusée.";
+            return "  La demande faite pour le paiement de {$this->intitule} a été refusée.";
         }
     }
 
index e4f7d8e..e2ca7a1 100644 (file)
@@ -65,10 +65,11 @@ class SurveyReq extends Validate
 
     protected function _mail_body($isok)
     {
+        $you_have = ($this->formal ? 'vous aviez' : 'tu avais');
         if ($isok) {
-            return "  Le sondage que tu avais proposé vient d'être validé.";
+            return "  Le sondage que $you_have proposé vient d'être validé.";
         } else {
-            return "  Le sondage que tu avais proposé a été refusé.";
+            return "  Le sondage que $you_have proposé a été refusé.";
         }
     }
 
index 99086cc..57561c0 100644 (file)
@@ -145,7 +145,7 @@ class VCard extends PlVCard
 
         // Melix
         if (!is_null($user)) {
-            $alias = $user->emailAliases();
+            $alias = $user->emailAlias();
             if (!is_null($alias) && $pf->alias_pub == 'public') {
                 $entry->addMail(null, $alias);
             }
index f63a6e2..a8e62eb 100644 (file)
@@ -444,6 +444,7 @@ class AdminModule extends PLModule
         }
 
         // Account Form {{{
+        require_once 'emails.inc.php';
         $to_update = array();
         if (Post::has('disable_weak_access')) {
             $to_update['weak_password'] = null;
@@ -504,9 +505,10 @@ class AdminModule extends PLModule
             if (Post::t('comment') != $user->comment) {
                 $to_update['comment'] = Post::blank('comment') ? null : Post::t('comment');
             }
-            if (!$user->checkPerms(User::PERM_MAIL) && Post::t('email') != $user->forlifeEmail()) {
+            if (require_email_update($user, Post::t('email'))) {
                 $to_update['email'] = Post::t('email');
                 $listClient->change_user_email($user->forlifeEmail(), Post::t('email'));
+                update_alias_user($user->forlifeEmail(), Post::t('email'));
             }
         }
         if (!empty($to_update)) {
@@ -574,7 +576,6 @@ class AdminModule extends PLModule
         // }}}
 
         // Email forwards form {{{
-        require_once("emails.inc.php");
         $redirect = ($registered ? new Redirect($user) : null);
         if (Post::has('add_fwd')) {
             $email = Post::t('email');
index 57dd50d..de8af94 100644 (file)
@@ -307,7 +307,7 @@ class EmailModule extends PLModule
         $page->assign('googleapps', GoogleAppsAccount::account_status($user->id()));
 
         require_once 'emails.combobox.inc.php';
-        fill_email_combobox($page);
+        fill_email_combobox($page, array('job', 'stripped_directory'));
     }
 
     function handler_antispam($page, $filter_status = null, $redirection = null)
index e1bfb11..eec6fa2 100644 (file)
@@ -44,6 +44,7 @@ class ListsModule extends PLModule
             'lists/soptions'     => $this->make_hook('soptions',  AUTH_MDP),
             'lists/check'        => $this->make_hook('check',     AUTH_MDP),
             'admin/lists'        => $this->make_hook('admin_all', AUTH_MDP,    'admin'),
+            'admin/aliases'      => $this->make_hook('aaliases',  AUTH_MDP,    'admin')
         );
     }
 
@@ -886,6 +887,62 @@ class ListsModule extends PLModule
         $listes = $this->client->get_all_lists();
         $page->assign_by_ref('listes', $listes);
     }
+
+    function handler_aaliases($page, $alias = null)
+    {
+        global $globals;
+        require_once 'emails.inc.php';
+        $page->setTitle('Administration - Aliases');
+
+        if (Post::has('new_alias')) {
+            pl_redirect('admin/aliases/' . Post::t('new_alias') . '@' . $globals->mail->domain);
+        }
+
+        // If no alias, list them all.
+        if (is_null($alias)) {
+            $page->changeTpl('lists/admin_aliases.tpl');
+            $page->assign('aliases', array_merge(iterate_list_alias($globals->mail->domain), iterate_list_alias($globals->mail->domain2)));
+            return;
+        }
+
+        list($local_part, $domain) = explode('@', $alias);
+        if (!($globals->mail->domain == $domain || $globals->mail->domain2 == $domain)
+              || !preg_match("/^[a-zA-Z0-9\-\.]*$/", $local_part)) {
+            $page->trigErrorRedirect('Le nom de l\'alias est erroné.', $globals->asso('diminutif') . 'admin/aliases');
+        }
+
+        // Now we can perform the action.
+        if (Post::has('del_alias')) {
+            S::assert_xsrf_token();
+
+            delete_list_alias($local_part, $domain);
+            $page->trigSuccessRedirect($alias . ' supprimé.', 'admin/aliases');
+        }
+
+        if (Post::has('add_member')) {
+            S::assert_xsrf_token();
+
+            if (add_to_list_alias(Post::t('add_member'), $local_part, $domain)) {
+                $page->trigSuccess('Ajout réussit.');
+            } else {
+                $page->trigError('Ajout infructueux.');
+            }
+        }
+
+        if (Get::has('del_member')) {
+            S::assert_xsrf_token();
+
+            if (delete_from_list_alias(Get::t('del_member'), $local_part, $domain)) {
+                $page->trigSuccess('Suppression réussie.');
+            } else {
+                $page->trigError('Suppression infructueuse.');
+            }
+        }
+
+        $page->changeTpl('lists/admin_edit_alias.tpl');
+        $page->assign('members', list_alias_members($local_part, $domain));
+        $page->assign('alias', $alias);
+    }
 }
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
index b0092a7..9416557 100644 (file)
@@ -285,7 +285,7 @@ class ProfileModule extends PLModule
 
         // Determines and displays the virtual alias.
         if (!is_null($owner) && $profile->alias_pub == 'public') {
-            $page->assign('virtualalias', $owner->emailAliases());
+            $page->assign('virtualalias', $owner->emailAlias());
         }
 
         $page->assign_by_ref('profile', $profile);
@@ -443,7 +443,7 @@ class ProfileModule extends PLModule
         $page->assign('job', array());
         $page->assign('new', true);
         require_once "emails.combobox.inc.php";
-        fill_email_combobox($page);
+        fill_email_combobox($page, array('redirect', 'job', 'stripped_directory'));
     }
 
     /**
index b984472..2051f16 100644 (file)
@@ -717,7 +717,7 @@ class ProfilePageGeneral extends ProfilePage
         $page->assign('edu_fields', $res->fetchAllAssoc());
 
         require_once "emails.combobox.inc.php";
-        fill_email_combobox($page, $this->owner);
+        fill_email_combobox($page, array('source', 'redirect', 'job', 'directory'), $this->owner);
 
         $res = XDB::query("SELECT  nw.nwid AS type, nw.name
                              FROM  profile_networking_enum AS nw
index b343ade..37b8f3d 100644 (file)
@@ -68,7 +68,7 @@ class ProfileSettingJob implements ProfileSetting
         $jobs  = XDB::fetchAllAssoc('SELECT  j.id, j.jobid, je.name,
                                              j.description, j.email AS w_email,
                                              j.email_pub AS w_email_pub,
-                                             j.url AS w_url, j.pub
+                                             j.url AS w_url, j.pub, j.entry_year AS w_entry_year
                                        FROM  profile_job      AS j
                                   LEFT JOIN  profile_job_enum AS je ON (j.jobid = je.id)
                                       WHERE  j.pid = {?}
@@ -183,6 +183,11 @@ class ProfileSettingJob implements ProfileSetting
         }
         $job['w_phone'] = Phone::formatFormArray($job['w_phone'], $s, $maxPublicity);
 
+        if ($job['w_entry_year'] && strlen($job['w_entry_year']) != 4) {
+            $job['w_entry_year_error'] = true;
+            $success = false;
+        }
+
         unset($job['removed']);
         unset($job['new']);
     }
@@ -272,16 +277,16 @@ class ProfileSettingJob implements ProfileSetting
         foreach ($value as $id => &$job) {
             if (($job['pub'] != 'private' || $deletePrivate) && (isset($job['name']) && $job['name'])) {
                 if (isset($job['jobid']) && $job['jobid']) {
-                    XDB::execute('INSERT INTO  profile_job (pid, id, description, email,
+                    XDB::execute('INSERT INTO  profile_job (pid, id, description, email, entry_year,
                                                             url, pub, email_pub, jobid)
-                                       VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
-                                 $page->pid(), $id, $job['description'], $job['w_email'],
+                                       VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
+                                 $page->pid(), $id, $job['description'], $job['w_email'], $job['w_entry_year'],
                                  $job['w_url'], $job['pub'], $job['w_email_pub'], $job['jobid']);
                 } else {
-                    XDB::execute('INSERT INTO  profile_job (pid, id, description, email,
+                    XDB::execute('INSERT INTO  profile_job (pid, id, description, email, entry_year,
                                                             url, pub, email_pub)
-                                       VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?})',
-                                 $page->pid(), $id, $job['description'], $job['w_email'],
+                                       VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
+                                 $page->pid(), $id, $job['description'], $job['w_email'], $job['w_entry_year'],
                                  $job['w_url'], $job['pub'], $job['w_email_pub']);
                     $request = new EntrReq(S::user(), $page->profile, $id, $job['name'], $job['hq_acronym'], $job['hq_url'],
                                            $job['hq_email'], $job['hq_fixed'], $job['hq_fax'], $job['hq_address']);
@@ -433,7 +438,7 @@ class ProfilePageJobs extends ProfilePage
     public function _prepare(PlPage $page, $id)
     {
         require_once 'emails.combobox.inc.php';
-        fill_email_combobox($page, $this->owner);
+        fill_email_combobox($page, array('redirect', 'job', 'stripped_directory'), $this->owner);
 
         if (!S::user()->isMe($this->owner)) {
             $res = XDB::iterator('SELECT  id, name
index cd80aeb..b9ae916 100644 (file)
@@ -156,6 +156,18 @@ class SearchModule extends PLModule
         $networks[0] = '-';
         ksort($networks);
         $page->assign('networking_types', $networks);
+        $origin_corps_list = DirEnum::getOptions(DirEnum::CURRENTCORPS);
+        $current_corps_list = DirEnum::getOptions(DirEnum::ORIGINCORPS);
+        $corps_rank_list = DirEnum::getOptions(DirEnum::CORPSRANKS);
+        $origin_corps_list[0] = '-';
+        $current_corps_list[0] = '-';
+        $corps_rank_list[0] = '-';
+        ksort($origin_corps_list);
+        ksort($current_corps_list);
+        ksort($corps_rank_list);
+        $page->assign('origin_corps_list', $origin_corps_list);
+        $page->assign('current_corps_list', $current_corps_list);
+        $page->assign('corps_rank_list', $corps_rank_list);
 
         if (!Env::has('rechercher') && $model != 'geoloc') {
             $this->form_prepare();
index 0e7f3a1..33b5153 100644 (file)
@@ -24,22 +24,14 @@ class UrlShortenerModule extends PLModule
     function handlers()
     {
         return array(
-            'url'       => $this->make_hook('url',       AUTH_COOKIE),
+            'url'       => $this->make_hook('url',       AUTH_PUBLIC),
             'admin/url' => $this->make_hook('admin_url', AUTH_MDP, 'admin')
         );
     }
 
     function handler_url($page, $alias)
     {
-        $url = XDB::fetchOneCell('SELECT  url
-                                    FROM  url_shortener
-                                   WHERE  alias = {?}',
-                                 $alias);
-
-        if (is_null($url)) {
-            return PL_NOT_FOUND;
-        }
-        http_redirect($url);
+        http_redirect(Platal::globals()->core->base_url_shortener . $alias);
     }
 
     function handler_admin_url($page)
@@ -54,17 +46,21 @@ class UrlShortenerModule extends PLModule
         $alias = Post::t('alias');
 
         $url_regex = '{^(https?|ftp)://[a-zA-Z0-9._%#+/?=&~-]+$}i';
-        if (!preg_match($url_regex, $url)) {
+        if (strlen($url) > 255 || !preg_match($url_regex, $url)) {
             $page->trigError("L'url donnée n'est pas valide.");
             return;
         }
         $page->assign('url', $url);
 
         if ($alias != '') {
-            if (!preg_match('/^[a-zA-Z0-9\-]{6}$/i', $alias)) {
+            if (!preg_match('/^[a-zA-Z0-9\-\/]+$/i', $alias)) {
                 $page->trigError("L'alias proposé n'est pas valide.");
                 return;
             }
+            if (preg_match('/^a\//i', $alias)) {
+                $page->trigError("L'alias commence par le préfixe 'a/' qui est réservé et donc non autorisé.");
+                return;
+            }
             $page->assign('alias', $alias);
 
             $used = XDB::fetchOneCell('SELECT  COUNT(*)
@@ -77,7 +73,7 @@ class UrlShortenerModule extends PLModule
             }
         } else {
             do {
-                $alias = rand_token(6);
+                $alias = 'a/' . rand_token(6);
                 $used = XDB::fetchOneCell('SELECT  COUNT(*)
                                              FROM  url_shortener
                                             WHERE  alias = {?}',
@@ -89,7 +85,7 @@ class UrlShortenerModule extends PLModule
         XDB::execute('INSERT INTO  url_shortener (url, alias)
                            VALUES  ({?}, {?})',
                      $url, $alias);
-        $page->trigSuccess("L'url « " . $url . ' » est maintenant accessible depuis « ' . Platal::globals()->baseurl . '/url/' . $alias . ' ».');
+        $page->trigSuccess("L'url « " . $url . ' » est maintenant accessible depuis « http://u.w4x.org/' . $alias . ' ».');
     }
 }
 
index 04a8a05..12c961c 100644 (file)
@@ -402,6 +402,12 @@ Email envoyé à " . Post::t('login'));
                        Post::t('full_name'), Post::t('directory_name'), Post::t('display_name'),
                        (Post::t('sex') == 'male') ? 'male' : 'female', Post::t('email'), $user->id());
             if (XDB::affectedRows()) {
+                require_once 'emails.inc.php';
+                if (require_email_update($user, Post::t('email'))) {
+                    $listClient = new MMList(S::user());
+                    $listClient->change_user_email($user->forlifeEmail(), Post::t('email'));
+                    update_alias_user($user->forlifeEmail(), Post::t('email'));
+                }
                 $user = User::getWithUID($user->id());
                 S::set('user', $user);
                 $page->trigSuccess('Données mises à jour.');
index 90a905f..fcff1ba 100644 (file)
@@ -993,6 +993,7 @@ class XnetGrpModule extends PLModule
         $mmlist = new MMList(S::user(), $globals->asso('mail_domain'));
 
         if (Post::has('change')) {
+            require_once 'emails.inc.php';
             S::assert_xsrf_token();
 
             // Convert user status to X
@@ -1020,6 +1021,11 @@ class XnetGrpModule extends PLModule
                              WHERE  uid = {?}',
                            Post::t('email'), $user->id());
             }
+            if (require_email_update($user, Post::t('email'))) {
+                $listClient = new MMList(S::user());
+                $listClient->change_user_email($user->forlifeEmail(), Post::t('email'));
+                update_alias_user($user->forlifeEmail(), Post::t('email'));
+            }
             if (XDB::affectedRows()) {
                 $page->trigSuccess('Données de l\'utilisateur mises à jour.');
             }
@@ -1247,13 +1253,13 @@ class XnetGrpModule extends PLModule
                 if (!empty($art['contact_html'])) {
                     $fulltext .= "\n\n'''Contacts :'''\\\\\n" . $art['contact_html'];
                 }
-                $post = null;/*
+                $post = null;
                 if ($globals->asso('forum')) {
                     require_once 'banana/forum.inc.php';
                     $banana = new ForumsBanana(S::user());
                     $post = $banana->post($globals->asso('forum'), null,
                                           $art['titre'], MiniWiki::wikiToText($fulltext, false, 0, 80));
-                }*/
+                }
                 XDB::query('INSERT INTO  group_announces (uid, asso_id, create_date, titre, texte, contacts,
                                                           expiration, promo_min, promo_max, flags, post_id)
                                  VALUES  ({?}, {?}, NOW(), {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
index a502f02..d018754 100644 (file)
@@ -70,7 +70,7 @@ class XnetListsModule extends ListsModule
         return $globals->asso('mail_domain');
     }
 
-    function handler_lists($page)
+    function handler_lists($page, $order_by = null, $order = null)
     {
         global $globals;
         require_once 'emails.inc.php';
@@ -102,9 +102,44 @@ class XnetListsModule extends ListsModule
         }
 
         $listes = $this->client->get_lists();
+        // Default ordering is by ascending names.
+        if (is_null($order_by) || is_null($order)
+            || !in_array($order_by, array('list', 'desc', 'nbsub'))
+            || !in_array($order, array('asc', 'desc'))) {
+            $order_by = 'list';
+            $order = 'asc';
+        }
+
+        $compare = function ($a, $b) use ($order_by, $order)
+        {
+            switch ($order_by) {
+              case 'desc':
+                $a[$order_by] = replace_accent($a[$order_by]);
+                $b[$order_by] = replace_accent($b[$order_by]);
+              case 'list':
+                $res = strcasecmp($a[$order_by], $b[$order_by]);
+                break;
+              case 'nbsub':
+                $res = $a[$order_by] - $b[$order_by];
+                break;
+              default:
+                $res = 0;
+            }
+
+            if ($order == 'asc') {
+                return $res;
+            }
+            return $res * -1;
+        };
+        usort($listes, $compare);
         $page->assign('listes', $listes);
+        $page->assign('order_by', $order_by);
+        $page->assign('order', $order);
         $page->assign('aliases', iterate_list_alias($globals->asso('mail_domain')));
         $page->assign('may_update', may_update());
+        if (S::suid()) {
+            $page->trigWarning("Attention&nbsp;: l'affichage des listes de diffusion ne tient pas compte de l'option « Voir le site comme&hellip; ».");
+        }
 
         if (count($listes) > 0 && !$globals->asso('has_ml')) {
             XDB::execute("UPDATE  groups
index e491163..fbb6ad3 100644 (file)
@@ -51,6 +51,8 @@
     <td>
       <a href="admin/lists">MLs</a>
       &nbsp;&nbsp;|&nbsp;&nbsp;
+      <a href="admin/aliases">aliases</a>
+      &nbsp;&nbsp;|&nbsp;&nbsp;
       <a href="admin/mx/broken">MX défaillants</a>
       &nbsp;&nbsp;|&nbsp;&nbsp;
       <a href="admin/emails/lost">Perdus de vue</a>
index 65f5fb2..a93804a 100644 (file)
         {/if}
       </td>
     </tr>
-  </table><br />
-</form>
+  </table>
+</form><br />
 
 <table class="bicol" style="text-align: center">
   <tr>
index 021a47f..74e84b3 100644 (file)
   {if $name eq "email"}<td></td>{/if}
   <td>
     {if $name neq "email"}<div style="float: left">{/if}
+    {if $emails_count neq 0}
     <select name="{$name}" id="{$combobox}">
-      {if $email_type eq "directory"}
-      <optgroup label="Email annuaire AX">
-        <option value="{$email_directory}" {if
-        $val eq $email_directory}selected="selected"{/if}>{$email_directory}</option>
-      </optgroup>
-      {/if}
-      {if $name eq "email_directory"}
-      <optgroup label="Emails polytechniciens">
-        {foreach from=$list_email_X item=email}
-        <option value="{$email.email}" {if $val eq $email.email}selected="selected"{/if}>{$email.email}</option>
-        {/foreach}
-      </optgroup>
-      {/if}
-      {if (($name neq "email") && ($list_email_redir|@count neq 0))}
-      <optgroup label="Redirections">
-        {foreach from=$list_email_redir item=email}
+      {foreach from=$email_lists item=email_list key=key}
+      {if $email_list|@count}
+      <optgroup label="{$key}">
+        {foreach from=$email_list item=email}
         <option value="{$email}" {if $val eq $email}selected="selected"{/if}>{$email}</option>
         {/foreach}
       </optgroup>
       {/if}
-      {if $list_email_pro|@count neq 0}
-      <optgroup label="Emails professionels">
-        {foreach from=$list_email_pro item=email}
-        <option value="{$email}" {if
-                $val eq $email}selected="selected"{/if}>{$email}</option>
-        {/foreach}
-      </optgroup>
-      {/if}
+      {/foreach}
       <optgroup label="Autres choix">
         <option value="new@example.org" {if ($val eq '' && !$error && $name eq 'email') || $error}selected="selected"{/if}>Nouvelle adresse email</option>
-        <option value="" {if $val eq '' && !$error && $name neq 'email'}selected="selected"{/if}>{if $name neq "email"}Ne pas mettre d'adresse email{else}&nbsp;{/if}</option>
+        {if $name neq "email"}<option value="" {if $val eq '' && !$error}selected="selected"{/if}>Ne pas mettre d'adresse email</option>{/if}
       </optgroup>
     </select>
+    {else}
+    <input type="text" maxlength="255" {if $error}class="error" value="{$val}"{/if} name="{$name}"/>
+    {/if}
     {if $name neq "email"}
     </div>
     <div style="float: right" class="flags">
diff --git a/templates/lists/admin_aliases.tpl b/templates/lists/admin_aliases.tpl
new file mode 100644 (file)
index 0000000..8e9dfd6
--- /dev/null
@@ -0,0 +1,50 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<h1>Aliases</h1>
+
+<table cellspacing="0" cellpadding="0" class="tinybicol">
+  <tr>
+    <th>Aliases</th>
+  </tr>
+  {if $aliases|@count}
+  {foreach from=$aliases item=alias}
+  <tr>
+    <td><a href="admin/aliases/{$alias}">{$alias}</a></td>
+  </tr>
+  {/foreach}
+  {else}
+  <tr>
+    <td>Aucun alias</td>
+  </tr>
+  {/if}
+</table>
+
+<form method="post" action="admin/aliases">
+  {xsrf_token_field}
+  <p class="center">
+    <input type="text" name="new_alias" />
+    <input type="submit" value="Créer l'alias" />
+  </p>
+</form>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
diff --git a/templates/lists/admin_edit_alias.tpl b/templates/lists/admin_edit_alias.tpl
new file mode 100644 (file)
index 0000000..1ec1f16
--- /dev/null
@@ -0,0 +1,92 @@
+{**************************************************************************}
+{*                                                                        *}
+{*  Copyright (C) 2003-2011 Polytechnique.org                             *}
+{*  http://opensource.polytechnique.org/                                  *}
+{*                                                                        *}
+{*  This program is free software; you can redistribute it and/or modify  *}
+{*  it under the terms of the GNU General Public License as published by  *}
+{*  the Free Software Foundation; either version 2 of the License, or     *}
+{*  (at your option) any later version.                                   *}
+{*                                                                        *}
+{*  This program is distributed in the hope that it will be useful,       *}
+{*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *}
+{*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *}
+{*  GNU General Public License for more details.                          *}
+{*                                                                        *}
+{*  You should have received a copy of the GNU General Public License     *}
+{*  along with this program; if not, write to the Free Software           *}
+{*  Foundation, Inc.,                                                     *}
+{*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA               *}
+{*                                                                        *}
+{**************************************************************************}
+
+<p>[<a href="admin/aliases">Retour à la liste des aliases</a>]</p>
+
+<h1>Membres de {$alias}</h1>
+
+<table class="tinybicol">
+  {if $members.users|@count}
+  {foreach from=$members.users item=member}
+  <tr>
+    <td>
+      {if $member->hasProfile()}
+      <a href="https://www.polytechnique.org/profile/{$member->hruid}" class="popup2">{$member->fullName()}</a>
+      {else}
+      {$member->fullName()}
+      {/if}
+    </td>
+    <td class="right">{$member->promo()}</td>
+    <td class="center">
+      <a href="admin/aliases/{$alias}?del_member={$member->id()}&amp;token={xsrf_token}">
+      {icon name=delete title="retirer membre"}
+      </a>
+    </td>
+  </tr>
+  {/foreach}
+  {/if}
+  {if $members.nonusers|@count}
+  {foreach from=$members.nonusers item=member}
+  <tr>
+    <td>{$member}</td>
+    <td></td>
+    <td class="center">
+      <a href="admin/aliases/{$alias}?del_member={$member}&amp;token={xsrf_token}">
+      {icon name=delete title="retirer membre"}
+      </a>
+    </td>
+  </tr>
+  {/foreach}
+  {/if}
+  {if $members.users|@count eq 0 && $members.nonusers|@count eq 0}
+  <tr>
+    <td colspan="3">
+      <em>aucun membre&hellip;</em>
+    </td>
+  </tr>
+  {/if}
+  <tr>
+    <th colspan="3">Ajouter</th>
+  </tr>
+  <tr>
+    <td colspan="3" class="center">
+      <form method="post" action="admin/aliases/{$alias}">
+        {xsrf_token_field}
+        <div>
+        <input type="text" name="add_member" />
+        &nbsp;
+        <input type="submit" value="ajouter" />
+        </div>
+      </form>
+    </td>
+  </tr>
+</table>
+
+
+<form method="post" action="admin/aliases/{$alias}">
+  {xsrf_token_field}
+  <p class="center">
+    <input type="submit" name="del_alias" value="Supprimer l'alias" onclick="return confirm('ES tu sûr de vouloir supprimer cet alias.')" />
+  </p>
+</form>
+
+{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 2b4efc3..8150c41 100644 (file)
     <tr class="pair" {if $hiddenjob}style="display: none"{/if}>
       <td class="titre">Page&nbsp;perso</td>
       <td>
-          <input type="text" size="35" maxlength="255" {if t($job.w_rul)}class="error"{/if}
+          <input type="text" size="35" maxlength="255" {if t($job.w_url_error)}class="error"{/if}
                  name="{$jobpref}[w_url]" value="{$job.w_url}" />
       </td>
     </tr>
+    <tr class="pair" {if $hiddenjob}style="display: none"{/if}>
+      <td class="titre">Année&nbsp;d'entrée</td>
+      <td>
+          <input type="text" size="4" maxlength="4" {if t($job.w_entry_year_error)}class="error"{/if}
+                 name="{$jobpref}[w_entry_year]" value="{$job.w_entry_year}" />
+          <small>(avec 4 chiffres, par exemple 1983)</small>
+      </td>
+    </tr>
     <tr id="{$jobid}_w_address" class="pair" {if $hiddenjob || $hiddenaddr}style="display: none"{/if}>
       <td colspan="2">
         <div style="float: left">
index 48ac0b0..ee04684 100644 (file)
@@ -345,6 +345,27 @@ function cleanForm(f) {
       </td>
     </tr>
     <tr>
+      <td>A une redirection active</td>
+      <td>
+        <table>
+          <tr>
+            <td style="width:100px">
+              <input type="radio" name="has_email_redirect" value="0" {if !$smarty.request.has_email_redirect}checked="checked"{/if}
+                id="has_email_redirect0" /><label for="has_email_redirect0">indifférent</label>
+            </td>
+            <td style="width:100px">
+              <input type="radio" name="has_email_redirect" value="1" {if $smarty.request.has_email_redirect eq 1}checked="checked"{/if}
+                id="has_email_redirect1" /><label for="has_email_redirect1">oui</label>
+            </td>
+            <td style="width:100px">
+              <input type="radio" name="has_email_redirect" value="2" {if $smarty.request.has_email_redirect eq 2}checked="checked"{/if}
+                id="has_email_redirect2" /><label for="has_email_redirect2">non</label>
+            </td>
+          </tr>
+        </table>
+      </td>
+    </tr>
+    <tr>
       <td>En vie</td>
       <td>
         <table>
@@ -495,6 +516,36 @@ function cleanForm(f) {
       </td>
     </tr>
     <tr>
+      <td>Corps d'origine</td>
+      <td>
+        <select name="origin_corps">
+        {foreach from=$origin_corps_list key=id item=corps}
+          <option value="{$id}" {if $smarty.request.origin_corps eq $id}selected="selected"{/if}>{$corps}</option>
+        {/foreach}
+        </select>
+      </td>
+    </tr>
+    <tr>
+      <td>Corps actuel</td>
+      <td>
+        <select name="current_corps">
+        {foreach from=$current_corps_list key=id item=corps}
+          <option value="{$id}" {if $smarty.request.current_corps eq $id}selected="selected"{/if}>{$corps}</option>
+        {/foreach}
+        </select>
+      </td>
+    </tr>
+    <tr>
+      <td>Grade</td>
+      <td>
+        <select name="corps_rank">
+        {foreach from=$corps_rank_list key=id item=corps}
+          <option value="{$id}" {if $smarty.request.corps_rank eq $id}selected="selected"{/if}>{$corps}</option>
+        {/foreach}
+        </select>
+      </td>
+    </tr>
+    <tr>
       <td>Commentaire contient</td>
       <td><input type="text" name="free" size="32" value="{$smarty.request.free}" /></td>
     </tr>
index e9d1dea..ec11de8 100644 (file)
       <td><input type="text" name="url" value="{if t($url)}{$url}{/if}" /></td>
     </tr>
     <tr>
-      <th>Alias (6 caractères, optionnel)&nbsp;:</th>
+      <th>Alias (optionnel)&nbsp;:</th>
       <td>
-        <input type="text" name="alias" size="6" maxlength="6" value="{if t($alias)}{$alias}{/if}" />
-        <small>(peut contenir lettres, chiffres et tirets)</small>
+        <input type="text" name="alias" size="42" maxlength="255" value="{if t($alias)}{$alias}{/if}" />
+        <small>(peut contenir lettres, chiffres, tirets et /)</small>
       </td>
     </tr>
   </table>
   <p class="center"><input type="submit" value="Raccourcir" /></p>
 </form>
 
+<h3>Explications</h3>
+<p>
+  L'alias peut être demandé. Dans ce cas, sa longueur maximal autorisée est
+  de 255 lettres, chiffres, tirets ou /. Ce dernier permet de définir des
+  domaines pour regrouper des raccourcis liés. Par exemple, « nl-04-04/ »
+  pourrait être utilisé comme base pour les urls de la lettre mensuelle d'avril
+  2004.<br />
+  Si aucun alias n'est fournit, le site en génère un de 6 caractères aléatoires
+  accolés à la la base «&nbsp;a/&nbsp;» (par exemple&nbsp;: « a/azerty ». Ce
+  préfixe «&nbsp;a/&nbsp;» et réservé à cet usage et ne peut être utilisé pour
+  former une url choisie.
+</p>
+
 {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 1818280..44431ad 100644 (file)
@@ -96,7 +96,7 @@ masculin ou féminin, par son prénom, ou son nom.
       <td>
         <label><input type="checkbox" name="ml[{$l.list}]" value="1" {if $smarty.request.ml[$l.list]}checked="checked"{/if} />
         {$l.addr}</label>
-        <a href="{$platal->ns}lists/admin/{$l.list}" class="popup">(voir composition)</a>
+        <a href="{$platal->ns}lists/members/{$l.list}" class="popup">(voir composition)</a>
       </td>
     </tr>
     {/foreach}
index 3bae8b3..f672c20 100644 (file)
@@ -52,11 +52,44 @@ croix verte te permet de t'inscrire, après accord des responsables si l'inscrip
 
 <table cellpadding="0" cellspacing="0" class='large'>
   <tr>
-    <th colspan="2">Liste</th>
-    <th>Description</th>
+    <th colspan="2">
+      <a href="{$platal->ns}lists/list/{if $order_by eq 'list' && $order eq 'asc'}desc{else}asc{/if}">
+        {if $order_by eq 'list'}
+        {if $order eq 'desc'}
+          <img src="{$platal->baseurl}images/up.png" alt="" title="Tri décroissant" />
+        {else}
+          <img src="{$platal->baseurl}images/dn.png" alt="" title="Tri croissant" />
+        {/if}
+        {/if}
+        Liste
+      </a>
+    </th>
+    <th>
+      <a href="{$platal->ns}lists/desc/{if $order_by eq 'desc' && $order eq 'asc'}desc{else}asc{/if}">
+        {if $order_by eq 'desc'}
+        {if $order eq 'desc'}
+          <img src="{$platal->baseurl}images/up.png" alt="" title="Tri décroissant" />
+        {else}
+          <img src="{$platal->baseurl}images/dn.png" alt="" title="Tri croissant" />
+        {/if}
+        {/if}
+        Description
+      </a>
+    </th>
     <th>Diffusion</th>
     <th>Inscription</th>
-    <th>Nb</th>
+    <th>
+      <a href="{$platal->ns}lists/nbsub/{if $order_by eq 'nbsub' && $order eq 'asc'}desc{else}asc{/if}">
+        {if $order_by eq 'nbsub'}
+        {if $order eq 'desc'}
+          <img src="{$platal->baseurl}images/up.png" alt="" title="Tri décroissant" />
+        {else}
+          <img src="{$platal->baseurl}images/dn.png" alt="" title="Tri croissant" />
+        {/if}
+        {/if}
+        Nb
+      </a>
+    </th>
     <th>&nbsp;</th>
   </tr>
   {foreach from=$listes item=l}
diff --git a/upgrade/1.1.1/01_languages.sql b/upgrade/1.1.1/01_languages.sql
new file mode 100644 (file)
index 0000000..b6529a7
--- /dev/null
@@ -0,0 +1,8 @@
+-- Updates serbian iso code.
+UPDATE  profile_langskills
+   SET  lid = 'srp'
+ WHERE  lid = 'scc';
+DELETE FROM  profile_langskill_enum
+      WHERE  iso_639_2b = 'scc';
+
+-- vim:set syntax=mysql:
diff --git a/upgrade/1.1.1/02_emails.sql b/upgrade/1.1.1/02_emails.sql
new file mode 100644 (file)
index 0000000..6903518
--- /dev/null
@@ -0,0 +1,10 @@
+    DELETE  e2
+      FROM  email_virtual AS e1
+INNER JOIN  email_virtual AS e2
+     WHERE  e1.email = e2.email AND e1.domain = e2.domain AND e1.redirect != e2.redirect
+            AND e1.redirect = REPLACE(e2.redirect, '@m4x.org', '@polytechnique.org');
+UPDATE  email_virtual
+   SET  redirect = REPLACE(redirect, '@m4x.org', '@polytechnique.org')
+ WHERE  redirect LIKE '%@m4x.org';
+
+-- vim:set syntax=mysql:
diff --git a/upgrade/1.1.1/03_url.sql b/upgrade/1.1.1/03_url.sql
new file mode 100644 (file)
index 0000000..14810a1
--- /dev/null
@@ -0,0 +1,15 @@
+DROP TABLE IF EXISTS tmp_url_shortener;
+CREATE TEMPORARY TABLE tmp_url_shortener LIKE url_shortener;
+INSERT INTO tmp_url_shortener SELECT * FROM url_shortener;
+DROP TABLE url_shortener;
+CREATE TABLE url_shortener (
+  alias VARCHAR(255) NOT NULL DEFAULT '',
+  url TEXT NOT NULL,
+  PRIMARY KEY (alias)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+INSERT INTO  url_shortener (alias, url)
+     SELECT  alias, url
+       FROM  tmp_url_shortener;
+DROP TABLE IF EXISTS tmp_url_shortener;
+
+-- vim:set syntax=mysql:
diff --git a/upgrade/1.1.1/04_jobs.sql b/upgrade/1.1.1/04_jobs.sql
new file mode 100644 (file)
index 0000000..4d0187e
--- /dev/null
@@ -0,0 +1,3 @@
+ALTER TABLE profile_job ADD COLUMN entry_year CHAR(4) DEFAULT NULL;
+
+-- vim:set syntax=mysql:
diff --git a/upgrade/1.1.1/README b/upgrade/1.1.1/README
new file mode 100644 (file)
index 0000000..936e205
--- /dev/null
@@ -0,0 +1,3 @@
+The following variable should be set:
+[Core]
+baseurl_shortener = "http://u.w4x.org/"
diff --git a/upgrade/1.1.1/connect.db.inc.php b/upgrade/1.1.1/connect.db.inc.php
new file mode 120000 (symlink)
index 0000000..442fab7
--- /dev/null
@@ -0,0 +1 @@
+../../bin/connect.db.inc.php
\ No newline at end of file
diff --git a/upgrade/1.1.1/update.sh b/upgrade/1.1.1/update.sh
new file mode 100755 (executable)
index 0000000..9230e34
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+. ../inc/pervasive.sh
+
+###########################################################
+[ "$DATABASE" != "x4dat" ] || die "Cannot target x4dat"
+
+confirm "* Running database upgrade scripts"
+mysql_run_directory .