Merge commit 'origin/master' into fusionax
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Mon, 12 Jan 2009 10:55:01 +0000 (11:55 +0100)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Mon, 12 Jan 2009 10:55:01 +0000 (11:55 +0100)
Conflicts:

include/applis.func.inc.php

Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
82 files changed:
1  2 
bin/cron/checkdb.php
bin/cron/clean.php
classes/user.php
htdocs/css/default.css
htdocs/css/keynote.css
htdocs/css/openweb.css
htdocs/javascript/profile.js
htdocs/xorg.php
include/education.func.inc.php
include/emails.combobox.inc.php
include/name.func.inc.php
include/notifs.inc.php
include/profil.func.inc.php
include/user.func.inc.php
include/userset.inc.php
include/validations.inc.php
include/validations/entreprises.inc.php
include/validations/orange.inc.php
modules/admin.php
modules/email.php
modules/events.php
modules/fusionax.php
modules/geoloc.php
modules/payment/money/paypal.inc.php
modules/profile.php
modules/profile/addresses.inc.php
modules/profile/general.inc.php
modules/profile/jobs.inc.php
modules/profile/mentor.inc.php
modules/profile/page.inc.php
modules/search.php
modules/search/classes.inc.php
modules/search/search.inc.php
plugins/function.display_address.php
plugins/function.display_phones.php
plugins/function.select_nat.php
templates/admin/index.tpl
templates/core/vcard.tpl
templates/emails/redirect.tpl
templates/events/index.tpl
templates/fusionax/deceased.tpl
templates/fusionax/ids.tpl
templates/fusionax/idsMissingInAx.tpl
templates/fusionax/idsMissingInXorg.tpl
templates/fusionax/idswrongInXorg.tpl
templates/fusionax/import.tpl
templates/fusionax/index.tpl
templates/fusionax/listFusion.tpl
templates/fusionax/promo.tpl
templates/fusionax/view.tpl
templates/gadgets/ig-minifiche.tpl
templates/include/emails.combobox.tpl
templates/include/emploi.tpl
templates/include/field.promo.tpl
templates/include/form.valid.edit-entreprises.tpl
templates/include/form.valid.entreprises.tpl
templates/include/minifiche.tpl
templates/include/plview.referent.tpl
templates/include/plview.trombi.tpl
templates/include/trombi.tpl
templates/marketing/private.tpl
templates/profile/adresses.address.tpl
templates/profile/education.js.tpl
templates/profile/fiche_referent.tpl
templates/profile/general.buildnames.tpl
templates/profile/general.edu.tpl
templates/profile/general.networking.tpl
templates/profile/general.searchname.tpl
templates/profile/general.tpl
templates/profile/jobs.job.tpl
templates/profile/jobs.secteur.tpl
templates/profile/jobs.soussecteur.tpl
templates/profile/jobs.tpl
templates/profile/name_info.tpl
templates/profile/orange.tpl
templates/profile/phone.tpl
templates/profile/profile.tpl
templates/search/adv.form.tpl
templates/search/adv.grade.form.tpl
templates/survey/index.tpl
templates/survey/show_root.tpl
upgrade/0.9.14/connect.db.inc.php

diff --combined bin/cron/checkdb.php
@@@ -1,7 -1,7 +1,7 @@@
  #!/usr/bin/php5 -q
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -73,16 -73,17 +73,16 @@@ if ( PEAR::isError($opts) ) 
  
  /* Validite des flags de transmission */
  check("SELECT  u.user_id, nom, prenom, promo,
 -               profile_mobile_pub, emails_alias_pub, profile_web_pub, profile_freetext_pub, profile_medals_pub
 +               emails_alias_pub, profile_freetext_pub, profile_medals_pub
           FROM  auth_user_md5 AS u
     INNER JOIN  auth_user_quick AS q USING(user_id)
 -        WHERE  (profile_mobile_pub != 'private' AND profile_mobile_pub != 'ax' AND profile_mobile_pub != 'public')
 -           OR  (emails_alias_pub != 'private' AND emails_alias_pub != 'public')
 -           OR  (profile_web_pub != 'private' AND profile_web_pub != 'public')
 +        WHERE  (emails_alias_pub != 'private' AND emails_alias_pub != 'public')
             OR  (profile_freetext_pub != 'private' AND profile_freetext_pub != 'public')
             OR  (profile_medals_pub != 'private' AND profile_medals_pub != 'public')",
      "Utilisateur n'ayant pas de flag de publicite pour leurs donnees de profil");
  check("select uid from adresses where pub != 'private' and pub !='ax' and pub != 'public'", "Utiliseur n'ayant pas de flag de publicite pour une adresse");
 -check("select uid from tels where tel_pub != 'private' and tel_pub !='ax' and tel_pub != 'public'", "Utiliseur n'ayant pas de flag de publicite pour un numero de telephone");
 +check("select uid from profile_phones where pub != 'private' and pub != 'ax' and pub != 'public'", "Utiliseur n'ayant pas de flag de publicite pour un numero de téléphone");
 +check("select uid from profile_networking where pub != 'private' and pub != 'public'", "Utiliseur n'ayant pas de flag de publicité pour une adresse de networking");
  
  /* validite des hruid */
  check("SELECT user_id, nom, prenom, promo FROM auth_user_md5 WHERE hruid IS NULL OR hruid = ''",
@@@ -94,9 -95,9 +94,9 @@@ check("SELECT a.
          LEFT JOIN auth_user_md5 AS u ON u.user_id=a.id
          WHERE (a.type='alias' OR a.type='a_vie') AND u.prenom is null");
  
 -/* validite de applis_ins */
 -check("select a.* from applis_ins as a left join auth_user_md5 as u on u.user_id=a.uid where u.prenom is null");
 -check("select a.* from applis_ins as a left join applis_def as ad on ad.id=a.aid where ad.text is null");
 +/* validite de profile_education */
 +check("select a.* from profile_education as a left join auth_user_md5 as u on u.user_id=a.uid where u.prenom is null");
 +check("select a.* from profile_education as a left join profile_education_enum as ad on ad.id=a.eduid where ad.name is null");
  
  /* validite de binet_users */
  check("select b.* from binets_ins as b left join auth_user_md5 as u on u.user_id=b.user_id where u.prenom is null");
@@@ -122,16 -123,6 +122,16 @@@ check("select g.* from groupesx_ins as 
  /* validite de photo */
  check("select p.* from photo as p left join auth_user_md5 as u on u.user_id=p.uid where u.prenom is null");
  
 +/* validite des formats téléphoniques */
 +check("SELECT DISTINCT g.phoneprf from geoloc_pays AS g
 +          WHERE EXISTS (SELECT h.phoneprf
 +                          FROM geoloc_pays AS h
 +                         WHERE h.phoneprf = g.phoneprf AND h.phoneformat != (SELECT i.phoneformat
 +                                                                               FROM geoloc_pays AS i
 +                                                                              WHERE i.phoneprf = g.phoneprf
 +                                                                              LIMIT 1))",
 +      "Préfixes téléphoniques qui ont des formats de numéros de téléphones différents selon les pays");
 +
  /* validite des champ pays et region */
  check("SELECT a.uid, a.country FROM adresses AS a LEFT JOIN geoloc_pays AS gp ON a.country = gp.a2 WHERE gp.pays IS NULL","donne la liste des pays dans les profils qui n'ont pas d'entree correspondante dans geoloc_pays");
  /* les régions ne sont valides que dans les adresses pros */
@@@ -188,25 -179,7 +188,25 @@@ check("SELECT  matricule,nom,prenom,mat
          WHERE  matricule_ax != '0'
          GROUP BY  matricule_ax
          having  c > 1", "à chaque personne de l'annuaire de l'AX (identification_ax) doit correspondre AU PLUS UNE personne de notre annuaire (auth_user_md5) -> si ce n'est pas le cas il faut regarder en manuel ce qui ne va pas !");
 -
 +        
 +/* each alumni has one and only one display name by default and one and only one name when we talk to him directly */
 +check("SELECT u.`user_id`, u.`nom`, u.`prenom`, COUNT(n.`display`) AS c
 +        FROM `auth_user_md5` AS u
 +        LEFT JOIN `profile_names_display` AS n ON(u.`user_id` = n.`user_id` AND FIND_IN_SET(n.`reason`, 'default'))
 +        GROUP BY u.`user_id`
 +        HAVING c != 1", "chaque personne doit avoir un et un seul nom par défaut");
 +check("SELECT u.`user_id`, u.`nom`, u.`prenom`, COUNT(n.`display`) AS c
 +        FROM `auth_user_md5` AS u
 +        LEFT JOIN `profile_names_display` AS n ON(u.`user_id` = n.`user_id` AND FIND_IN_SET(n.`reason`, 'yourself'))
 +        GROUP BY u.`user_id`
 +        HAVING c != 1", "chaque personne doit avoir un et un seul nom quand on lui parle");
 +
 +/* no alumni is allowed to have empty names */
 +check("SELECT u.`user_id`, u.`nom`, u.`prenom`
 +        FROM `auth_user_md5` AS u
 +        INNER JOIN `profile_names_search` AS n USING(`user_id`)
 +        WHERE n.`search_name` = ''", "liste des personnes qui ont un de leur nom de recherche vide");
 +        
  /* verifie qu'il n'y a pas d'utilisateurs ayant un compte Google Apps désactivé et une redirection encore active vers Google Apps */
  check("SELECT  a.alias, g.g_status, u.mail_storage
           FROM  auth_user_md5 AS u
diff --combined bin/cron/clean.php
@@@ -1,7 -1,7 +1,7 @@@
  #!/usr/bin/php5 -q
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -37,7 -37,7 +37,7 @@@ query("DELETE FROM register_pending WHE
  query("DELETE FROM register_pending WHERE hash = 'INSCRIT'");
  
  // quelques tables sont triées pour que la lecture triée soit plus facile
 -query("ALTER TABLE applis_def ORDER BY text");
 +query("ALTER TABLE profile_education_enum ORDER BY name");
  query("ALTER TABLE binets_def ORDER BY text");
  query("ALTER TABLE groupesx_def ORDER BY text");
  query("ALTER TABLE secteur ORDER BY text");
diff --combined classes/user.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -117,7 -117,7 +117,7 @@@ class User extends PlUse
          }
  
          global $globals;
 -        $res = XDB::query("SELECT  u.hruid, u.promo,
 +        $res = XDB::query("SELECT  u.hruid, d.promo,
                                     CONCAT(af.alias, '@{$globals->mail->domain}') AS forlife,
                                     CONCAT(ab.alias, '@{$globals->mail->domain}') AS bestalias,
                                     CONCAT(u.prenom, ' ', IF(u.nom_usage <> '', u.nom_usage, u.nom)) AS full_name,
                                     q.core_mail_fmt AS email_format,
                                     u.perms
                               FROM  auth_user_md5 AS u
 +                       INNER JOIN  profile_display AS d ON (d.pid = u.user_id)
                          LEFT JOIN  auth_user_quick AS q ON (q.user_id = u.user_id)
                          LEFT JOIN  aliases AS af ON (af.id = u.user_id AND af.type = 'a_vie')
                          LEFT JOIN  aliases AS ab ON (ab.id = u.user_id AND FIND_IN_SET('bestalias', ab.flags))
diff --combined htdocs/css/default.css
@@@ -1,5 -1,5 +1,5 @@@
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -107,10 -107,6 +107,10 @@@ p 
      background: inherit;
  }
  
 +.hinted {
 +    border-bottom: 1px dashed black;
 +}
 +
  input.error, textarea.error {
      background-color: #faa;
  }
@@@ -228,18 -224,6 +228,18 @@@ td.action 
  }
  td.action a { padding: 0px 2px 0px 2px; }
  
 +div.titre {
 +    color: #000000;
 +    background: inherit;
 +    font-weight: bold;
 +}
 +
 +span.titre {
 +    color: #000000;
 +    background: inherit;
 +    font-weight: bold;
 +}
 +
  /*******************************************************************************
      4   Tableau de choix de skins
          [ Styles pour les tableaux de types de ceux des skins ]
diff --combined htdocs/css/keynote.css
@@@ -1,5 -1,5 +1,5 @@@
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -247,18 -247,6 +247,18 @@@ th.grayed 
      font-style: italic;
  }
  
 +div.titre {
 +    color: #000000;
 +    background: inherit;
 +    font-weight: bold;
 +}
 +
 +span.titre {
 +    color: #000000;
 +    background: inherit;
 +    font-weight: bold;
 +}
 +
  /*******************************************************************************
      4   Tableau de choix de skins
          [ Styles pour les tableaux de types de ceux des skins ]
@@@ -334,7 -322,7 +334,7 @@@ div.contact div.nom a 
      font-size: 100%;
  }
  
 -div.contact div.appli {
 +div.contact div.edu {
  }
  
  div.contact div.bits {
diff --combined htdocs/css/openweb.css
@@@ -1,5 -1,5 +1,5 @@@
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -215,18 -215,6 +215,18 @@@ td.action 
  }
  td.action a { padding: 0px 2px; }
  
 +div.titre {
 +    color: #000000;
 +    background: inherit;
 +    font-weight: bold;
 +}
 +
 +span.titre {
 +    color: #000000;
 +    background: inherit;
 +    font-weight: bold;
 +}
 +
  /*******************************************************************************
      4   Tableau de choix de skins
          [ Styles pour les tableaux de types de ceux des skins ]
@@@ -1,5 -1,5 +1,5 @@@
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -24,15 -24,10 +24,15 @@@ function wizPage_onLoad(id
  {
      switch (id) {
        case 'general':
 -        fillType(document.forms.prof_annu['appli1[type]'], document.forms.prof_annu['appli1[id]'].selectedIndex-1);
 -        selectType(document.forms.prof_annu['appli1[type]'], document.forms.prof_annu['appli1_tmp'].value);
 -        fillType(document.forms.prof_annu['appli2[type]'], document.forms.prof_annu['appli2[id]'].selectedIndex-1);
 -        selectType(document.forms.prof_annu['appli2[type]'], document.forms.prof_annu['appli2_tmp'].value);
 +        var i = 0;
 +        var prefix  = 'edu_';
 +        while ($('.' + prefix + i).length != 0) {
 +            i++;
 +        }
 +        i--;
 +        for (var j = 0; j < i; j++) {
 +            prepareType(j);
 +        }
          break;
        case 'poly':
          updateGroupSubLink(document.forms.prof_annu.groupesx_sub);
          for (var i = 0 ; document.getElementById('job_' + i) != null ; ++i) {
              updateJobSecteur(i, 'job_' + i, 'jobs[' + i + ']',
                               document.forms.prof_annu["jobs[" + i + "][ss_secteur]"].value);
 +            updateJobSousSecteur(i, 'job_' + i, 'jobs[' + i + ']',
 +                             document.forms.prof_annu["jobs[" + i + "][sss_secteur]"].value);
          }
          setTimeout('registerEnterpriseAutocomplete(-1)', 100);
          break;
      }
  }
  
 -var applisType;
 -var applisTypeAll;
 +var educationDegree;
 +var educationDegreeAll;
 +var educationDegreeName;
  
  // General
  
  var subgrades;
  var names;
 -function fillType(selectCtrl, appli, fill)
 +function fillType(selectCtrl, edu, fill)
  {
      var i;
 -    var i0=0;
 +    var i0 = 0;
  
 -    for (i = selectCtrl.options.length; i >=0; i--) {
 +    for (i = selectCtrl.options.length; i >= 0; i--) {
          selectCtrl.options[i] = null;
      }
  
 -    if (fill || appli <0) {
 +    if (fill || edu < 0) {
          selectCtrl.options[0] = new Option(' ');
 -        i0=1;
 +        i0 = 1;
 +    }
 +    if (edu >= 0) {
 +        for (i = 0; i < educationDegree[edu].length; i++) {
 +            selectCtrl.options[i0 + i] = new Option(educationDegreeName[educationDegree[edu][i] - 1], educationDegree[edu][i]);
 +        }
 +    } else if (fill) {
 +        for (i = 0; i < educationDegreeAll.length; i++) {
 +            selectCtrl.options[i0 + i] = new Option(educationDegreeName[educationDegreeAll[i] - 1], educationDegreeAll[i]);
 +        }
      }
 -    if (appli>=0)
 -        for (i=0; i < applisType[appli].length; i++)
 -            selectCtrl.options[i0+i] = new Option(applisType[appli][i]);
 -    else if (fill)
 -        for (i=0; i < applisTypeAll.length; i++)
 -            selectCtrl.options[i0+i] = new Option(applisTypeAll[i]);
  }
  
  
  function selectType(selectCtrl, type)
  {
      for (i = 0; i < selectCtrl.options.length; i++) {
 -        if (selectCtrl.options[i].text == type)
 -            selectCtrl.selectedIndex=i;
 +        if (selectCtrl.options[i].value == type) {
 +            selectCtrl.selectedIndex = i;
 +        }
      }
  }
  
 +function prepareType(i)
 +{
 +    fillType(document.forms.prof_annu["edus[" + i + "][degreeid]"], document.forms.prof_annu["edus[" + i + "][eduid]"].selectedIndex - 1);
 +    selectType(document.forms.prof_annu["edus[" + i + "][degreeid]"], document.forms.prof_annu["edu_" + i + "_tmp"].value);
 +}
  
 +function displayNamesAdvanced()
 +{
 +    $('.names_advanced').show();
 +}
 +
 +function addSearchName()
 +{
 +    var i = 0;
 +    while ($('#search_name_' + i).length != 0) {
 +        i++;
 +    }
 +    Ajax.update_html('search_name_' + i, 'profile/ajax/searchname/' + i, function(data){
 +        $('#searchname').before(data);
 +        changeNameFlag(i);
 +    });
 +}
 +
 +function removeSearchName(i)
 +{
 +    $('#search_name_' + i).remove();
 +    updateNameDisplay();
 +}
 +
 +function changeNameFlag(i)
 +{
 +    $('#flag_' + i).remove();
 +    var typeid = $('#search_name_' + i).find('select').val();
 +    var type   = $('#search_name_' + i).find('select :selected').text();
 +    if ($('[@name=sn_type_' + typeid + '_' + i + ']').val() > 0) {
 +        $('#flag_cb_' + i).after('<span id="flag_' + i + '">&nbsp;' +
 +            '<img src="images/icons/flag_green.gif" alt="site public" title="site public" />' +
 +            '<input type="hidden" name="search_names[' + i + '][pub]" value="1"/>' +
 +            '<input type="hidden" name="search_names[' + i + '][typeid]" value="' + typeid + '"/>' +
 +            '<input type="hidden" name="search_names[' + i + '][type]" value="' + type + '"/></span>');
 +    } else {
 +        $('#flag_cb_' + i).after('<span id="flag_' + i + '">&nbsp;' +
 +            '<img src="images/icons/flag_red.gif" alt="site privé" title="site privé" />' +
 +            '<input type="hidden" name="search_names[' + i + '][typeid]" value="' + typeid + '"/>' +
 +            '<input type="hidden" name="search_names[' + i + '][type]" value="' + type + '"/></span>');
 +    }
 +}
 +
 +function updateNameDisplay()
 +{
 +    var searchnames = '';
 +    for (var i = 0; i < 10; i++) {
 +        if ($('#search_name_' + i).find(':text').val()) {
 +            searchnames += $('#search_name_' + i).find('[name*=typeid]').val() + ';';
 +            searchnames += $('#search_name_' + i).find(':checked').length-1 + ';';
 +            searchnames += $('#search_name_' + i).find(':text').val() + ';;';
 +        }
 +    }
 +    Ajax.update_html(null, 'profile/ajax/buildnames/' + searchnames, function(data){
 +        var name = data.split(';');
 +        $('#public_name').html(name[0]);
 +        $('#private_name').html(name[0] + name[1]);
 +    });
 +}
 +
 +function delNationality(i)
 +{
 +    $('#nationalite' + i).hide().find('select').val('');
 +}
 +
 +function addNationality()
 +{
 +    var i = 0;
 +    if ($('#nationalite2').find('select').val() == "") {
 +        i = 2;
 +    } else if ($('#nationalite3').find('select').val() == "") {
 +        i = 3;
 +    }
 +    if ((i == 2) || (i == 3)) {
 +        $('#nationalite' + i).show();
 +    }
 +}
 +
 +function addNetworking()
 +{
 +    var i = 0;
 +    var nws = 'networking_';
 +    while (document.getElementById(nws + i) != null) {
 +        i++;
 +    }
 +    var namefirst = '';
 +    var html = '<tr id="networking_' + i + '">'
 +        + '  <td colspan="2">'
 +        + '    <div style="float: left; width: 200px;">'
 +        + '      <span class="flags">'
 +        + '        <input type="checkbox" name="networking[' + i + '][pub]"/>'
 +        + '        <img src="images/icons/flag_green.gif" alt="site public" title="site public">'
 +        + '      </span>&nbsp;'
 +        + '      <select id="networking_type_' + i + '" name="networking[' + i + '][type]" onchange="javascript:updateNetworking(' + i + ');">';
 +    for (nw in nw_list) {
 +        if (namefirst == '') {
 +            namefirst = nw;
 +        }
 +        html += '  <option value="' + nw_list[nw] + '">' + nw + '</option>';
 +    }
 +    html += '</select>'
 +        + '      <input type="hidden" id="networking_name_' + i + '" name="networking[' + i + '][name]" value="' + namefirst + '"/>'
 +        + '    </div>'
 +        + '    <div style="float: left">'
 +        + '      <input type="text" name="networking[' + i + '][address]" value="" size="30"/>'
 +        + '      <a href="javascript:removeNetworking(' + i + ')">'
 +        + '        <img src="images/icons/cross.gif" alt="cross" title="Supprimer cet élément"/>'
 +        + '      </a>'
 +        + '    </div>'
 +        + '  </td>'
 +        + '</tr>';
 +
 +    $('#networking').before(html);
 +}
 +
 +function removeNetworking(id)
 +{
 +    $('#networking_' + id).remove();
 +}
 +
 +function updateNetworking(i)
 +{
 +    var name = document.getElementById('networking_name_' + i);
 +    var type = document.getElementById('networking_type_' + i);
 +    if (type != null && name != null) {
 +        name.value = type.options[type.selectedIndex].text;
 +    }
 +
 +}
  
  // Addresses
  
@@@ -311,74 -166,18 +311,74 @@@ function addAddress(
      Ajax.update_html('addresses_' + i + '_cont', 'profile/ajax/address/' + i, checkCurrentAddress);
  }
  
 -function addTel(id)
 +function addEdu()
 +{
 +    var i = 0;
 +    var j = 0;
 +    var prefix  = 'edu_';
 +    var class_parity;
 +
 +    while (!$('#edu_add').hasClass(prefix + i)) {
 +        if ($('.' + prefix + i).length != 0) {
 +            j++;
 +        }
 +        i++;
 +    }
 +    if (j % 2) {
 +        class_parity = 'pair';
 +    } else {
 +        class_parity = 'impair';
 +    }
 +    $('#edu_add').removeClass(prefix + i);
 +    i++;
 +    $('#edu_add').addClass(prefix + i);
 +    i--;
 +    $.get(platal_baseurl + 'profile/ajax/edu/' + i + '/' + class_parity,
 +          function(data) {
 +              $('#edu_add').before(data);
 +              prepareType(i);
 +          });
 +}
 +
 +function removeEdu(i)
 +{
 +    var prefix  = 'edu_';
 +    $('.' + prefix + i).remove();
 +    while (!$('#edu_add').hasClass(prefix + i)) {
 +        $('.' + prefix + i).toggleClass('pair');
 +        $('.' + prefix + i).toggleClass('impair');
 +        i++;
 +    }
 +}
 +
 +function addTel(prefid, prefname)
  {
      var i = 0;
 -    var adid = 'addresses_' + id;
 -    var tel  = adid + '_tel_';
 -    while (document.getElementById(tel + i) != null) {
 +    var prefix  = prefid + '_';
 +    while (document.getElementById(prefix + i) != null) {
          i++;
      }
 -    $('#' + adid + '_add_tel').before('<div id="' + tel + i + '" style="clear: both"></div>');
 -    Ajax.update_html(tel + i, 'profile/ajax/tel/' + id + '/' + i);
 +    $('#' + prefix + 'add').before('<div id="' + prefix + i + '" style="clear: both; padding-top: 4px; padding-bottom: 4px"></div>');
 +    Ajax.update_html(prefix + i, 'profile/ajax/tel/' + prefid + '/' + prefname + '/' + i);
 +}
 +
 +function removeTel(id)
 +{
 +    $('#' + id).remove();
  }
  
 +function addPhoneComment(id, pref)
 +{
 +    document.getElementById(id+'_comment').style.display = '';
 +    document.getElementById(id+'_addComment').style.display = 'none';
 +}
 +
 +function removePhoneComment(id, pref)
 +{
 +    document.getElementById(id+'_comment').style.display = 'none';
 +    document.forms.prof_annu[pref+ '[comment]'].value = '';
 +    document.getElementById(id+'_addComment').style.display = '';
 +}
  
  // Geoloc
  
@@@ -542,22 -341,7 +542,22 @@@ function updateJobSecteur(nb, id, pref
      if (secteur == '') {
          secteur = '-1';
      }
 -    Ajax.update_html(id + '_ss_secteur', 'profile/ajax/secteur/' +nb + '/' + secteur + '/' + sel);
 +    Ajax.update_html(id + '_ss_secteur', 'profile/ajax/secteur/' + nb + '/' + id + '/' + pref + '/' + secteur + '/' + sel);
 +}
 +
 +function updateJobSousSecteur(nb, id, pref, sel)
 +{
 +    var ssecteur = document.forms.prof_annu[pref + '[ss_secteur]'].value;
 +    if (ssecteur == '') {
 +        ssecteur = '-1';
 +    }
 +    Ajax.update_html(id + '_sss_secteur', 'profile/ajax/ssecteur/' + nb + '/' + ssecteur + '/' + sel);
 +}
 +
 +function displayAllSector(id)
 +{
 +    $('.sector_text_' + id).remove();
 +    $('.sector_' + id).show();
  }
  
  function makeAddJob(id)
@@@ -579,10 -363,6 +579,10 @@@ function addJob(
      $.get(platal_baseurl + 'profile/ajax/job/' + i, makeAddJob(i));
  }
  
 +function addEntreprise(id)
 +{
 +    $('.entreprise_' + id).toggle();
 +}
  
  // Skills
  
@@@ -677,13 -457,13 +677,13 @@@ function updateSecteur(
          document.getElementById('ss_secteur_sel').innerHTML = '';
          return;
      }
 -    $.get(platal_baseurl + 'profile/ajax/secteur/-1/' + secteur,
 +    $.get(platal_baseurl + 'profile/ajax/secteur/-1/0/0/' + secteur,
            function(data) {
 -          data = '<a href="javascript:addSecteur()" style="display: none; float: right" id="secteurs_add">'
 -          +  '  <img src="images/icons/add.gif" alt="" title="Ajouter ce secteur" />'
 -          +  '</a>' + data;
 -          document.getElementById('ss_secteur_sel').innerHTML = data;
 -          $(document.forms.prof_annu['jobs[-1][ss_secteur]']).change(updateSSecteur);
 +              data = '<a href="javascript:addSecteur()" style="display: none; float: right" id="secteurs_add">'
 +                     +  '  <img src="images/icons/add.gif" alt="" title="Ajouter ce secteur" />'
 +                     +  '</a>' + data;
 +              document.getElementById('ss_secteur_sel').innerHTML = data;
 +              $(document.forms.prof_annu['jobs[-1][ss_secteur]']).change(updateSSecteur);
            });
  }
  
@@@ -729,20 -509,6 +729,20 @@@ function registerEnterpriseAutocomplete
          }
        }
      );
 +
 +    $(".sector_name").each(
 +      function() {
 +        if (id == -1 || this.name == "jobs[" + id + "][sss_secteur_name]") {
 +            $(this).autocomplete(platal_baseurl + "search/autocomplete/sss_secteur",
 +                                 {
 +                                   selectOnly:1,
 +                                   field:this.name,
 +                                   matchSubset:0,
 +                                   width:$(this).width()
 +                                 });
 +        }
 +      }
 +    );
  }
  
  // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
diff --combined htdocs/xorg.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -25,7 -25,7 +25,7 @@@ $platal = new Xorg('auth', 'carnet', 'e
                     'geoloc', 'lists', 'marketing', 'payment', 'platal',
                     'profile', 'register', 'search', 'stats', 'admin',
                     'newsletter', 'axletter', 'bandeau', 'survey',
 -                   'gadgets', 'googleapps', 'poison', 'openid');
 +                   'fusionax', 'gadgets', 'googleapps', 'poison', 'openid');
  
  if (!($path = Env::v('n')) || ($path{0} < 'A' || $path{0} > 'Z')) {
      $platal->run();
index 28f3b9d,0000000..04a98ca
mode 100644,000000..100644
--- /dev/null
@@@ -1,173 -1,0 +1,173 @@@
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
 +<?php
 +/***************************************************************************
++ *  Copyright (C) 2003-2009 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                *
 + ***************************************************************************/
 +
 +function education_options($current = 0)
 +{
 +    $html = '<option value="-1"></option>';
 +    $res  = XDB::iterator("SELECT  e.id AS id, g.pays AS country,
 +                                   IF(CHAR_LENGTH(e.name) > 76, e.abbreviation, e.name) AS name
 +                             FROM  profile_education_enum AS e
 +                        LEFT JOIN  geoloc_pays            AS g ON (e.country = g.a2)
 +                     WHERE EXISTS  (SELECT  *
 +                                      FROM  profile_education_degree AS d
 +                                     WHERE  e.id = d.eduid)
 +                         ORDER BY  g.pays, e.name");
 +    $country = "";
 +    while ($arr_edu = $res->next()) {
 +        if ($arr_edu["country"] != $country) {
 +            $country = $arr_edu["country"];
 +            $html .= "<optgroup label=" . $country . ">";
 +        }
 +        $html .= '<option value="' . $arr_edu["id"] . '"';
 +        if ($arr_edu["id"] == $current) {
 +            $html .= " selected='selected'";
 +        }
 +        $html .= '>' . htmlspecialchars($arr_edu["name"]) . "</option>\n";
 +    }
 +    return $html;
 +}
 +
 +/** pour appeller education_options depuis smarty
 + */
 +function _education_options_smarty($params)
 +{
 +    if(!isset($params['selected'])) {
 +        $params['selected'] = 0;
 +    }
 +    return education_options($params['selected']);
 +}
 +Platal::page()->register_function('education_options', '_education_options_smarty');
 +
 +/** affiche un Array javascript contenant les diplômes de chaque formation
 + */
 +function education_degree()
 +{
 +    $html = "";
 +    $res = XDB::iterRow("SELECT  d.eduid, d.degreeid
 +                           FROM  profile_education_enum   AS e
 +                     INNER JOIN  profile_education_degree AS d ON (e.id = d.eduid)
 +                      LEFT JOIN  geoloc_pays              AS g ON (e.country = g.a2)
 +                       ORDER BY  g.pays, e.name");
 +    if ($edu_degree = $res->next()) {
 +        $eduid = $edu_degree['0'];
 +        $html .= "[";
 +        $html .= $edu_degree['1'];
 +        $edu_degree = $res->next();
 +        while ($edu_degree['0'] == $eduid) {
 +            $html .= "," . $edu_degree['1'];
 +            $edu_degree = $res->next();
 +        }
 +        $html .= "]";
 +    }
 +    while ($edu_degree) {
 +        $eduid = $edu_degree['0'];
 +        $html .= ",\n[";
 +        $html .= $edu_degree['1'];
 +        $edu_degree = $res->next();
 +        while ($edu_degree['0'] == $eduid) {
 +            $html .= "," . $edu_degree['1'];
 +            $edu_degree = $res->next();
 +        }
 +        $html .= "]";
 +    }
 +    return $html;
 +}
 +Platal::page()->register_function('education_degree', 'education_degree');
 +
 +/** affiche tous les types possibles de diplômes
 + */
 +function education_degree_all()
 +{
 +    $res = XDB::query("SELECT  id
 +                         FROM  profile_education_degree_enum
 +                     ORDER BY  id");
 +    return implode(',', $res->fetchColumn());
 +}
 +Platal::page()->register_function('education_degree_all', 'education_degree_all');
 +
 +/** affiche les noms de tous les diplômes possibles
 + */
 +function education_degree_name()
 +{
 +    $res = XDB::query("SELECT  degree
 +                         FROM  profile_education_degree_enum
 +                     ORDER BY  id");
 +    return '"' . implode('","', $res->fetchColumn()) . '"';
 +}
 +Platal::page()->register_function('education_degree_name', 'education_degree_name');
 +
 +/** formatte une formation pour l'affichage
 + */
 +function education_fmt($name, $url, $degree, $grad_year, $field, $program, $sexe, $long)
 +{
 +    $field = strtolower($field);
 +    $txt = "";
 +
 +    if ($grad_year || $field || $program) {
 +        $txt .= "<span title=\"(";
 +        if ($program) {
 +            $txt .= $program;
 +            if ($grad_year || $field) {
 +                $txt .= ", ";
 +            }
 +        }
 +        if ($grad_year) {
 +            if ($sexe) {
 +                $txt .= "diplômée en $grad_year";
 +            } else {
 +                $txt .= "diplômé en $grad_year";
 +            }
 +            if ($field) {
 +                $txt .= ", ";
 +            }
 +        }
 +        if ($field) {
 +            $txt .= "domaine : $field)\">";
 +        }
 +    }
 +
 +    if (($degree != "Lic.") || ($long)) {
 +        if (($degree != "Ing.") && ($degree != "Dipl.")) {
 +            $txt .= $degree;
 +        }
 +        if ($name) {
 +            $txt .= ' ';
 +        }
 +        if ($url != ' ') {
 +            $txt .= "<a href=\"$url\" onclick=\"return popup(this)\">$name</a>";
 +        } else {
 +            $txt .= $name;
 +        }
 +    }
 +    $txt .= "</span>";
 +
 +    return $txt;
 +}
 +
 +function _education_fmt($params, &$smarty)
 +{
 +    extract($params);
 +    return education_fmt($name, $url, $degree, $grad_year, $field, $program, $sexe, $long);
 +}
 +Platal::page()->register_function('education_fmt', '_education_fmt');
 +
 +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 +?>
index 31df31c,0000000..2de4a2e
mode 100644,000000..100644
--- /dev/null
@@@ -1,109 -1,0 +1,109 @@@
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
 +<?php
 +/***************************************************************************
++ *  Copyright (C) 2003-2009 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                *
 + ***************************************************************************/
 +
 +function fill_email_combobox(PlPage& $page)
 +{
 +    global $globals;
 +
 +    $user = S::user();
 +    $email_type = "directory";
 +
 +    $res = XDB::query(
 +            "SELECT  email_directory
 +               FROM  profile_directory
 +              WHERE  uid = {?}", $user->id());
 +    $email_directory = $res->fetchOneCell();
 +    if ($email_directory) {
 +        $page->assign('email_directory', $email_directory);
 +        list($alias, $domain) = explode('@', $email_directory);
 +    } else {
 +        $page->assign('email_directory', '');
 +        $email_type = NULL;
 +        $alias = $domain = '';
 +    }
 +
 +    $res = XDB::query(
 +            "SELECT  alias
 +               FROM  virtual
 +         INNER JOIN  virtual_redirect USING(vid)
 +              WHERE  (redirect = {?} OR redirect = {?})
 +                     AND alias LIKE '%@{$globals->mail->alias_dom}'",
 +            $user->forlifeEmail(),
 +            // TODO: remove this über-ugly hack. The issue is that you need
 +            // to remove all @m4x.org addresses in virtual_redirect first.
 +            $user->login() . '@' . $globals->mail->domain2);
 +    $melix = $res->fetchOneCell();
 +    if ($melix) {
 +        list($melix) = explode('@', $melix);
 +        $page->assign('melix', $melix);
 +        if (($domain == $globals->mail->alias_dom) || ($domain == $globals->mail->alias_dom2)) {
 +            $email_type = "melix";
 +        }
 +    }
 +
 +    $res = XDB::query(
 +            "SELECT  alias
 +               FROM  aliases
 +              WHERE  id={?} AND (type='a_vie' OR type='alias')", $user->id());
 +    $res = $res->fetchAllAssoc();
 +    $page->assign('list_email_X', $res);
 +    if (($domain == $globals->mail->domain) || ($domain == $globals->mail->domain2)) {
 +        foreach ($res as $res_it) {
 +            if ($alias == $res_it['alias']) {
 +                $email_type = "X";
 +            }
 +        }
 +    }
 +
 +    require_once 'emails.inc.php';
 +    $redirect = new Redirect($user);
 +    $redir    = array();
 +    foreach ($redirect->emails as $redirect_it) {
 +        if ($redirect_it instanceof EmailRedirection) {
 +            $redir[] = $redirect_it->email;
 +            if ($email_directory == $redirect_it->email) {
 +                $email_type = "redir";
 +            }
 +        }
 +    }
 +    $page->assign('list_email_redir', $redir);
 +
 +    $res = XDB::query(
 +            "SELECT  email
 +               FROM  profile_job
 +              WHERE  uid = {?}", $user->id());
 +    $res = $res->fetchAllAssoc();
 +    $pro = array();
 +    foreach ($res as $res_it) {
 +        if ($res_it['email'] != '') {
 +            $pro[] = $res_it['email'];
 +            if ($email_directory == $res_it['email']) {
 +                $email_type = "pro";
 +            }
 +        }
 +    }
 +    $page->assign('list_email_pro', $pro);
 +
 +    $page->assign('email_type', $email_type);
 +}
 +
 +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 +?>
index 049b715,0000000..ddb85a1
mode 100644,000000..100644
--- /dev/null
@@@ -1,185 -1,0 +1,185 @@@
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
 +<?php
 +/***************************************************************************
++ *  Copyright (C) 2003-2009 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                *
 + ***************************************************************************/
 +
 +function build_names_display($data)
 +{
 +    $data_array = explode(';;', $data);
 +    $n = count($data_array);
 +    $n--;
 +    for ($i = 0; $i < $n; $i++) {
 +        $searchname = explode(';', $data_array[$i]);
 +        if ($searchname[1] != 0) {
 +            list($particle, $name) = explode(' ', $searchname[2], 2);
 +            if (!$name) {
 +                list($particle, $name) = explode('\'', $searchname[2], 2);
 +            }
 +        } else {
 +            $particle = '';
 +            $name     = $searchname[2];
 +        }
 +        if (!isset($search_names[$searchname[0]])) {
 +            $search_names[$searchname[0]] = array($searchname[2], $name);
 +        } else {
 +            $search_names[$searchname[0]] = array_merge($search_names[$searchname[0]], array($name));
 +        }
 +    }
 +    $sn_types_public  = build_types('public');
 +    $sn_types_private = build_types('private');
 +    $full_name        = build_full_name($search_names, $sn_types_public);
 +    return build_public_name($search_names, $sn_types_public, $full_name) . ';' .
 +        build_private_name($search_names, $sn_types_private);
 +}
 +
 +function build_types($pub)
 +{
 +    if ($pub == 'public') {
 +        $sql_pub = "AND FIND_IN_SET('public', flags)";
 +    } elseif ($pub == 'private') {
 +        $sql_pub = "AND NOT FIND_IN_SET('public', flags)";
 +    } else {
 +        $sql_pub = "";
 +    }
 +    $sql = "SELECT  id, name
 +              FROM  profile_name_search_enum
 +             WHERE  NOT FIND_IN_SET('not_displayed', flags)" . $sql_pub;
 +    $sn_types = XDB::iterator($sql);
 +    $types    = array();
 +    while ($sn_type = $sn_types->next()) {
 +        $types[$sn_type['name']] = $sn_type['id'];
 +    }
 +    return $types;
 +}
 +
 +function build_full_name(&$search_names, &$sn_types)
 +{
 +    $name = "";
 +    if (isset($search_names[$sn_types['Nom usuel']])) {
 +        $name .= $search_names[$sn_types['Nom usuel']][0] . " ("
 +              . $search_names[$sn_types['Nom patronymique']][0] . ")";
 +    } else {
 +        $name .= $search_names[$sn_types['Nom patronymique']][0];
 +    }
 +    if (isset($search_names[$sn_types['Nom marital']])
 +        || isset($search_names[$sn_types['Pseudonyme (nom de plume)']])) {
 +        if (isset($search_names[$sn_types['Nom marital']])) {
 +            $user = S::user();
 +            if ($user->isFemale()) {
 +                $name .= " (Mme ";
 +            } else {
 +                $name .= " (M ";
 +            }
 +            $name .= $search_names[$sn_types['Nom marital']][0];
 +            if (isset($search_names[$sn_types['Pseudonyme (nom de plume)']])) {
 +                $name .= ", ";
 +            }
 +        }
 +        if (isset($search_names[$sn_types['Pseudonyme (nom de plume)']])) {
 +            $name .= $search_names[$sn_types['Pseudonyme (nom de plume)']][0];
 +        }
 +        $name .= ")";
 +    }
 +    return $name;
 +}
 +
 +function build_public_name(&$search_names, &$sn_types, $full_name)
 +{
 +    return $search_names[$sn_types['Prénom']][0] . " " . $full_name;
 +}
 +
 +function build_private_name(&$search_names, &$sn_types)
 +{
 +    $name = "";
 +    if (isset($search_names[$sn_types['Surnom']])
 +        || (isset($search_names[$sn_types['Autre prénom']])
 +        || isset($search_names[$sn_types['Autre nom']]))) {
 +        $name .= " (";
 +        if (isset($search_names[$sn_types['Surnom']])) {
 +            $name .= "alias " . $search_names[$sn_types['Surnom']][0];
 +            $i = 2;
 +            while (isset($search_names[$sn_types['Surnom']][$i])) {
 +                $name .= ", " . $search_names[$sn_types['Surnom']][$i];
 +                $i++;
 +            }
 +            if (isset($search_names[$sn_types['Autre prénom']])
 +                || isset($search_names[$sn_types['Autre nom']])) {
 +                $name .= ", ";
 +            }
 +        }
 +        if (isset($search_names[$sn_types['Autre prénom']])) {
 +            $name .= "autres prénoms : " . $search_names[$sn_types['Autre prénom']][0];
 +            $i = 2;
 +            while (isset($search_names[$sn_types['Autre prénom']][$i])) {
 +                $name .= ", " . $search_names[$sn_types['Autre prénom']][$i];
 +                $i++;
 +            }
 +            if (isset($search_names[$sn_types['Autre nom']])) {
 +                $name .= ", ";
 +            }
 +        }
 +        if (isset($search_names[$sn_types['Autre nom']])) {
 +            $name .= "autres noms : " . $search_names[$sn_types['Autre nom']][0];
 +            $i = 2;
 +            while (isset($search_names[$sn_types['Autre nom']][$i])) {
 +                $name .= ", " . $search_names[$sn_types['Autre nom']][$i];
 +                $i++;
 +            }
 +        }
 +        $name .= ")";
 +    }
 +    return $name;
 +}
 +
 +function build_directory_name(&$search_names, &$sn_types, $full_name)
 +{
 +    return $full_name . " " . $search_names[$sn_types['Prénom']][0];
 +}
 +
 +function short_name(&$search_names, &$sn_types)
 +{
 +    $name = "";
 +    if (isset($search_names[$sn_types['Nom usuel']])) {
 +        $name .= $search_names[$sn_types['Nom usuel']][0];
 +    } else {
 +        $name .= $search_names[$sn_types['Nom patronymique']][0];
 +    }
 +    $name = " ";
 +    if (isset($search_names[$sn_types['Prénom usuel']])) {
 +        $name .= $search_names[$sn_types['Prénom usuel']][0];
 +    } else {
 +        $name .= $search_names[$sn_types['Prénom']][0];
 +    }
 +    return $name;
 +}
 +
 +function sort_name(&$search_names, &$sn_types)
 +{
 +    $name = "";
 +    if (isset($search_names[$sn_types['Nom usuel']])) {
 +        $name .= $search_names[$sn_types['Nom usuel']][1];
 +    } else {
 +        $name .= $search_names[$sn_types['Nom patronymique']][1];
 +    }
 +    $name .= $search_names[$sn_types['Prénom']][0];
 +    return $name;
 +}
 +
 +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 +?>
diff --combined include/notifs.inc.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -142,17 -142,15 +142,17 @@@ $prf_desc = array('nom' => 'Son patrony
                    'freetext' => 'Le texte libre',
                    'mobile' => 'Son numéro de téléphone portable',
                    'nationalite' => 'Sa nationalité',
 +                  'nationalite2' => 'Sa seconde nationalité',
 +                  'nationalite3' => 'Sa troisième nationalité',
                    'nick' => 'Son surnom',
 -                  'web' => 'L\'adresse de son site web',
 -                  'appli1' => 'Son école d\'application',
 -                  'appli2' => 'Son école de post-application',
 +                  'networking' => 'La liste de ses adresses de networking',
 +                  'edus' => 'Ses formations',
                    'addresses' => 'Ses adresses',
                    'section' => 'Sa section sportive',
                    'binets' => 'La liste de ses binets',
                    'medals' => 'Ses décorations',
                    'cv' => 'Son Curriculum Vitae',
 +                  'corps' => 'Son Corps d\'État',
                    'jobs' => 'Ses informations professionnelles',
                    'photo' => 'Sa photographie');
  
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -20,6 -20,7 +20,6 @@@
   ***************************************************************************/
  
  
 -require_once('applis.func.inc.php');
  
  function replace_ifset(&$var,$req) {
      if (Env::has($req)){
@@@ -61,12 -62,16 +61,12 @@@ function diff_user_details(&$a, &$b, $v
                  switch ($val) {
                      case 'adr' : if (!($c['adr'] = diff_user_addresses($a[$val], $bvar, $view))) unset($c['adr']); break;
                      case 'adr_pro' : if (!($c['adr_pro'] = diff_user_pros($a[$val], $bvar, $view))) unset($c['adr_pro']); break;
 -                    case 'mobile' : if (same_tel($a[$val], $bvar)) unset($c['mobile']); break;
 +                    case 'tels' : if (!($c['tels'] = diff_user_tels($a[$val], $bvar, $view))) unset($c['tels']); break;
                  }
              }
          }
      }
 -    // don't modify mobile if you don't have the right
 -    if (isset($b['mobile_pub']) && !has_user_right($b['mobile_pub'], $view) && isset($c['mobile']))
 -        unset($c['mobile']);
 -    if (isset($b['web_pub']) && !has_user_right($b['web_pub'], $view) && isset($c['web']))
 -        unset($c['web']);
 +    // don't modify freetext if you don't have the right
      if (isset($b['freetext_pub']) && !has_user_right($b['freetext_pub'], $view) && isset($c['freetext']))
          unset($c['freetext']);
      if (!count($c))
  }
  
  function same_tel(&$a, &$b) {
 -    $numbera = preg_replace('/[^0-9]/', '', (string) $a);
 -    $numberb = preg_replace('/[^0-9]/', '', (string) $b);
 +    $numbera = format_phone_number((string) $a);
 +    $numberb = format_phone_number((string) $b);
      return $numbera === $numberb;
  }
  function same_address(&$a, &$b) {
      return
          (same_field($a['adr1'],$b['adr1'])) &&
 -        (same_field($a['adr1'],$b['adr1'])) &&
 -        (same_field($a['adr1'],$b['adr1'])) &&
 +        (same_field($a['adr2'],$b['adr2'])) &&
 +        (same_field($a['adr3'],$b['adr3'])) &&
          (same_field($a['postcode'],$b['postcode'])) &&
          (same_field($a['city'],$b['city'])) &&
          (same_field($a['countrytxt'],$b['countrytxt'])) &&
@@@ -121,57 -126,49 +121,57 @@@ function diff_user_tel(&$a, &$b) 
      return $c;
  }
  
 -function diff_user_address($a, $b) {
 -    if (isset($b['pub']) && isset($a['pub']) && has_user_right($b['pub'], $a['pub']))
 -        $a['pub'] = $b['pub'];
 -    if (isset($b['tels'])) {
 -        $bvar = $b['tels'];
 -
 -        $telids_b = array();
 -        foreach ($bvar as $i => $telb) $telids_b[$telb['telid']] = $i;
 +function diff_user_tels(&$a, &$b)
 +{
 +    $c = $a;
 +    $telids_b = array();
 +    foreach ($b as $i => $telb) $telids_b[$telb['telid']] = $i;
  
 -        if (isset($a['tels']))
 -            $avar = $a['tels'];
 -        else
 -            $avar = array();
 -        $ctels = $avar;
 -        foreach ($avar as $j => $tela) {
 -            if (isset($tela['telid'])) {
 -                // if b has a tel with the same telid, compute diff
 -                if (isset($telids_b[$tela['telid']])) {
 -                    if (!($ctels[$j] = diff_user_tel($tela, $varb[$telids_b[$tela['adrid']]])))
 -                        unset($ctels[$j]);
 -                    unset($telids_b[$tela['telid']]);
 +    foreach ($a as $j => $tela) {
 +        if (isset($tela['telid'])) {
 +            // if b has a tel with the same telid, compute diff
 +            if (isset($telids_b[$tela['telid']])) {
 +                if (!($c[$j] = diff_user_tel($tela, $b[$telids_b[$tela['adrid']]]))) {
 +                    unset($c[$j]);
                  }
 -            } else {
 -                // try to find a match in b
 -                foreach ($bvar as $i => $telb) {
 -                    if (same_tel($tela['tel'], $telb['tel'])) {
 -                        $tela['telid'] = $telb['telid'];
 -                        if (!($ctels[$j] = diff_user_tel($tela, $telb)))
 -                            unset($ctels[$j]);
 -                        unset($telids_b[$tela['telid']]);
 -                        break;
 +                unset($telids_b[$tela['telid']]);
 +            }
 +        } else {
 +            // try to find a match in b
 +            foreach ($b as $i => $telb) {
 +                if (same_tel($tela['tel'], $telb['tel'])) {
 +                    $tela['telid'] = $telb['telid'];
 +                    if (!($c[$j] = diff_user_tel($tela, $telb))) {
 +                        unset($c[$j]);
                      }
 +                    unset($telids_b[$tela['telid']]);
 +                    break;
                  }
              }
          }
 +    }
  
 -        foreach ($telids_b as $telidb => $i)
 -            $ctels[] = array('telid' => $telidb, 'remove' => 1);
 +    foreach ($telids_b as $telidb => $i)
 +        $c[] = array('telid' => $telidb, 'remove' => 1);
 +    return $c;
 +}
 +
 +function diff_user_address($a, $b) {
 +    if (isset($b['pub']) && isset($a['pub']) && has_user_right($b['pub'], $a['pub']))
 +        $a['pub'] = $b['pub'];
 +    if (isset($b['tels'])) {
 +        if (isset($a['tels'])) {
 +            $avar = $a['tels'];
 +        } else {
 +            $avar = array();
 +        }
 +        $ctels = diff_user_tels($avar, $b['tels']);
  
          if (!count($ctels)) {
              $b['tels'] = $avar;
 -        } else
 +        } else {
              $a['tels'] = $ctels;
 +        }
      }
  
      foreach ($a as $val => $avar) {
@@@ -232,18 -229,13 +232,18 @@@ function diff_user_pro($a, &$b, $view 
      }
      if (isset($b['adr_pub']) && isset($a['adr_pub']) && has_user_right($b['adr_pub'], $a['adr_pub']))
          $a['adr_pub'] = $b['adr_pub'];
 -    if (isset($b['tel_pub']) && !has_user_right($b['tel_pub'], $view)) {
 -        unset($a['tel']);
 -        unset($a['fax']);
 -        unset($a['mobile']);
 +    if (isset($b['tels'])) {
 +        if (isset($a['tels']))
 +            $avar = $a['tels'];
 +        else
 +            $avar = array();
 +        $ctels = diff_user_tels($avar, $b['tels']);
 +
 +        if (!count($ctels)) {
 +            $b['tels'] = $avar;
 +        } else
 +            $a['tels'] = $ctels;
      }
 -    if (isset($b['tel_pub']) && isset($a['tel_pub']) && has_user_right($b['tel_pub'], $a['tel_pub']))
 -        $a['tel_pub'] = $b['tel_pub'];
      if (isset($b['email_pub']) && !has_user_right($b['email_pub'], $view))
          unset($a['email']);
      if (isset($b['email_pub']) && isset($a['email_pub']) && has_user_right($b['email_pub'], $a['email_pub']))
@@@ -292,65 -284,5 +292,65 @@@ function diff_user_pros(&$a, &$b, $vie
      return $c;
  }
  
 +function format_phone_number($tel)
 +{
 +    $tel = trim($tel);
 +    if (substr($tel, 0, 3) === '(0)') {
 +        $tel = '33' . $tel;
 +    }
 +    $tel = preg_replace('/\(0\)/',  '', $tel);
 +    $tel = preg_replace('/[^0-9]/', '', $tel);
 +    if (substr($tel, 0, 2) === '00') {
 +        $tel = substr($tel, 2);
 +    } else if(substr($tel, 0, 1) === '0') {
 +        $tel = '33' . substr($tel, 1);
 +    }
 +    return $tel;
 +}
 +
 +function format_display_number($tel, &$error, $format = array('format'=>'','phoneprf'=>''))
 +{
 +    $error = false;
 +    $ret = '';
 +    $tel_length = strlen($tel);
 +    if((!isset($format['phoneprf'])) || ($format['phoneprf'] == '')) {
 +        $res = XDB::query("SELECT phoneprf, phoneformat AS format
 +                             FROM geoloc_pays
 +                            WHERE phoneprf = {?} OR phoneprf = {?} OR phoneprf = {?}
 +                            LIMIT 1",
 +                          substr($tel, 0, 1), substr($tel, 0, 2), substr($tel, 0, 3));
 +        if ($res->numRows() == 0) {
 +            $error = true;
 +            return '+' . $tel;
 +        }
 +        $format = $res->fetchOneAssoc();
 +    }
 +    if ($format['format'] == '') {
 +        $format['format'] = '+p';
 +    }
 +    $j = 0;
 +    $i = strlen($format['phoneprf']);
 +    $length_format = strlen($format['format']);
 +    while (($i < $tel_length) && ($j < $length_format)){
 +        if ($format['format'][$j] == '#'){
 +            $ret .= $tel[$i];
 +            $i++;
 +        } else if ($format['format'][$j] == 'p') {
 +            $ret .= $format['phoneprf'];
 +        } else {
 +            $ret .= $format['format'][$j];
 +        }
 +        $j++;
 +    }
 +    for (; $i < $tel_length - 1; $i += 2) {
 +        $ret .= ' ' . substr($tel, $i, 2);
 +    }
 +    //appends last alone number to the last block
 +    if ($i < $tel_length) {
 +        $ret .= substr($tel, $i);
 +    }
 +    return $ret;
 +}
 +
  // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
  ?>
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -26,7 -26,7 +26,7 @@@
   */
  function user_clear_all_subs($user_id, $really_del=true)
  {
 -    // keep datas in : aliases, adresses, tels, applis_ins, binets_ins, contacts, groupesx_ins, homonymes, identification_ax, photo
 +    // keep datas in : aliases, adresses, tels, profile_education, binets_ins, contacts, groupesx_ins, homonymes, identification_ax, photo
      // delete in     : auth_user_md5, auth_user_quick, competences_ins, emails, entreprises, langues_ins, mentor,
      //                 mentor_pays, mentor_secteurs, newsletter_ins, perte_pass, requests, user_changes, virtual_redirect, watch_sub
      // + delete maillists
      $user = User::getSilent($uid);
      list($alias) = explode('@', $user->forlifeEmail());
  
 -    $tables_to_clear = array('uid' => array('competences_ins', 'entreprises', 'langues_ins', 'mentor_pays',
 -                                            'mentor_secteurs', 'mentor', 'perte_pass', 'watch_sub'),
 +    $tables_to_clear = array('uid' => array('competences_ins', 'profile_job', 'langues_ins', 'profile_mentor_country',
 +                                            'profile_mentor_sector', 'profile_mentor', 'perte_pass', 'watch_sub'),
                               'user_id' => array('requests', 'user_changes'));
  
      if ($really_del) {
 -        array_push($tables_to_clear['uid'], 'emails', 'groupex.membres', 'contacts', 'adresses', 'tels',
 +        array_push($tables_to_clear['uid'], 'emails', 'groupex.membres', 'contacts', 'adresses', 'profile_phones',
                                              'photo', 'perte_pass', 'langues_ins', 'forums.abos', 'forums.profils');
          array_push($tables_to_clear['user_id'], 'newsletter_ins', 'auth_user_quick', 'binets_ins');
          $tables_to_clear['id'] = array('aliases');
          $tables_to_clear['contact'] = array('contacts');
          XDB::execute("UPDATE auth_user_md5
                           SET date_ins = 0, promo_sortie = 0, nom_usage = '',  password = '', perms = 'pending',
 -                             nationalite = '', cv = '', section = 0, date = 0, smtppass = '', mail_storage = ''
 +                             nationalite = '', nationalite2 = '', nationalite3 = '', cv = '', section = 0,
 +                             date = 0, smtppass = '', mail_storage = ''
                         WHERE user_id = {?}", $uid);
          XDB::execute("DELETE virtual.* FROM virtual INNER JOIN virtual_redirect AS r USING(vid) WHERE redirect = {?}",
                       $alias.'@'.$globals->mail->domain);
@@@ -130,19 -129,18 +130,19 @@@ function get_not_registered_user($login
  
  function get_user_details_pro($uid, $view = 'private')
  {
 -    $sql  = "SELECT  e.entreprise, s.label as secteur , ss.label as sous_secteur , f.fonction_fr as fonction,
 -                     e.poste, e.adr1, e.adr2, e.adr3, e.postcode, e.city, e.entrid,
 -                     gp.pays AS countrytxt, gr.name AS region, e.tel, e.fax, e.mobile, e.entrid,
 -                     e.pub, e.adr_pub, e.tel_pub, e.email, e.email_pub, e.web
 -               FROM  entreprises AS e
 -          LEFT JOIN  emploi_secteur AS s ON(e.secteur = s.id)
 -          LEFT JOIN  emploi_ss_secteur AS ss ON(e.ss_secteur = ss.id AND e.secteur = ss.secteur)
 -          LEFT JOIN  fonctions_def AS f ON(e.fonction = f.id)
 -          LEFT JOIN  geoloc_pays AS gp ON (gp.a2 = e.country)
 -          LEFT JOIN  geoloc_region AS gr ON (gr.a2 = e.country and gr.region = e.region)
 -              WHERE  e.uid = {?}
 -           ORDER BY  e.entrid";
 +    $sql  = "SELECT  en.name AS entreprise, s.name as secteur, f.fonction_fr as fonction,
 +                     j.description AS poste, gp.pays AS countrytxt, gr.name AS region,
 +                     j.id AS entrid, j.pub, j.email, j.email_pub, j.url AS w_web, en.url AS web,
 +                     e.adr1, e.adr2, e.adr3, e.postcode, e.city, e.adr_pub
 +               FROM  profile_job                   AS j
 +          LEFT JOIN  entreprises                   AS e  ON (e.entrid = j.id AND e.uid = j.uid)
 +          LEFT JOIN  profile_job_enum              AS en ON (j.jobid = en.id)
 +          LEFT JOIN  profile_job_subsubsector_enum AS s  ON (j.subsubsectorid = s.id)
 +          LEFT JOIN  fonctions_def                 AS f  ON (j.functionid = f.id)
 +          LEFT JOIN  geoloc_pays                   AS gp ON (gp.a2 = e.country)
 +          LEFT JOIN  geoloc_region                 AS gr ON (gr.a2 = e.country AND gr.region = e.region)
 +              WHERE  j.uid = {?}
 +           ORDER BY  j.id";
      $res  = XDB::query($sql, $uid);
      $all_pro = $res->fetchAllAssoc();
      foreach ($all_pro as $i => $pro) {
                      $all_pro[$i]['region'] = '';
                  }
              }
 -            if (!has_user_right($pro['tel_pub'], $view)) {
 -                // if no tel was defined, then the viewer will be able to write it
 -                if ($pro['tel'] == '' &&
 -                    $pro['fax'] == '' &&
 -                    $pro['mobile'] == '') {
 -                    $all_pro[$i]['tel_pub'] = $view;
 -                } else {
 -                    $all_pro[$i]['tel'] = '';
 -                    $all_pro[$i]['fax'] = '';
 -                    $all_pro[$i]['mobile'] = '';
 +            $sql = "SELECT  pub AS tel_pub, tel_type, display_tel AS tel, comment
 +                      FROM  profile_phones AS t
 +                     WHERE  uid = {?} AND link_type = 'pro' AND link_id = {?}
 +                  ORDER BY  link_id, tel_type DESC, tel_id";
 +            $restel = XDB::iterator($sql, $uid, $pro['entrid']);
 +            while ($nexttel = $restel->next()) {
 +                if (has_user_right($nexttel['tel_pub'], $view)) {
 +                    if (!isset($all_pro[$i]['tels'])) {
 +                        $all_pro[$i]['tels'] = array($nexttel);
 +                    } else {
 +                        $all_pro[$i]['tels'][] = $nexttel;
 +                    }
                  }
              }
              if (!has_user_right($pro['email_pub'], $view)) {
                  $all_pro[$i]['fonction'] == '' &&
                  $all_pro[$i]['secteur'] == '' &&
                  $all_pro[$i]['poste'] == '' &&
 -                $all_pro[$i]['tel'] == '' &&
 -                $all_pro[$i]['fax'] == '' &&
 -                $all_pro[$i]['mobile'] == '' &&
 +                (!isset($all_pro[$i]['tels'])) &&
                  $all_pro[$i]['email'] == '')
                  unset($all_pro[$i]);
          }
@@@ -217,7 -215,7 +217,7 @@@ function get_user_details_adr($uid, $vi
                       FIND_IN_SET('active', a.statut) AS active, a.adrid,
                       FIND_IN_SET('res-secondaire', a.statut) AS secondaire,
                       FIND_IN_SET('courrier', a.statut) AS courier,
 -                     a.pub, gp.display
 +                     a.pub, gp.display, a.comment
                 FROM  adresses AS a
            LEFT JOIN  geoloc_pays AS gp ON (gp.a2=a.country)
                WHERE  uid= {?} AND NOT FIND_IN_SET('pro',a.statut)
              $adrid_index[$adr['adrid']] = $i;
      }
  
 -    $sql = "SELECT  t.adrid, t.tel_pub, t.tel_type, t.tel, t.telid
 -              FROM  tels AS t
 -        INNER JOIN  adresses AS a ON (a.uid = t.uid) AND (a.adrid = t.adrid)
 -             WHERE  t.uid = {?} AND NOT FIND_IN_SET('pro',a.statut)
 -          ORDER BY  t.adrid, t.tel_type DESC, t.telid";
 +    $sql = "SELECT  link_id AS adrid, pub AS tel_pub, tel_type, display_tel AS tel, tel_id AS telid, comment
 +              FROM  profile_phones AS t
 +             WHERE  uid = {?} AND link_type = 'address'
 +          ORDER BY  link_id, tel_type DESC, tel_id";
      $restel = XDB::iterator($sql, $uid);
      while ($nexttel = $restel->next()) {
          if (has_user_right($nexttel['tel_pub'], $view)) {
  
  function &get_user_details($login, $from_uid = '', $view = 'private')
  {
 -    $reqsql = "SELECT  u.user_id, u.promo, u.promo_sortie, u.prenom, u.nom, u.nom_usage, u.date, u.cv,
 +    $reqsql = "SELECT  u.user_id, d.promo, u.prenom, u.nom, u.nom_usage, u.date, u.cv,
                         u.perms IN ('admin','user','disabled') AS inscrit,  FIND_IN_SET('femme', u.flags) AS sexe, u.deces != 0 AS dcd, u.deces,
 -                       q.profile_nick AS nickname, q.profile_from_ax, q.profile_mobile AS mobile, q.profile_web AS web, q.profile_freetext AS freetext,
 -                       q.profile_mobile_pub AS mobile_pub, q.profile_web_pub AS web_pub, q.profile_freetext_pub AS freetext_pub,
 -                       q.profile_medals_pub AS medals_pub,
 -                       IF(gp.nat='',gp.pays,gp.nat) AS nationalite, gp.a2 AS iso3166,
 +                       q.profile_nick AS nickname, q.profile_from_ax, q.profile_freetext AS freetext,
 +                       q.profile_freetext_pub AS freetext_pub,
 +                       q.profile_medals_pub AS medals_pub, co.corps_pub AS corps_pub,
 +                       IF(gp1.nat='',gp1.pays,gp1.nat) AS nationalite, gp1.a2 AS iso3166_1,
 +                       IF(gp2.nat='',gp2.pays,gp2.nat) AS nationalite2, gp2.a2 AS iso3166_2,
 +                       IF(gp3.nat='',gp3.pays,gp3.nat) AS nationalite3, gp3.a2 AS iso3166_3,
                         a.alias AS forlife, a2.alias AS bestalias,
                         c.uid IS NOT NULL AS is_contact,
                         s.text AS section, p.x, p.y, p.pub AS photo_pub,
                         u.matricule_ax,
                         m.expertise != '' AS is_referent,
 -                       (COUNT(e.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif
 -                 FROM  auth_user_md5   AS u
 -           INNER JOIN  auth_user_quick AS q  USING(user_id)
 -           INNER JOIN  aliases         AS a  ON (u.user_id=a.id AND a.type='a_vie')
 -           INNER JOIN  aliases         AS a2 ON (u.user_id=a2.id AND FIND_IN_SET('bestalias',a2.flags))
 -            LEFT JOIN  contacts        AS c  ON (c.uid = {?} and c.contact = u.user_id)
 -            LEFT JOIN  geoloc_pays     AS gp ON (gp.a2 = u.nationalite)
 -           INNER JOIN  sections        AS s  ON (s.id  = u.section)
 -            LEFT JOIN  photo           AS p  ON (p.uid = u.user_id)
 -            LEFT JOIN  mentor          AS m  ON (m.uid = u.user_id)
 -            LEFT JOIN  emails          AS e  ON (e.uid = u.user_id AND e.flags='active')
 +                       (COUNT(e.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif,
 +                       nd.display AS name_display, nd.tooltip AS name_tooltip
 +                 FROM  auth_user_md5         AS u
 +           INNER JOIN  auth_user_quick       AS q   USING(user_id)
 +           INNER JOIN  aliases               AS a   ON (u.user_id = a.id AND a.type = 'a_vie')
 +           INNER JOIN  aliases               AS a2  ON (u.user_id = a2.id AND FIND_IN_SET('bestalias', a2.flags))
 +            LEFT JOIN  contacts              AS c   ON (c.uid = {?} and c.contact = u.user_id)
 +            LEFT JOIN  profile_corps         AS co  ON (co.uid = u.user_id)
 +            LEFT JOIN  geoloc_pays           AS gp1 ON (gp1.a2 = u.nationalite)
 +            LEFT JOIN  geoloc_pays           AS gp2 ON (gp2.a2 = u.nationalite2)
 +            LEFT JOIN  geoloc_pays           AS gp3 ON (gp3.a2 = u.nationalite3)
 +           INNER JOIN  sections              AS s   ON (s.id  = u.section)
 +            LEFT JOIN  photo                 AS p   ON (p.uid = u.user_id)
 +            LEFT JOIN  profile_mentor        AS m   ON (m.uid = u.user_id)
 +            LEFT JOIN  emails                AS e   ON (e.uid = u.user_id AND e.flags='active')
 +           INNER JOIN  profile_names_display AS nd  ON (nd.user_id = u.user_id)
 +           INNER JOIN  profile_display       AS d   ON (d.pid = u.user_id)
                  WHERE  a.alias = {?}
               GROUP BY  u.user_id";
      $res  = XDB::query($reqsql, $from_uid, $login);
      $uid  = $user['user_id'];
      // hide orange status, cv, nickname, section
      if (!has_user_right('private', $view)) {
 -        $user['promo_sortie'] = $user['promo'] + 3;
          $user['cv'] = '';
          $user['nickname'] = '';
          $user['section'] = '';
      }
 -    // hide mobile
 -    if (!has_user_right($user['mobile_pub'], $view)) {
 -        if ($user['mobile'] == '')
 -            $user['mobile_pub'] = $view;
 -        else
 -            $user['mobile'] = '';
 -    }
 -    // hide web
 -    if (!has_user_right($user['web_pub'], $view)) {
 -        if ($user['web'] == '')
 -            $user['web_pub'] = $view;
 -        else
 -            $user['web'] = '';
 -    }
 +
      // hide freetext
      if (!has_user_right($user['freetext_pub'], $view)) {
          if ($user['freetext'] == '')
              $user['freetext'] = '';
      }
  
 +    $sql = "SELECT  pub AS tel_pub, tel_type, display_tel AS tel, comment
 +              FROM  profile_phones AS t
 +             WHERE  uid = {?} AND link_type = 'user'
 +          ORDER BY  tel_type DESC, tel_id";
 +    $restel = XDB::iterator($sql, $uid);
 +    while ($nexttel = $restel->next()) {
 +        if (has_user_right($nexttel['tel_pub'], $view)) {
 +            if (!isset($user['tels'])) {
 +                $user['tels'] = array($nexttel);
 +            } else {
 +                $user['tels'][] = $nexttel;
 +            }
 +        }
 +    }
 +
      $user['adr_pro'] = get_user_details_pro($uid, $view);
      $user['adr']     = get_user_details_adr($uid, $view);
  
          $user['gpxs_join'] = join(', ', $user['gpxs']);
      }
  
 -    $res = XDB::iterRow("SELECT  applis_def.text, applis_def.url, applis_ins.type
 -                           FROM  applis_ins
 -                     INNER JOIN  applis_def ON applis_def.id = applis_ins.aid
 -                          WHERE  uid={?}
 -                       ORDER BY  ordre", $uid);
 +    $res = XDB::iterRow("SELECT  en.name AS name, en.url AS url, d.degree AS degree,
 +                                 ed.grad_year AS grad_year, f.field AS field, ed.program AS program
 +                           FROM  profile_education AS ed
 +                      LEFT JOIN  profile_education_enum        AS en ON (en.id = ed.eduid)
 +                      LEFT JOIN  profile_education_degree_enum AS d  ON (d.id  = ed.degreeid)
 +                      LEFT JOIN  profile_education_field_enum  AS f  ON (f.id  = ed.fieldid)
 +                          WHERE  uid = {?} AND NOT FIND_IN_SET('primary', flags)
 +                       ORDER BY  ed.grad_year", $uid);
  
 -    $user['applis_fmt'] = Array();
 -    $user['formation'] = Array();
 -    while (list($txt, $url, $type) = $res->next()) {
 -        $user['formation'][] = $txt." ".$type;
 -        require_once('applis.func.inc.php');
 -        $user['applis_fmt'][] = applis_fmt($type, $txt, $url);
 +    if (list($name, $url, $degree, $grad_year, $field, $program) = $res->next()) {
 +        require_once('education.func.inc.php');
 +        $user['education'][] = education_fmt($name, $url, $degree, $grad_year, $field, $program, $user['sexe'], true);
 +    }
 +    while (list($name, $url, $degree, $grad_year, $field, $program) = $res->next()) {
 +        $user['education'][] = education_fmt($name, $url, $degree, $grad_year, $field, $program, $user['sexe'], true);
 +    }
 +
 +    if (has_user_right($user['corps_pub'], $view)) {
 +        $res = XDB::query("SELECT  e1.name AS original, e2.name AS current, r.name AS rank
 +                             FROM  profile_corps           AS c
 +                        LEFT JOIN  profile_corps_enum      AS e1 ON (c.original_corpsid = e1.id)
 +                        LEFT JOIN  profile_corps_enum      AS e2 ON (c.current_corpsid = e2.id)
 +                        LEFT JOIN  profile_corps_rank_enum AS r  ON (c.rankid = r.id)
 +                            WHERE  c.uid = {?} AND c.original_corpsid != 1", $uid);
 +        if ($res = $res->fetchOneRow()) {
 +            list($original, $current, $rank) = $res;
 +            $user['corps'] = "Corps d'origine : " . $original . ", corps actuel : " . $current . ", grade : " . $rank;
 +        }
      }
 -    $user['applis_join'] = join(', ', $user['applis_fmt']);
  
      if (has_user_right($user['medals_pub'], $view)) {
          $res = XDB::iterator("SELECT  m.id, m.text AS medal, m.type, s.gid, g.text AS grade
          }
      }
  
 +    $user['networking'] = Array();
 +    $res = XDB::iterator("SELECT  n.address, n.pub, m.network_type AS type, m.name, m.filter, m.link
 +                            FROM  profile_networking AS n
 +                      INNER JOIN  profile_networking_enum AS m ON (n.network_type = m.network_type)
 +                           WHERE  n.uid = {?}", $uid);
 +    while($network = $res->next())
 +    {
 +        if (has_user_right($network['pub'], $view)) {
 +            $network['link'] = str_replace('%s', $network['address'], $network['link']);
 +            $user['networking'][] = $network;
 +        }
 +    }
 +
      return $user;
  }
  // }}}
@@@ -422,7 -384,7 +422,7 @@@ function add_user_address($uid, $adrid
      if (isset($adr['tels']) && is_array($adr['tels'])) {
          $telid = 0;
          foreach ($adr['tels'] as $tel) if ($tel['tel']) {
 -            add_user_tel($uid, $adrid, $telid, $tel);
 +            add_user_tel($uid, 'address', $adrid, $telid, $tel);
              $telid ++;
          }
      }
@@@ -440,17 -402,17 +440,17 @@@ function update_user_address($uid, $adr
          $adr['adr1'], $adr['adr2'], $adr['adr3'],
          $adr['postcode'], $adr['city'], $adr['pub'], $adrid, $uid);
      if (isset($adr['tels']) && is_array($adr['tels'])) {
 -        $res = XDB::query("SELECT telid FROM tels WHERE uid = {?} AND adrid = {?} ORDER BY telid", $uid, $adrid);
 +        $res = XDB::query("SELECT tel_id FROM profile_phones WHERE uid = {?} AND link_type = 'address' AND link_id = {?} ORDER BY tel_id", $uid, $adrid);
          $telids = $res->fetchColumn();
          foreach ($adr['tels'] as $tel) {
              if (isset($tel['telid']) && isset($tel['remove']) && $tel['remove']) {
 -                remove_user_tel($uid, $adrid, $tel['telid']);
 +                remove_user_tel($uid, 'address', $adrid, $tel['telid']);
                  if (isset($telids[$tel['telid']])) unset($telids[$tel['telid']]);
              } else if (isset($tel['telid'])) {
 -                update_user_tel($uid, $adrid, $tel['telid'], $tel);
 +                update_user_tel($uid, 'address', $adrid, $tel['telid'], $tel);
              } else {
                  for ($telid = 0; isset($telids[$telid]) && ($telids[$telid] == $telid); $telid++);
 -                add_user_tel($uid, $adrid, $telid, $tel);
 +                add_user_tel($uid, 'address', $adrid, $telid, $tel);
              }
          }
      }
  // {{{ function remove_user_address()
  function remove_user_address($uid, $adrid) {
      XDB::execute("DELETE FROM adresses WHERE adrid = {?} AND uid = {?}", $adrid, $uid);
 -    XDB::execute("DELETE FROM tels WHERE adrid = {?} AND uid = {?}", $adrid, $uid);
 +    XDB::execute("DELETE FROM profile_phones WHERE link_id = {?} AND uid = {?} AND link_type = 'address'", $adrid, $uid);
  }
  // }}}
  // {{{ function add_user_tel()
 -function add_user_tel($uid, $adrid, $telid, $tel) {
 -    XDB::execute(
 -        "INSERT INTO tels SET uid = {?}, adrid = {?}, telid = {?}, tel = {?}, tel_type = {?}, tel_pub = {?}",
 -        $uid, $adrid, $telid, $tel['tel'], $tel['tel_type'], $tel['tel_pub']);
 +function add_user_tel($uid, $link_type, $link_id, $telid, $tel) {
 +    require('profil.func.inc.php');
 +    $fmt_phone  = format_phone_number($tel['tel']);
 +    $disp_phone = format_display_number($fmt_phone, $error);
 +    XDB::execute("INSERT INTO profile_phones (uid, link_type, link_id, tel_id, tel_type, search_tel, display_tel, pub)
 +                       VALUES ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
 +                 $uid, $link_type, $link_id, $telid, $tel['tel_type'], $fmt_phone, $disp_phone, $tel['tel_pub']);
  }
  // }}}
  // {{{ function update_user_tel()
 -function update_user_tel($uid, $adrid, $telid, $tel) {
 -    XDB::execute(
 -        "UPDATE tels SET tel = {?}, tel_type = {?}, tel_pub = {?}
 -        WHERE telid = {?} AND adrid = {?} AND uid = {?}",
 -        $tel['tel'], $tel['tel_type'], $tel['tel_pub'],
 -        $telid, $adrid, $uid);
 +function update_user_tel($uid, $link_type, $link_id, $telid, $tel) {
 +    require('profil.func.inc.php');
 +    $fmt_phone  = format_phone_number($tel['tel']);
 +    $disp_phone = format_display_number($fmt_phone, $error);
 +    XDB::execute("UPDATE profile_phones SET search_tel = {?}, display_tel = {?}, tel_type = {?}, pub = {?}
 +                   WHERE link_type = {?} AND tel_id = {?} AND link_id = {?} AND uid = {?}",
 +                 $fmt_phone, $disp_phone, $tel['tel_type'], $tel['tel_pub'],
 +                 $link_type, $telid, $link_id, $uid);
  }
  // }}}
  // {{{ function remove_user_tel()
 -function remove_user_tel($uid, $adrid, $telid) {
 -    XDB::execute("DELETE FROM tels WHERE telid = {?} AND adrid = {?} AND uid = {?}",
 -                 $telid, $adrid, $uid);
 +function remove_user_tel($uid, $link_type, $link_id, $telid) {
 +    XDB::execute("DELETE FROM profile_phones WHERE tel_id = {?} AND link_id = {?} AND uid = {?} AND link_type = {?}",
 +                 $telid, $link_id, $uid, $link_type);
  }
  // }}}
  // {{{ function add_user_pro()
  function add_user_pro($uid, $entrid, $pro) {
      XDB::execute(
          "INSERT INTO entreprises (`uid`, `entrid`, `entreprise`, `poste`, `secteur`, `ss_secteur`, `fonction`,
 -            `adr1`, `adr2`, `adr3`, `postcode`, `city`, `country`, `region`, `tel`, `fax`, `mobile`, `email`, `web`, `pub`, `adr_pub`, `tel_pub`, `email_pub`)
 +            `adr1`, `adr2`, `adr3`, `postcode`, `city`, `country`, `region`, `email`, `web`, `pub`, `adr_pub`, `email_pub`)
          SELECT u.user_id, {?}, {?}, {?}, s.id, ss.id, f.id,
          {?}, {?}, {?}, {?}, {?}, gp.a2, gr.region, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}
          FROM auth_user_md5 AS u
          WHERE u.user_id = {?}
          LIMIT 1",
          $entrid, $pro['entreprise'], $pro['poste'],
 -        $pro['adr1'], $pro['adr2'], $pro['adr3'], $pro['postcode'], $pro['city'], $pro['tel'], $pro['fax'], $pro['mobile'], $pro['email'], $pro['web'], $pro['pub'], $pro['adr_pub'], $pro['tel_pub'], $pro['email_pub'],
 +        $pro['adr1'], $pro['adr2'], $pro['adr3'], $pro['postcode'], $pro['city'], $pro['email'], $pro['web'], $pro['pub'], $pro['adr_pub'], $pro['email_pub'],
          $pro['secteur'], $pro['sous_secteur'], $pro['fonction'], $pro['fonction'],
          $pro['countrytxt'], $pro['countrytxt'], $pro['region'],
          $uid);
 +    if (isset($pro['tels']) && is_array($pro['tels'])) {
 +        $telid = 0;
 +        foreach ($pro['tels'] as $tel) {
 +            if ($pro['tel']) {
 +                add_user_tel($uid, 'pro', $entrid, $telid, $tel);
 +                $telid ++;
 +            }
 +        }
 +    }
  }
  // }}}
  // {{{ function update_user_pro()
@@@ -555,6 -503,13 +555,6 @@@ function update_user_pro($uid, $entrid
          $args_set[] = $pro['adr_pub'];
      }
  
 -    if (isset($pro['tel'])) {
 -        $set .= ", e.`tel` = {?}, e.`fax` = {?}, e.`mobile` = {?}, e.tel_pub = {?}";
 -        $args_set[] = $pro['tel'];
 -        $args_set[] = $pro['fax'];
 -        $args_set[] = $pro['mobile'];
 -        $args_set[] = $pro['tel_pub'];
 -    }
      if (isset($pro['email'])) {
          $set .= ", e.`email` = {?}, e.`email_pub` = {?}";
          $args_set[] = $pro['email'];
      $args_where = array($uid, $entrid);
      $args = array_merge(array($query), $args_join, $args_set, $args_where);
      call_user_func_array(array('XDB', 'execute'), $args);
 +
 +
 +    if (isset($pro['tels']) && is_array($pro['tels'])) {
 +        $res = XDB::query("SELECT tel_id FROM profile_phones WHERE uid = {?} AND link_type = 'pro' AND link_id = {?} ORDER BY tel_id", $uid, $entrid);
 +        $telids = $res->fetchColumn();
 +        foreach ($pro['tels'] as $tel) {
 +            if (isset($tel['telid']) && isset($tel['remove']) && $tel['remove']) {
 +                remove_user_tel($uid, 'pro', $entrid, $tel['telid']);
 +                if (isset($telids[$tel['telid']])) unset($telids[$tel['telid']]);
 +            } else if (isset($tel['telid'])) {
 +                update_user_tel($uid, 'pro', $entrid, $tel['telid'], $tel);
 +            } else {
 +                for ($telid = 0; isset($telids[$telid]) && ($telids[$telid] == $telid); $telid++);
 +                add_user_tel($uid, 'pro', $entrid, $telid, $tel);
 +            }
 +        }
 +    }
  }
  // }}}
  // {{{ function remove_user_pro()
  function remove_user_pro($uid, $entrid) {
      XDB::execute("DELETE FROM entreprises WHERE entrid = {?} AND uid = {?}", $entrid, $uid);
 +    XDB::execute("DELETE FROM profile_phones WHERE link_id = {?} AND uid = {?} AND link_type = 'pro'", $entrid, $uid);
  }
  // }}}
 -// {{{ function set_user_details()
 +// {{{ function set_user_details_addresses()
  function set_user_details_addresses($uid, $adrs) {
      $req = XDB::query('SELECT MAX(adrid) + 1
                           FROM adresses
@@@ -633,6 -570,9 +633,6 @@@ function set_user_details($uid, $detail
      if (isset($details['nom_usage'])) {
          XDB::execute("UPDATE auth_user_md5 SET nom_usage = {?} WHERE user_id = {?}", strtoupper($details['nom_usage']), $uid);
      }
 -    if (isset($details['mobile'])) {
 -        XDB::execute("UPDATE auth_user_quick SET profile_mobile = {?} WHERE user_id = {?}", $details['mobile'], $uid);
 -    }
      if (isset($details['nationalite'])) {
          XDB::execute(
              "UPDATE auth_user_md5 AS u
                  $uid, $groupex);
          }
      }
 -    // applis
 +    if (isset($details['tels']) && is_array($details['tels'])) {
 +        $res = XDB::query("SELECT tel_id FROM profile_phones WHERE uid = {?} AND link_type = 'user' ORDER BY tel_id", $uid);
 +        $telids = $res->fetchColumn();
 +        foreach ($details['tels'] as $tel) {
 +            if (isset($tel['telid']) && isset($tel['remove']) && $tel['remove']) {
 +                remove_user_tel($uid, 'user', 0, $tel['telid']);
 +                if (isset($telids[$tel['telid']])) unset($telids[$tel['telid']]);
 +            } else if (isset($tel['telid'])) {
 +                update_user_tel($uid, 'user', 0, $tel['telid'], $tel);
 +            } else {
 +                for ($telid = 0; isset($telids[$telid]) && ($telids[$telid] == $telid); $telid++);
 +                add_user_tel($uid, 'user', 0, $telid, $tel);
 +            }
 +        }
 +    }
 +
 +    // education
      // medals
  }
  // }}}
diff --combined include/userset.inc.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -24,19 -24,18 +24,19 @@@ require_once('user.func.inc.php')
  global $globals;
  
  @$globals->search->result_where_statement = '
 -    LEFT JOIN  applis_ins     AS ai0 ON (u.user_id = ai0.uid AND ai0.ordre = 0)
 -    LEFT JOIN  applis_def     AS ad0 ON (ad0.id = ai0.aid)
 -    LEFT JOIN  applis_ins     AS ai1 ON (u.user_id = ai1.uid AND ai1.ordre = 1)
 -    LEFT JOIN  applis_def     AS ad1 ON (ad1.id = ai1.aid)
 -    LEFT JOIN  entreprises    AS e   ON (e.entrid = 0 AND e.uid = u.user_id)
 -    LEFT JOIN  emploi_secteur AS es  ON (e.secteur = es.id)
 -    LEFT JOIN  fonctions_def  AS ef  ON (e.fonction = ef.id)
 -    LEFT JOIN  geoloc_pays    AS n   ON (u.nationalite = n.a2)
 -    LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid AND FIND_IN_SET(\'active\',adr.statut))
 -    LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
 -    LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
 -    LEFT JOIN  emails         AS em  ON (em.uid = u.user_id AND em.flags = \'active\')';
 +    LEFT JOIN  profile_education       AS edu ON (u.user_id = edu.uid)
 +    LEFT JOIN  profile_education_enum  AS ede ON (ede.id = edu.eduid)
 +    LEFT JOIN  profile_job             AS j   ON (j.id = 0 AND j.uid = u.user_id)
 +    LEFT JOIN  profile_job_enum        AS je  ON (je.id = j.jobid)
 +    LEFT JOIN  profile_job_sector_enum AS es  ON (j.sectorid = es.id)
 +    LEFT JOIN  fonctions_def           AS ef  ON (j.functionid = ef.id)
 +    LEFT JOIN  geoloc_pays             AS n1  ON (u.nationalite = n1.a2)
 +    LEFT JOIN  geoloc_pays             AS n2  ON (u.nationalite2 = n2.a2)
 +    LEFT JOIN  geoloc_pays             AS n3  ON (u.nationalite2 = n3.a2)
 +    LEFT JOIN  adresses                AS adr ON (u.user_id = adr.uid AND FIND_IN_SET(\'active\',adr.statut))
 +    LEFT JOIN  geoloc_pays             AS gp  ON (adr.country = gp.a2)
 +    LEFT JOIN  geoloc_region           AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
 +    LEFT JOIN  emails                  AS em  ON (em.uid = u.user_id AND em.flags = \'active\')';
  
  class UserSet extends PlSet
  {
@@@ -157,84 -156,55 +157,84 @@@ class MinificheView extends MultipageVi
  {
      public function __construct(PlSet &$set, $data, array $params)
      {
 -        require_once 'applis.func.inc.php';
 +        require_once 'education.func.inc.php';
          global $globals;
          $this->entriesPerPage = $globals->search->per_page;
          if (@$params['with_score']) {
 -            $this->addSortKey('score', array('-score', '-date', '-promo', 'nom', 'prenom'), 'pertinence');
 +            $this->addSortKey('score', array('-score', '-date', '-promo', 'name_sort'), 'pertinence');
          }
 -        $this->addSortKey('name', array('nom', 'prenom'), 'nom');
 -        $this->addSortKey('promo', array('-promo', 'nom', 'prenom'), 'promotion');
 -        $this->addSortKey('date_mod', array('-date', '-promo', 'nom', 'prenom'), 'dernière modification');
 +        $this->addSortKey('name', array('name_sort'), 'nom');
 +        $this->addSortKey('promo', array('-promo', 'name_sort'), 'promotion');
 +        $this->addSortKey('date_mod', array('-date', '-promo', 'name_sort'), 'dernière modification');
          parent::__construct($set, $data, $params);
      }
  
      public function fields()
      {
          global $globals;
 -        return "u.user_id AS id, u.*,
 +        return "u.user_id AS id, u.*, d.promo,
                  CONCAT(a.alias, '@{$globals->mail->domain}') AS bestemail,
                  u.perms != 'pending' AS inscrit,
                  u.perms != 'pending' AS wasinscrit,
                  u.deces != 0 AS dcd, u.deces, u.matricule_ax,
                  FIND_IN_SET('femme', u.flags) AS sexe,
 -                e.entreprise, e.web AS job_web, es.label AS secteur, ef.fonction_fr AS fonction,
 -                IF(n.nat='',n.pays,n.nat) AS nat, n.a2 AS iso3166,
 -                ad0.text AS app0text, ad0.url AS app0url, ai0.type AS app0type,
 -                ad1.text AS app1text, ad1.url AS app1url, ai1.type AS app1type,
 +                je.name AS entreprise, je.url AS job_web, es.name AS secteur, ef.fonction_fr AS fonction,
 +                IF(n1.nat = '', n1.pays, n1.nat) AS nat1, n1.a2 AS iso3166_1,
 +                IF(n2.nat = '', n2.pays, n2.nat) AS nat2, n2.a2 AS iso3166_2,
 +                IF(n3.nat = '', n3.pays, n3.nat) AS nat3, n3.a2 AS iso3166_3,
 +                IF(ede0.abbreviation = '', ede0.name, ede0.abbreviation) AS eduname0, ede0.url AS eduurl0,
 +                IF(edd0.abbreviation = '', edd0.degree, edd0.abbreviation) AS edudegree0,
 +                edu0.grad_year AS edugrad_year0, f0.field AS edufield0, edu0.program AS eduprogram0,
 +                IF(ede1.abbreviation = '', ede1.name, ede1.abbreviation) AS eduname1, ede1.url AS eduurl1,
 +                IF(edd1.abbreviation = '', edd1.degree, edd1.abbreviation) AS edudegree1,
 +                edu1.grad_year AS edugrad_year1, f1.field AS edufield1, edu1.program AS eduprogram1,
 +                IF(ede2.abbreviation = '', ede2.name, ede2.abbreviation) AS eduname2, ede2.url AS eduurl2,
 +                IF(edd2.abbreviation = '', edd2.degree, edd2.abbreviation) AS edudegree2,
 +                edu2.grad_year AS edugrad_year2, f2.field AS edufield2, edu2.program AS eduprogram2,
 +                IF(ede3.abbreviation = '', ede3.name, ede3.abbreviation) AS eduname3, ede3.url AS eduurl3,
 +                IF(edd3.abbreviation = '', edd3.degree, edd3.abbreviation) AS edudegree3,
 +                edu3.grad_year AS edugrad_year3, f3.field AS edufield3, edu3.program AS eduprogram3,
                  adr.city, gp.a2, gp.pays AS countrytxt, gr.name AS region,
 -                IF(u.nom_usage<>'',u.nom_usage,u.nom) AS sortkey,
 -                (COUNT(em.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif" .
 +                (COUNT(em.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif,
 +                nd.display AS name_display, nd.tooltip AS name_tooltip, nd.sort AS name_sort" .
                  (S::logged() ? ", c.contact AS contact" : '');
      }
  
      public function joins()
      {
 -        return  "LEFT JOIN  entreprises    AS e   ON (e.entrid = 0 AND e.uid = u.user_id".(S::logged() ? "" : " AND e.pub = 'public'").")
 -                 LEFT JOIN  emploi_secteur AS es  ON (e.secteur = es.id)
 -                 LEFT JOIN  fonctions_def  AS ef  ON (e.fonction = ef.id)
 -                 LEFT JOIN  geoloc_pays    AS n   ON (u.nationalite = n.a2)
 -                 LEFT JOIN  applis_ins     AS ai0 ON (u.user_id = ai0.uid AND ai0.ordre = 0)
 -                 LEFT JOIN  applis_def     AS ad0 ON (ad0.id = ai0.aid)
 -                 LEFT JOIN  applis_ins     AS ai1 ON (u.user_id = ai1.uid AND ai1.ordre = 1)
 -                 LEFT JOIN  applis_def     AS ad1 ON (ad1.id = ai1.aid)
 -                 LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid
 -                                                      AND FIND_IN_SET('active', adr.statut)".(S::logged() ? "" : " AND adr.pub = 'public'").")
 -                 LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
 -                 LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
 -                 LEFT JOIN  aliases        AS a   ON (a.id = u.user_id AND FIND_IN_SET('bestalias', a.flags))
 -                 LEFT JOIN  emails         AS em  ON (em.uid = u.user_id AND em.flags = 'active')" .
 -                (S::logged() ?
 -                 "LEFT JOIN  contacts       AS c   On (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
 +        return  "LEFT JOIN  aliases                       AS a    ON (u.user_id = a.id AND FIND_IN_SET('bestalias', a.flags))
 +                 LEFT JOIN  profile_job                   AS j    ON (j.uid = u.user_id".(S::logged() ? "" : " AND j.pub = 'public'").")
 +                 LEFT JOIN  profile_job_enum              AS je   ON (je.id = j.jobid)
 +                 LEFT JOIN  profile_job_sector_enum       AS es   ON (j.sectorid = es.id)
 +                 LEFT JOIN  fonctions_def                 AS ef   ON (j.functionid = ef.id)
 +                 LEFT JOIN  geoloc_pays                   AS n1   ON (u.nationalite = n1.a2)
 +                 LEFT JOIN  geoloc_pays                   AS n2   ON (u.nationalite2 = n2.a2)
 +                 LEFT JOIN  geoloc_pays                   AS n3   ON (u.nationalite3 = n3.a2)
 +                 LEFT JOIN  profile_education             AS edu0 ON (u.user_id = edu0.uid AND edu0.id = 0)
 +                 LEFT JOIN  profile_education_enum        AS ede0 ON (ede0.id = edu0.eduid)
 +                 LEFT JOIN  profile_education_degree_enum AS edd0 ON (edd0.id = edu0.degreeid)
 +                 LEFT JOIN  profile_education_field_enum  AS f0   ON (f0.id = edu0.fieldid)
 +                 LEFT JOIN  profile_education             AS edu1 ON (u.user_id = edu1.uid AND edu1.id = 1)
 +                 LEFT JOIN  profile_education_enum        AS ede1 ON (ede1.id = edu1.eduid)
 +                 LEFT JOIN  profile_education_degree_enum AS edd1 ON (edd1.id = edu1.degreeid)
 +                 LEFT JOIN  profile_education_field_enum  AS f1   ON (f1.id = edu1.fieldid)
 +                 LEFT JOIN  profile_education             AS edu2 ON (u.user_id = edu2.uid AND edu2.id = 2)
 +                 LEFT JOIN  profile_education_enum        AS ede2 ON (ede2.id = edu2.eduid)
 +                 LEFT JOIN  profile_education_degree_enum AS edd2 ON (edd2.id = edu2.degreeid)
 +                 LEFT JOIN  profile_education_field_enum  AS f2   ON (f2.id = edu2.fieldid)
 +                 LEFT JOIN  profile_education             AS edu3 ON (u.user_id = edu3.uid AND edu3.id = 3)
 +                 LEFT JOIN  profile_education_enum        AS ede3 ON (ede3.id = edu3.eduid)
 +                 LEFT JOIN  profile_education_degree_enum AS edd3 ON (edd3.id = edu3.degreeid)
 +                 LEFT JOIN  profile_education_field_enum  AS f3   ON (f3.id = edu3.fieldid)
 +                 LEFT JOIN  adresses                      AS adr  ON (u.user_id = adr.uid
 +                                                                      AND FIND_IN_SET('active', adr.statut)".(S::logged() ? "" : "
 +                                                                      AND adr.pub = 'public'").")
 +                 LEFT JOIN  geoloc_pays                   AS gp   ON (adr.country = gp.a2)
 +                 LEFT JOIN  geoloc_region                 AS gr   ON (adr.country = gr.a2 AND adr.region = gr.region)
 +                 LEFT JOIN  emails                        AS em   ON (em.uid = u.user_id AND em.flags = 'active')
 +                INNER JOIN  profile_names_display         AS nd   ON (nd.user_id = u.user_id)
 +                INNER JOIN  profile_display               AS d    ON (d.pid = u.user_id)" . (S::logged() ?
 +                "LEFT JOIN  contacts                      AS c    ON (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
                   : "");
      }
  
@@@ -267,23 -237,16 +267,23 @@@ class MentorView extends MultipageVie
      {
          $this->entriesPerPage = 10;
          $this->addSortKey('rand', array('RAND(' . S::i('uid') . ')'), 'aléatoirement');
 -        $this->addSortKey('name', array('nom', 'prenom'), 'nom');
 -        $this->addSortKey('promo', array('-promo', 'nom', 'prenom'), 'promotion');
 -        $this->addSortKey('date_mod', array('-date', '-promo', 'nom', 'prenom'), 'dernière modification');
 +        $this->addSortKey('name', array('name_sort'), 'nom');
 +        $this->addSortKey('promo', array('-promo', 'name_sort'), 'promotion');
 +        $this->addSortKey('date_mod', array('-date', '-promo', 'name_sort'), 'dernière modification');
          parent::__construct($set, $data, $params);
      }
  
      public function fields()
      {
 -        return "m.uid, u.prenom, u.nom, u.promo, u.hruid,
 -                m.expertise, mp.pid, ms.secteur, ms.ss_secteur";
 +        return "m.uid, d.promo, u.hruid,
 +                m.expertise, mp.country, ms.sectorid, ms.subsectorid,
 +                nd.display AS name_display, nd.tooltip AS name_tooltip, nd.sort AS name_sort";
 +    }
 +
 +    public function joins()
 +    {
 +        return "INNER JOIN  profile_names_display AS nd ON (nd.user_id = u.user_id)
 +                INNER JOIN  profile_display       AS d  ON (d.pid = u.user_id)";
      }
  
      public function bounds()
@@@ -314,25 -277,23 +314,25 @@@ class TrombiView extends MultipageVie
      public function __construct(PlSet &$set, $data, array $params)
      {
          $this->entriesPerPage = 24;
 -        $this->order = explode(',', Env::v('order', 'nom,prenom,promo'));
 +        $this->order = explode(',', Env::v('order', 'name_sort'));
          if (@$params['with_score']) {
 -            $this->addSortKey('score', array('-score', '-watch_last', '-promo', 'nom', 'prenom'), 'pertinence');
 +            $this->addSortKey('score', array('-score', '-watch_last', '-promo', 'name_sort'), 'pertinence');
          }
 -        $this->addSortKey('name', array('nom', 'prenom'), 'nom');
 -        $this->addSortKey('promo', array('-promo', 'nom', 'prenom'), 'promotion');
 +        $this->addSortKey('name', array('name_sort'), 'nom');
 +        $this->addSortKey('promo', array('-promo', 'name_sort'), 'promotion');
          parent::__construct($set, $data, $params);
      }
  
      public function fields()
      {
 -        return "u.user_id, IF(u.nom_usage != '', u.nom_usage, u.nom) AS nom, u.prenom, u.promo, u.hruid ";
 +        return "u.user_id, nd.display AS name_display, nd.tooltip AS name_tooltip, nd.sort AS name_sort, u.promo, d.promo, u.hruid ";
      }
  
      public function joins()
      {
 -        return "INNER JOIN  photo AS p ON (p.uid = u.user_id) ";
 +        return "INNER JOIN  photo                 AS p  ON (p.uid = u.user_id)
 +                INNER JOIN  profile_display       AS d  ON (d.pid = u.user_id)
 +                INNER JOIN  profile_names_display AS nd ON (nd.user_id = u.user_id)";
      }
  
      public function bounds()
@@@ -426,12 -387,11 +426,12 @@@ class GeolocView implements PlVie
              header('Content-Type: text/xml');
              header('Pragma:');
              $only_current = Env::v('only_current', false)? ' AND FIND_IN_SET(\'active\', adrf.statut)' : '';
 -            $it =& $this->set->get('u.user_id AS id, u.prenom, u.nom, u.promo, al.alias',
 -                                   "INNER JOIN  adresses AS adrf  ON (adrf.uid = u.user_id $only_current)
 -                                     LEFT JOIN  aliases  AS al   ON (u.user_id = al.id
 -                                                                   AND FIND_IN_SET('bestalias', al.flags))
 -                                    INNER JOIN  adresses AS avg ON (" . getadr_join('avg') . ")",
 +            $it =& $this->set->get('u.user_id AS id, u.prenom, u.nom, d.promo, al.alias',
 +                                   "INNER JOIN  adresses        AS adrf ON (adrf.uid = u.user_id $only_current)
 +                                    INNER JOIN  profile_display AS d    ON (d.pid = u.user_id)
 +                                     LEFT JOIN  aliases         AS al   ON (u.user_id = al.id
 +                                                                            AND FIND_IN_SET('bestalias', al.flags))
 +                                    INNER JOIN  adresses        AS avg  ON (" . getadr_join('avg') . ")",
                                     'adrf.cityid = ' . Env::i('cityid'), null, null, 11);
              $page->assign('users', $it);
              break;
@@@ -473,6 -433,7 +473,6 @@@ class GadgetView implements PlVie
      public function fields()
      {
          return "u.user_id AS id, u.*," .
 -                (S::logged() ? "q.profile_mobile AS mobile, " : "IF(q.profile_mobile_pub = 'public', q.profile_mobile, NULL) as mobile, ") .
                 "u.perms != 'pending' AS inscrit,
                  u.perms != 'pending' AS wasinscrit,
                  u.deces != 0 AS dcd, u.deces,
  
      public function joins()
      {
 -        return  "LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid AND FIND_IN_SET('active', adr.statut)".(S::logged() ? "" : " AND adr.pub = 'public'").")
 -                 LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
 -                 LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)" .
 +        return  "LEFT JOIN  adresses      AS adr ON (u.user_id = adr.uid AND FIND_IN_SET('active', adr.statut)".(S::logged() ? "" : "
 +                                                                         AND adr.pub = 'public'").")
 +                 LEFT JOIN  geoloc_pays   AS gp  ON (adr.country = gp.a2)
 +                 LEFT JOIN  geoloc_region AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)" .
                  (S::logged() ?
 -                 "LEFT JOIN  contacts       AS c   On (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
 +                "LEFT JOIN  contacts      AS c   ON (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
                   : "");
      }
  
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -85,10 -85,6 +85,10 @@@ abstract class Validat
          $this->stamp  = date('YmdHis');
          $this->unique = $_unique;
          $this->type   = $_type;
 +        $res = XDB::query("SELECT  promo
 +                             FROM  profile_display
 +                            WHERE  pid={?}", $this->user->id());
 +        $this->promo = $res->fetchOneCell();
      }
  
      // }}}
index 5f6e1be,0000000..635173d
mode 100644,000000..100644
--- /dev/null
@@@ -1,185 -1,0 +1,185 @@@
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
 +<?php
 +/***************************************************************************
++ *  Copyright (C) 2003-2009 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                *
 + ***************************************************************************/
 +
 +// {{{ class EntrReq
 +
 +class EntrReq extends Validate
 +{
 +    // {{{ properties
 +
 +    public $id;
 +    public $name;
 +    public $acronym;
 +    public $url;
 +    public $email;
 +    public $holdingid;
 +    public $NAF_code;
 +    public $AX_code;
 +
 +    public $tel;
 +    public $fax;
 +
 +    public $suggestions;
 +    //TODO: addresses
 +
 +    // }}}
 +    // {{{ constructor
 +
 +    public function __construct(User &$_user, $_id, $_name, $_acronym, $_url, $_email, $_tel, $_fax, $_stamp = 0)
 +    {
 +        parent::__construct($_user, false, 'entreprise', $_stamp);
 +        $this->id       = $_id;
 +        $this->name     = $_name;
 +        $this->acronym  = $_acronym;
 +        $this->url      = $_url;
 +        $this->email    = $_email;
 +        $this->tel      = $_tel;
 +        $this->fax      = $_fax;
 +
 +        $_name       = preg_replace('/[^0-9a-z]/i', ' ', strtolower(replace_accent($_name)));
 +        $name        = explode(" ", $_name);
 +        $name_array  = array_map("trim", $name);
 +        $length      = count($name_array);
 +        $where       = "";
 +        for ($i = 0; $i < $length; $i++) {
 +            if (strlen($name_array[$i]) > 2) {
 +                if ($where !== "") {
 +                    $where .= " OR ";
 +                }
 +                $where .= "name LIKE '%" . $name_array[$i] . "%'";
 +            }
 +        }
 +        $res = XDB::iterator("SELECT  name
 +                             FROM  profile_job_enum
 +                            WHERE  "
 +                          . $where);
 +        $this->suggestions = "| ";
 +        while ($sug = $res->next()) {
 +            $this->suggestions .= $sug['name'] . " | ";
 +        }
 +    }
 +
 +    // }}}
 +    // {{{ function formu()
 +
 +    public function formu()
 +    {
 +        return 'include/form.valid.entreprises.tpl';
 +    }
 +
 +    // }}}
 +    // {{{ function editor()
 +
 +    public function editor()
 +    {
 +        return 'include/form.valid.edit-entreprises.tpl';
 +    }
 +
 +    // }}}
 +    // {{{ function handle_editor()
 +
 +    protected function handle_editor()
 +    {
 +        if (Env::has('holdingid')) {
 +            $this->holdingid = trim(Env::v('holdingid'));
 +        }
 +        if (Env::has('name')) {
 +            $this->name = trim(Env::v('name'));
 +            if (Env::has('acronym')) {
 +                $this->acronym = trim(Env::v('acronym'));
 +                if (Env::has('url')) {
 +                    $this->url = trim(Env::v('url'));
 +                    if (Env::has('NAF_code')) {
 +                        $this->NAF_code = trim(Env::v('NAF_code'));
 +                        if (Env::has('AX_code')) {
 +                            $this->AX_code = trim(Env::v('AX_code'));
 +                            return true;
 +                        }
 +                    }
 +                }
 +            }
 +        }
 +        return false;
 +    }
 +
 +    // }}}
 +    // {{{ function _mail_subj
 +
 +    protected function _mail_subj()
 +    {
 +        return "[Polytechnique.org/Entreprises] Demande d'ajout d'une entreprise : " . $this->name;
 +    }
 +
 +    // }}}
 +    // {{{ function _mail_body
 +
 +    protected function _mail_body($isok)
 +    {
 +        if ($isok) {
 +            return "  L'entreprise " . $this->name . " vient d'être ajoutée à ta fiche.";
 +        } else {
 +            return "  La demande que tu avais faite pour l'entreprise " . $this->name .
 +                   " a été refusée, car elle figure déjà dans notre base.";
 +        }
 +    }
 +
 +    // }}}
 +    // {{{ function commit()
 +
 +    public function commit()
 +    {
 +        $res = XDB::query('SELECT  id
 +                             FROM  profile_job_enum
 +                            WHERE  name = {?}',
 +                          $this->name);
 +        if ($res->numRows() != 1) {
 +            require_once("profil.func.inc.php");
 +
 +            XDB::execute('INSERT INTO  profile_job_enum (name, acronym, url, email, holdingid, NAF_code, AX_code)
 +                               VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?})',
 +                         $this->name, $this->acronym, $this->url, $this->email,
 +                         $this->holdingid, $this->NAF_code, $this->AX_code);
 +            $jobid = XDB::insertId();
 +            $display_tel = format_display_number($this->tel, $error_tel);
 +            $display_fax =format_display_number($this->fax, $error_fax);
 +            XDB::execute('INSERT INTO  profile_phones (uid, link_type, link_id, tel_id, tel_type,
 +                                       search_tel, display_tel, pub)
 +                               VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}),
 +                                       ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})',
 +                         $jobid, 'hq', $this->id, 0, 'fixed', format_phone_number($this->tel), $display_tel, 'public', 
 +                         $jobid, 'hq', $this->id, 1, 'fax', format_phone_number($this->fax), $display_fax, 'public');
 +        } else {
 +            $jobid = $res->fetchOneCell();
 +            $success = true;
 +        }
 +        return XDB::execute('UPDATE  profile_job
 +                                SET  jobid = {?}
 +                              WHERE  uid = {?} AND id = {?}',
 +                            $jobid, $this->user->id(), $this->id);
 +    }
 +
 +    // }}}
 +}
 +
 +// }}}
 +
 +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 +?>
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -29,8 -29,8 +29,8 @@@ class OrangeReq extends Validat
  
      public $promo_sortie;
  
 -    public $rules = "A priori accepter (la validation sert à repousser les
 -    petits malins). Refuse si tu connais la personne et que tu es sure
 +    public $rules = "À priori accepter (la validation sert à repousser les
 +    petits malins). Refuse si tu connais la personne et que tu es sûr
      qu'elle n'est pas orange.";
  
      // }}}
      {
          parent::__construct($_user, true, 'orange');
          $this->promo_sortie  = $_sortie;
 -        $res = XDB::query("SELECT promo FROM auth_user_md5 WHERE user_id = {?}", $_user->id());
 +        $res = XDB::query("SELECT  entry_year
 +                             FROM  profile_education
 +                            WHERE  uid = {?} AND FIND_IN_SET('primary', flags)", $_uid);
 +        $this->promo = $res->fetchOneCell();
      }
  
      // }}}
      protected function _mail_body($isok)
      {
          if ($isok) {
 -            $res = "  La demande de changement de promo de sortie que tu as demandée vient d'être effectuée.";
 -            return $res;
 +            return "  La demande de changement de promotion de sortie que tu as demandée vient d'être effectuée. "
 +                   . "Si tu le souhaites, tu peux maintenant modifier l'affichage de ta promotion sur le site sur la page suivante : "
 +                   . "https://www.polytechnique.org/profile/edit";
          } else {
 -            return "  La demande de changement de promo de sortie tu avais faite a été refusée.";
 +            return "  La demande de changement de promotion de sortie tu avais faite a été refusée.";
          }
      }
  
@@@ -81,9 -77,7 +81,9 @@@
  
      public function commit()
      {
 -        XDB::execute("UPDATE auth_user_md5 set promo_sortie = {?} WHERE user_id = {?}",$this->promo_sortie, $this->user->id());
 +        XDB::execute("UPDATE  profile_education
 +                         SET  grad_year = {?}
 +                       WHERE  uid = {?} AND FIND_IN_SET('primary', flags)", $this->promo_sortie, $this->uid);
          return true;
      }
  
diff --combined modules/admin.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -720,7 -720,7 +720,7 @@@ class AdminModule extends PLModul
                  $action = Env::v('valid_promo') == 'Ajouter des membres' ? 'add' : 'ax';
                  pl_redirect('admin/promo/' . $action . '/' . Env::i('promo'));
              } else {
 -                $page->trigError('Promo non valide');
 +                $page->trigError('Promotion non valide.');
              }
          }
  
diff --combined modules/email.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -258,15 -258,7 +258,15 @@@ class EmailModule extends PLModul
              $actifs = Env::v('emails_actifs', Array());
              print_r(Env::v('emails_rewrite'));
              if (Env::v('emailop') == "ajouter" && Env::has('email')) {
 -                $retour = $redirect->add_email(Env::v('email'));
 +                $new_email = Env::v('email');
 +                if ($new_email == "new@example.org") {
 +                    $new_email = Env::v('email_new');
 +                }
 +                $retour = $redirect->add_email($new_email);
 +                if ($retour == ERROR_INVALID_EMAIL) {
 +                    $page->assign('email', $new_email);
 +                }
 +                $page->assign('retour', $retour);
              } elseif (empty($actifs)) {
                  $retour = ERROR_INACTIVE_REDIRECTION;
              } elseif (is_array($actifs)) {
          // Display GoogleApps acount information.
          require_once 'googleapps.inc.php';
          $page->assign('googleapps', GoogleAppsAccount::account_status($user->id()));
 +
 +        require_once 'emails.combobox.inc.php';
 +        fill_email_combobox($page);
      }
  
      function handler_antispam(&$page, $statut_filtre = null)
diff --combined modules/events.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -159,17 -159,16 +159,17 @@@ class EventsModule extends PLModul
  
          // Fetch the events to display, along with their metadata.
          $array = array();
 -        $it = XDB::iterator("SELECT  e.id,e.titre,e.texte,e.post_id,a.user_id,a.nom,a.prenom,a.promo,a.hruid,
 +        $it = XDB::iterator("SELECT  e.id, e.titre, e.texte, e.post_id, a.user_id, a.nom, a.prenom, d.promo AS promo_display ,a.hruid,
                                       p.x, p.y, p.attach IS NOT NULL AS img, FIND_IN_SET('wiki', e.flags) AS wiki,
                                       FIND_IN_SET('important', e.flags) AS important,
                                       e.creation_date > DATE_SUB(CURDATE(), INTERVAL 2 DAY) AS news,
                                       e.peremption < DATE_ADD(CURDATE(), INTERVAL 2 DAY) AS end,
                                       ev.user_id IS NULL AS nonlu
                                 FROM  evenements       AS e
 -                          LEFT JOIN  evenements_photo AS p ON (e.id = p.eid)
 -                         INNER JOIN  auth_user_md5    AS a ON e.user_id=a.user_id
 -                          LEFT JOIN  evenements_vus AS ev ON (e.id = ev.evt_id AND ev.user_id = {?})
 +                          LEFT JOIN  evenements_photo AS p  ON (e.id = p.eid)
 +                         INNER JOIN  auth_user_md5    AS a  ON (e.user_id = a.user_id)
 +                         INNER JOIN  profile_display  AS d  ON (d.pid = a.user_id)
 +                          LEFT JOIN  evenements_vus   AS ev ON (e.id = ev.evt_id AND ev.user_id = {?})
                                WHERE  FIND_IN_SET('valide', e.flags) AND peremption >= NOW()
                                       AND (e.promo_min = 0 || e.promo_min <= {?})
                                       AND (e.promo_max = 0 || e.promo_max >= {?})
diff --combined modules/fusionax.php
index aa07f4b,0000000..fac47d1
mode 100644,000000..100644
--- /dev/null
@@@ -1,432 -1,0 +1,432 @@@
-  *  Copyright (C) 2003-2007 Polytechnique.org                              *
 +<?php
 +/***************************************************************************
++ *  Copyright (C) 2003-2009 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                *
 + ***************************************************************************/
 +
 +/**
 + * @brief Module to merge data from AX database
 + *
 + * Module to import data from another database of alumni that had
 + * different schemas. The organization that used this db is called AX
 + * hence the name of this module.
 + *
 + * Datas are stored in an external server and you need a private key
 + * to connect to their server.
 + */
 +class FusionAxModule extends PLModule
 +{
 +    function __construct()
 +    {
 +    }
 +
 +    function handlers()
 +    {
 +        return array(
 +            'fusionax'          => $this->make_hook('index',    AUTH_MDP, 'admin'),
 +            'fusionax/import'   => $this->make_hook('import',   AUTH_MDP, 'admin'),
 +            'fusionax/view'     => $this->make_hook('view',     AUTH_MDP, 'admin'),
 +            'fusionax/ids'      => $this->make_hook('ids',      AUTH_MDP, 'admin'),
 +            'fusionax/deceased' => $this->make_hook('deceased', AUTH_MDP, 'admin'),
 +            'fusionax/promo'    => $this->make_hook('promo',    AUTH_MDP, 'admin'),
 +        );
 +    }
 +
 +
 +    function handler_index(&$page)
 +    {
 +        $globals = Platal::globals();
 +
 +        $page->changeTpl('fusionax/index.tpl');
 +        $page->assign('xorg_title', 'Polytechnique.org - Fusion des annuaires');
 +        if (isset($globals->fusionax) && isset($globals->fusionax->LastUpdate)) {
 +            $page->assign('lastimport', date("d-m-Y", $globals->fusionax->LastUpdate));
 +        }
 +    }
 +
 +    /** Import de l'annuaire de l'AX depuis l'export situé dans le home de jacou */
 +    function handler_import(&$page, $action = 'index', $fileSQL = '')
 +    {
 +        $globals = Platal::globals();
 +
 +        if ($action == 'index') {
 +            $page->changeTpl('fusionax/import.tpl');
 +            $page->addJsLink('jquery.js');
 +            if (isset($globals->fusionax) && isset($globals->fusionax->LastUpdate)) {
 +                $page->assign(
 +                    'lastimport',
 +                    "le " . date("d/m/Y à H:i", $globals->fusionax->LastUpdate));
 +            }
 +            return;
 +        }
 +
 +        // toutes les actions sont faites en ajax en utilisant jquery
 +        header("Content-type: text/javascript; charset=utf-8");
 +
 +        // log des actions
 +        $report = array();
 +
 +        // création d'un fichier temporaire si nécessaire
 +        if (Env::has('tmpdir')) {
 +            $tmpdir = Env::v('tmpdir');
 +        } else {
 +            $tmpdir = tempnam('/tmp', 'fusionax');
 +            unlink($tmpdir);
 +            mkdir($tmpdir);
 +            chmod($tmpdir, 0700);
 +        }
 +
 +        $modulepath = realpath(dirname(__FILE__) . '/fusionax/') . '/';
 +        $olddir = getcwd();
 +        chdir($tmpdir);
 +
 +        if ($action == 'launch') {
 +            // séparation de l'archive en fichiers par tables
 +            exec($modulepath . 'import-ax.sh', $report);
 +            $report[] = 'Fichier parsé.';
 +            $report[] = 'Import dans la base en cours...';
 +            $next = 'integrateSQL';
 +        } elseif ($action == 'integrateSQL') {
 +            // intégration des données dans la base MySQL
 +            // liste des fichiers sql à exécuter
 +            $filesSQL = array(
 +                'Activites.sql',
 +                'Adresses.sql',
 +                'Anciens.sql',
 +                'Formations.sql',
 +                'Entreprises.sql');
 +            if ($fileSQL != '') {
 +                // récupère le contenu du fichier sql
 +                $queries = explode(';', file_get_contents($modulepath . $fileSQL));
 +                foreach ($queries as $q) {
 +                    if (trim($q)) {
 +                        // coupe le fichier en requêtes individuelles
 +                        if (substr($q, 0, 2) == '--') {
 +                            // affiche les commentaires dans le report
 +                            $lines = explode("\n", $q);
 +                            $l = $lines[0];
 +                            $report[] = addslashes($l);
 +                        }
 +                        // exécute la requête
 +                        XDB::execute($q);
 +                    }
 +                }
 +                // trouve le prochain fichier à exécuter
 +                $trans = array_flip($filesSQL);
 +                $nextfile = $trans[$fileSQL] + 1;
 +            } else {
 +                $nextfile = 0;
 +            }
 +            if (!isset($filesSQL[$nextfile])) {
 +                // tous les fichiers ont été exécutés, on passe à l'étape
 +                // suivante
 +                $next = 'clean';
 +            } else {
 +                // on passe au fichier suivant
 +                $next = 'integrateSQL/' . $filesSQL[$nextfile];
 +            }
 +        } elseif ($action == 'clean') {
 +            // nettoyage du fichier temporaire
 +            chdir($olddir);
 +            exec("rm -Rf $tmpdir", $report);
 +            $report[] = "Fin de l\'import";
 +            // met à jour la date de dernier import
 +            //$globals->change_dynamic_config(array('LastUpdate' => time()), 'FusionAx');
 +        }
 +        foreach($report as $t) {
 +            // affiche les lignes de report
 +            echo "$('#fusionax_import').append('" . $t . "<br/>');\n";
 +        }
 +        if (isset($next)) {
 +            $tmpdir = getcwd();
 +            chdir($olddir);
 +            // lance le prochain script s'il y en a un
 +            echo "$.getScript('fusionax/import/" . $next . "?tmpdir=" . urlencode($tmpdir) . "');";
 +        }
 +        // exit pour ne pas afficher la page template par défaut
 +        exit;
 +    }
 +
 +    /** Import de l'annuaire de l'AX depuis l'export situé dans le home de jacou */
 +    function handler_view(&$page, $action = '')
 +    {
 +        $globals = Platal::globals();
 +
 +        $page->changeTpl('fusionax/view.tpl');
 +        if ($action == 'create') {
 +            XDB::execute('DROP VIEW IF EXISTS fusionax_deceased');
 +            XDB::execute('CREATE VIEW  fusionax_deceased AS
 +                               SELECT  u.user_id, a.id_ancien, u.nom, u.prenom, u.promo, u.deces AS deces_xorg, a.Date_deces AS deces_ax
 +                                 FROM  auth_user_md5    AS u
 +                           INNER JOIN  fusionax_anciens AS a ON (a.id_ancien = u.matricule_ax)
 +                                WHERE  u.deces != a.Date_deces');
 +            XDB::execute('DROP VIEW IF EXISTS fusionax_promo');
 +            XDB::execute('CREATE VIEW  fusionax_promo AS
 +                               SELECT  u.user_id, u.matricule_ax, CONCAT(u.nom, " ", u.prenom) AS display_name, u.promo AS promo_etude_xorg,
 +                                       f.promotion_etude AS promo_etude_ax, u.promo_sortie AS promo_sortie_xorg
 +                                 FROM  auth_user_md5    AS u
 +                           INNER JOIN  fusionax_anciens AS f ON (u.matricule_ax = f.id_ancien)
 +                                WHERE  u.promo != f.promotion_etude AND !(f.promotion_etude = u.promo + 1 AND u.promo_sortie = u.promo + 4)');
 +        }
 +    }
 +
 +    /* Mets à NULL le matricule_ax de ces camarades pour marquer le fait qu'ils ne figurent pas dans l'annuaire de l'AX */
 +    private static function clear_wrong_in_xorg($user_id)
 +    {
 +        $res = XDB::execute("UPDATE  fusionax_xorg_anciens
 +                                SET  matricule_ax = NULL
 +                              WHERE  user_id = {?}", $user_id);
 +        if (!$res) {
 +            return 0;
 +        }
 +        return XDB::affectedRows() / 2;
 +    }
 +
 +    /* Cherche les les anciens présents dans Xorg avec un matricule_ax ne correspondant à rien dans la base de l'AX 
 +     * (mises à part les promo 1921 et 1923 qui ne figurent pas dans les données de l'AX)*/
 +    private static function find_wrong_in_xorg($limit = 10)
 +    {
 +        return XDB::iterator("SELECT  u.promo, u.user_id, u.display_name
 +                                FROM  fusionax_xorg_anciens AS u
 +                               WHERE  NOT EXISTS (SELECT  *
 +                                                    FROM  fusionax_anciens AS f
 +                                                   WHERE  f.id_ancien = u.matricule_ax)
 +                                      AND u.matricule_ax IS NOT NULL AND promo != 1921 AND promo != 1923");
 +    }
 +
 +    /** Lier les identifiants d'un ancien dans les deux annuaires
 +     * @param user_id identifiant dans l'annuaire X.org
 +     * @param matricule_ax identifiant dans l'annuaire de l'AX
 +     * @return 0 si la liaison a échoué, 1 sinon
 +     */
 +    private static function link_by_ids($user_id, $matricule_ax)
 +    {
 +        $res = XDB::execute("UPDATE  fusionax_import       AS i
 +                         INNER JOIN  fusionax_xorg_anciens AS u
 +                                SET  u.matricule_ax = i.id_ancien,
 +                                     i.user_id = u.user_id,
 +                                     i.date_match_id = NOW()
 +                              WHERE  i.id_ancien = {?} AND u.user_id = {?}
 +                                     AND (u.matricule_ax != {?} OR u.matricule_ax IS NULL
 +                                          OR i.user_id != {?} OR i.user_id IS NULL)",
 +                            $matricule_ax, $user_id, $matricule_ax, $user_id);
 +        if (!$res) {
 +            return 0;
 +        }
 +        return XDB::affectedRows() / 2;
 +    }
 +
 +    /** Recherche automatique d'anciens à lier entre les deux annuaires
 +     * @param limit nombre d'anciens à trouver au max
 +     * @param sure si true, ne trouve que des anciens qui sont quasi sûrs
 +     * @return un XOrgDBIterator sur les entrées avec display_name, promo,
 +     * user_id, id_ancien et display_name_ax
 +     */
 +    private static function find_easy_to_link($limit = 10, $sure = false)
 +    {
 +        $easy_to_link = XDB::iterator("
 +        SELECT  u.display_name, u.promo, u.user_id, ax.id_ancien,
 +                CONCAT(ax.prenom, ' ', ax.nom_complet, ' (X ', ax.promotion_etude, ')') AS display_name_ax,
 +                COUNT(*) AS nbMatches
 +          FROM  fusionax_anciens      AS ax
 +    INNER JOIN  fusionax_import       AS i ON (i.id_ancien = ax.id_ancien AND i.user_id IS NULL)
 +     LEFT JOIN  fusionax_xorg_anciens AS u ON (u.matricule_ax IS NULL
 +                                               AND ax.Nom_patronymique = u.nom
 +                                               AND ax.prenom = u.prenom
 +                                               AND u.promo = ax.promotion_etude)
 +      GROUP BY  u.user_id
 +        HAVING  u.user_id IS NOT NULL AND nbMatches = 1 " . ($limit ? ('LIMIT ' . $limit) : ''));
 +        if ($easy_to_link->total() > 0 || $sure) {
 +            return $easy_to_link;
 +        }
 +        return XDB::iterator("
 +        SELECT  u.display_name, u.promo, u.user_id, ax.id_ancien,
 +                CONCAT(ax.prenom, ' ', ax.nom_complet, ' (X ', ax.promotion_etude, ')') AS display_name_ax,
 +                COUNT(*) AS nbMatches
 +          FROM  fusionax_anciens      AS ax
 +    INNER JOIN  fusionax_import       AS i ON (i.id_ancien = ax.id_ancien AND i.user_id IS NULL)
 +     LEFT JOIN  fusionax_xorg_anciens AS u ON (u.matricule_ax IS NULL
 +                                               AND (ax.Nom_patronymique = u.nom
 +                                                    OR ax.Nom_patronymique LIKE CONCAT(u.nom, ' %')
 +                                                    OR ax.Nom_patronymique LIKE CONCAT(u.nom, '-%')
 +                                                    OR ax.Nom_usuel = u.nom
 +                                                    OR u.nom LIKE CONCAT('% ', ax.Nom_patronymique))
 +                                               AND u.promo < ax.promotion_etude + 2
 +                                               AND u.promo > ax.promotion_etude - 2)
 +      GROUP BY  u.user_id
 +        HAVING  u.user_id IS NOT NULL AND nbMatches = 1 " . ($limit ? ('LIMIT ' . $limit) : ''));
 +    }
 +
 +    /** Module de mise en correspondance les ids */
 +    function handler_ids(&$page, $part = 'main', $user_id = null, $matricule_ax = null)
 +    {
 +        $globals = Platal::globals();
 +        $nbToLink = 100;
 +
 +        $page->addJsLink('jquery.js');
 +        $page->assign('xorg_title', 'Polytechnique.org - Fusion - Mise en correspondance simple');
 +        if ($part == 'missingInAX') {
 +            // locate all persons from this database that are not in AX's
 +            $page->changeTpl('fusionax/idsMissingInAx.tpl');
 +            $missingInAX = XDB::iterator("SELECT  promo, user_id, display_name
 +                                            FROM  fusionax_xorg_anciens
 +                                           WHERE  matricule_ax IS NULL");
 +            $page->assign('missingInAX', $missingInAX);
 +            return;
 +        }
 +        if ($part == 'missingInXorg') {
 +            // locate all persons from AX's database that are not here
 +            $page->changeTpl('fusionax/idsMissingInXorg.tpl');
 +            $missingInXorg = XDB::iterator("SELECT  a.promotion_etude AS promo,
 +                                                    CONCAT(a.prenom, ' ', a.Nom_usuel) AS display_name,
 +                                                    a.id_ancien
 +                                              FROM  fusionax_import
 +                                        INNER JOIN  fusionax_anciens AS a USING (id_ancien)
 +                                             WHERE  fusionax_import.user_id IS NULL");
 +            $page->assign('missingInXorg', $missingInXorg);
 +            return;
 +        }
 +        if ($part == 'wrongInXorg') {
 +            // locate all persons from Xorg database that have a bad AX id
 +            $page->changeTpl('fusionax/idswrongInXorg.tpl');
 +            $wrongInXorg = FusionAxModule::find_wrong_in_xorg($nbToLink);
 +            $page->assign('wrongInXorg', $wrongInXorg);
 +            return;
 +        }
 +        if ($part == 'cleanwronginxorg') {
 +            $linksToDo = FusionAxModule::find_wrong_in_xorg($nbToLink);
 +            while ($l = $linksToDo->next()) {
 +                FusionAxModule::clear_wrong_in_xorg($l['user_id']);
 +            }
 +            pl_redirect('fusionax/ids/wrongInXorg');
 +        }
 +        if ($part == 'lier') {
 +            if (Post::has('user_id') && Post::has('matricule_ax')) {
 +                FusionAxModule::link_by_ids(Post::i('user_id'), Post::v('matricule_ax'));
 +            }
 +        }
 +        if ($part == 'link') {
 +            FusionAxModule::link_by_ids($user_id, $matricule_ax);
 +            exit;
 +        }
 +        if ($part == 'linknext') {
 +            $linksToDo = FusionAxModule::find_easy_to_link($nbToLink);
 +            while ($l = $linksToDo->next()) {
 +                FusionAxModule::link_by_ids($l['user_id'], $l['id_ancien']);
 +            }
 +            pl_redirect('fusionax/ids#autolink');
 +        }
 +        if ($part == 'linkall') {
 +            $linksToDo = FusionAxModule::find_easy_to_link(0);
 +            while ($l = $linksToDo->next()) {
 +                FusionAxModule::link_by_ids($l['user_id'], $l['id_ancien']);
 +            }
 +        }
 +        {
 +            $page->changeTpl('fusionax/ids.tpl');
 +            $missingInAX = XDB::query('SELECT  COUNT(*)
 +                                         FROM  fusionax_xorg_anciens AS u
 +                                        WHERE  u.matricule_ax IS NULL');
 +            if ($missingInAX) {
 +                $page->assign('nbMissingInAX', $missingInAX->fetchOneCell());
 +            }
 +            $missingInXorg = XDB::query('SELECT  COUNT(*)
 +                                           FROM  fusionax_import AS i
 +                                          WHERE  i.user_id IS NULL');
 +            if ($missingInXorg) {
 +                $page->assign('nbMissingInXorg', $missingInXorg->fetchOneCell());
 +            }
 +            $wrongInXorg = FusionAxModule::find_wrong_in_xorg($nbToLink);
 +            if ($wrongInXorg->total() > 0) {
 +                $page->assign('wrongInXorg', $wrongInXorg->total());
 +            }
 +            $easyToLink = FusionAxModule::find_easy_to_link($nbToLink);
 +            if ($easyToLink->total() > 0) {
 +                $page->assign('nbMatch', $easyToLink->total());
 +                $page->assign('easyToLink', $easyToLink);
 +            }
 +        }
 +    }
 +
 +    function handler_deceased(&$page, $action = '')
 +    {
 +        if ($action == 'updateXorg') {
 +            XDB::execute('UPDATE  fusionax_deceased
 +                             SET  deces_xorg = deces_ax
 +                           WHERE  deces_xorg = "0000-00-00"');
 +        }
 +        if ($action == 'updateAX') {
 +            XDB::execute('UPDATE  fusionax_deceased
 +                             SET  deces_ax = deces_xorg
 +                           WHERE  deces_ax = "0000-00-00"');
 +        }
 +        if ($action == 'update') {
 +            if (Post::has('user_id') && Post::has('date')) {
 +                XDB::execute('UPDATE  fusionax_deceased
 +                                 SET  deces_ax = {?}, deces_xorg = {?}
 +                               WHERE  user_id = {?}',
 +                             Post::v('date'), Post::v('date'), Post::i('user_id'));
 +            }
 +        }
 +        $page->changeTpl('fusionax/deceased.tpl');
 +        // deceased
 +        $deceasedErrorsSql = XDB::query('SELECT COUNT(*) FROM fusionax_deceased');
 +        $page->assign('deceasedErrors', $deceasedErrorsSql->fetchOneCell());
 +        $res = XDB::iterator('SELECT  d.user_id, d.id_ancien, d.nom, d.prenom, d.promo, d.deces_ax,
 +                                      CONCAT(d.prenom, " ", d.nom) AS display_name
 +                                FROM  fusionax_deceased AS d
 +                               WHERE  d.deces_xorg = "0000-00-00"
 +                               LIMIT  10');
 +        $page->assign('nbDeceasedMissingInXorg', $res->total());
 +        $page->assign('deceasedMissingInXorg', $res);
 +        $res = XDB::iterator('SELECT  d.user_id, d.id_ancien, d.nom, d.prenom, d.promo, d.deces_xorg,
 +                                      CONCAT(d.prenom, " ", d.nom) AS display_name
 +                                FROM  fusionax_deceased AS d
 +                               WHERE  d.deces_ax = "0000-00-00"
 +                               LIMIT  10');
 +        $page->assign('nbDeceasedMissingInAX', $res->total());
 +        $page->assign('deceasedMissingInAX', $res);
 +        $res = XDB::iterator('SELECT  d.user_id, d.id_ancien, d.nom, d.prenom, d.promo,
 +                                      d.deces_ax, d.deces_xorg,
 +                                      CONCAT(d.prenom, " ", d.nom, " ", d.user_id) AS display_name
 +                                FROM  fusionax_deceased AS d
 +                               WHERE  d.deces_xorg != "0000-00-00" AND d.deces_ax != "0000-00-00"');
 +        $page->assign('nbDeceasedDifferent', $res->total());
 +        $page->assign('deceasedDifferent', $res);
 +    }
 +
 +    function handler_promo(&$page, $action = '')
 +    {
 +        $page->changeTpl('fusionax/promo.tpl');
 +        $res = XDB::iterator('SELECT  user_id, display_name, promo_etude_xorg, promo_sortie_xorg, promo_etude_ax
 +                                FROM  fusionax_promo
 +                               WHERE  !(promo_etude_ax + 1 = promo_etude_xorg AND promo_etude_xorg + 3 = promo_sortie_xorg)');
 +        $nbMissmatchingPromos = $res->total();
 +        $page->assign('nbMissmatchingPromos1', $res->total());
 +        $page->assign('missmatchingPromos1', $res);
 +        $res = XDB::iterator('SELECT  user_id, display_name, promo_etude_xorg, promo_sortie_xorg, promo_etude_ax
 +                                FROM  fusionax_promo
 +                               WHERE  promo_etude_ax + 1 = promo_etude_xorg AND promo_etude_xorg + 3 = promo_sortie_xorg');
 +        $nbMissmatchingPromos += $res->total();
 +        $page->assign('nbMissmatchingPromos2', $res->total());
 +        $page->assign('missmatchingPromos2', $res);
 +        $page->assign('nbMissmatchingPromos', $nbMissmatchingPromos);
 +    }
 +}
 +
 +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:?>
diff --combined modules/geoloc.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -27,7 -27,6 +27,7 @@@ class GeolocModule extends PLModul
              'geoloc'             => $this->make_hook('default', AUTH_COOKIE),
              'admin/geoloc'           => $this->make_hook('admin', AUTH_MDP, 'admin'),
              'admin/geoloc/dynamap'   => $this->make_hook('admin_dynamap', AUTH_MDP, 'admin'),
 +            'admin/geoloc/country'   => $this->make_hook('admin_country',  AUTH_MDP, 'admin')
          );
      }
  
          $page->assign("no_coordinates", $noCoordinates);
      }
  
 +    function handler_admin_country(&$page, $action = 'list', $id = null)
 +    {
 +        $page->assign('xorg_title', 'Polytechnique.org - Administration - Pays');
 +        $page->assign('title', 'Gestion des pays');
 +        $table_editor = new PLTableEditor('admin/geoloc/country', 'geoloc_pays', 'a2', true);
 +        $table_editor->describe('a2', 'alpha-2', true);
 +        $table_editor->describe('a3', 'alpha-3', false);
 +        $table_editor->describe('n3', 'ISO numeric', false);
 +        $table_editor->describe('num', 'num', false);
 +        $table_editor->describe('worldrgn', 'Continent', false);
 +        $table_editor->describe('subd', 'Subdivisions territoriales', false);
 +        $table_editor->describe('post', 'post', false);
 +        $table_editor->describe('pays', 'Nom (fr)', true);
 +        $table_editor->describe('country', 'Nom (en)', true);
 +        $table_editor->describe('phoneprf', 'Préfixe téléphonique', true);
 +        $table_editor->describe('phoneformat', 'Format du téléphone (ex: (+p) ### ## ## ##)', false);
 +        $table_editor->describe('capital', 'Capitale', true);
 +        $table_editor->describe('nat', 'Nationalité', true);
 +        $table_editor->describe('display', 'Format des adresses', false);
 +
 +        if ($action == 'update') {
 +            if (Post::has('a2') && (Post::v('a2') == $id) && Post::has('phoneprf') && (Post::v('phoneprf') != '')) {
 +                if (Post::has('phoneformat')) {
 +                    $new_format = Post::v('phoneformat');
 +                } else {
 +                    $new_format = '';
 +                }
 +                $res = XDB::query("SELECT phoneformat
 +                                     FROM geoloc_pays
 +                                    WHERE phoneprf = {?}
 +                                    LIMIT 1",
 +                                  Post::v('phoneprf'));
 +                $old_format = $res->fetchOneCell();
 +                if ($new_format != $old_format) {
 +                    require_once("profil.func.inc.php");
 +                    XDB::execute("UPDATE  geoloc_pays
 +                                     SET  phoneformat = {?}
 +                                   WHERE  phoneprf = {?}",
 +                                 $new_format, Post::v('phoneprf'));
 +                }
 +            }
 +        }
 +        $table_editor->apply($page, $action, $id);
 +    }
 +
  }
  
  // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -80,11 -80,10 +80,11 @@@ class PayPa
          $res = XDB::query(
              "SELECT a.adr1 AS address1, a.adr2 AS address2,
                      a.city, a.postcode AS zip, a.country,
 -                    IF(t.tel, t.tel, q.profile_mobile) AS night_phone_b
 +                    IF(t1.display_tel != '', t1.display_tel, t2.display_tel) AS night_phone_b
                 FROM auth_user_quick AS q
            LEFT JOIN adresses  AS a ON (q.user_id = a.uid AND FIND_IN_SET('active', a.statut))
 -          LEFT JOIN tels        AS t ON (t.uid = a.uid AND t.adrid = a.adrid)
 +          LEFT JOIN profile_phones AS t1 ON (t1.uid = a.uid AND t1.link_type = 'address' AND t1.link_id = a.adrid)
 +          LEFT JOIN profile_phones AS t2 ON (t2.uid = a.uid AND t2.link_type = 'user' AND t2.link_id = 0)
                WHERE q.user_id = {?}
                LIMIT 1", S::v('uid'));
          $this->infos['client'] = array_map('replace_accent', array_merge($info_client, $res->fetchOneAssoc()));
diff --combined modules/profile.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -24,55 -24,43 +24,55 @@@ class ProfileModule extends PLModul
      function handlers()
      {
          return array(
 -            'photo'        => $this->make_hook('photo',        AUTH_PUBLIC),
 -            'photo/change' => $this->make_hook('photo_change', AUTH_MDP),
 -
 -            'fiche.php'        => $this->make_hook('fiche',      AUTH_PUBLIC),
 -            'profile'          => $this->make_hook('profile',    AUTH_PUBLIC),
 -            'profile/private'  => $this->make_hook('profile',    AUTH_COOKIE),
 -            'profile/ax'       => $this->make_hook('ax',         AUTH_COOKIE, 'admin'),
 -            'profile/edit'     => $this->make_hook('p_edit',     AUTH_MDP),
 -            'profile/ajax/address' => $this->make_hook('ajax_address', AUTH_COOKIE, 'user', NO_AUTH),
 -            'profile/ajax/tel'     => $this->make_hook('ajax_tel',     AUTH_COOKIE, 'user', NO_AUTH),
 -            'profile/ajax/medal'   => $this->make_hook('ajax_medal',   AUTH_COOKIE, 'user', NO_AUTH),
 -            'profile/ajax/job'     => $this->make_hook('ajax_job',     AUTH_COOKIE, 'user', NO_AUTH),
 -            'profile/ajax/secteur' => $this->make_hook('ajax_secteur', AUTH_COOKIE, 'user', NO_AUTH),
 -            'profile/ajax/skill'   => $this->make_hook('ajax_skill',   AUTH_COOKIE, 'user', NO_AUTH),
 -            'javascript/applis.js' => $this->make_hook('applis_js', AUTH_COOKIE),
 -            'javascript/grades.js' => $this->make_hook('grades_js', AUTH_COOKIE),
 -            'profile/medal'    => $this->make_hook('medal', AUTH_PUBLIC),
 -            'profile/orange'   => $this->make_hook('p_orange',   AUTH_MDP),
 -            'profile/usage'    => $this->make_hook('p_usage',    AUTH_MDP),
 -
 -            'referent'         => $this->make_hook('referent',   AUTH_COOKIE),
 -            'emploi'           => $this->make_hook('ref_search', AUTH_COOKIE),
 -            'referent/search'  => $this->make_hook('ref_search', AUTH_COOKIE),
 -            'referent/ssect'   => $this->make_hook('ref_sect',   AUTH_COOKIE, 'user', NO_AUTH),
 -            'referent/country' => $this->make_hook('ref_country', AUTH_COOKIE, 'user', NO_AUTH),
 -
 -            'groupes-x'        => $this->make_hook('xnet',      AUTH_COOKIE),
 -
 -            'vcard'   => $this->make_hook('vcard',  AUTH_COOKIE, 'user', NO_HTTPS),
 -            'admin/binets'     => $this->make_hook('admin_binets', AUTH_MDP, 'admin'),
 -            'admin/medals'     => $this->make_hook('admin_medals', AUTH_MDP, 'admin'),
 -            'admin/formations' => $this->make_hook('admin_formations', AUTH_MDP, 'admin'),
 -            'admin/sections'  => $this->make_hook('admin_sections', AUTH_MDP, 'admin'),
 -            'admin/secteurs'  => $this->make_hook('admin_secteurs', AUTH_MDP, 'admin'),
 -            'admin/trombino'   => $this->make_hook('admin_trombino', AUTH_MDP, 'admin'),
 -            'admin/ss_secteurs'  => $this->make_hook('admin_ss_secteurs', AUTH_MDP, 'admin'),
 -            'admin/fonctions'  => $this->make_hook('admin_fonctions', AUTH_MDP, 'admin'),
 +            'photo'                      => $this->make_hook('photo',                      AUTH_PUBLIC),
 +            'photo/change'               => $this->make_hook('photo_change',               AUTH_MDP),
 +
 +            'fiche.php'                  => $this->make_hook('fiche',                      AUTH_PUBLIC),
 +            'profile'                    => $this->make_hook('profile',                    AUTH_PUBLIC),
 +            'profile/private'            => $this->make_hook('profile',                    AUTH_COOKIE),
 +            'profile/ax'                 => $this->make_hook('ax',                         AUTH_COOKIE, 'admin'),
 +            'profile/edit'               => $this->make_hook('p_edit',                     AUTH_MDP),
 +            'profile/ajax/address'       => $this->make_hook('ajax_address',               AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/tel'           => $this->make_hook('ajax_tel',                   AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/edu'           => $this->make_hook('ajax_edu',                   AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/medal'         => $this->make_hook('ajax_medal',                 AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/networking'         => $this->make_hook('networking',                 AUTH_PUBLIC),
 +            'profile/ajax/job'           => $this->make_hook('ajax_job',                   AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/secteur'       => $this->make_hook('ajax_secteur',               AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/ssecteur'      => $this->make_hook('ajax_ssecteur',              AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/skill'         => $this->make_hook('ajax_skill',                 AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/searchname'    => $this->make_hook('ajax_searchname',            AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/buildnames'    => $this->make_hook('ajax_buildnames',            AUTH_COOKIE, 'user', NO_AUTH),
 +            'javascript/education.js'    => $this->make_hook('education_js',               AUTH_COOKIE),
 +            'javascript/grades.js'       => $this->make_hook('grades_js',                  AUTH_COOKIE),
 +            'profile/medal'              => $this->make_hook('medal',                      AUTH_PUBLIC),
 +            'profile/name_info'          => $this->make_hook('name_info',                  AUTH_PUBLIC),
 +            'profile/orange'             => $this->make_hook('p_orange',                   AUTH_MDP),
 +            'profile/usage'              => $this->make_hook('p_usage',                    AUTH_MDP),
 +
 +            'referent'                   => $this->make_hook('referent',                   AUTH_COOKIE),
 +            'emploi'                     => $this->make_hook('ref_search',                 AUTH_COOKIE),
 +            'referent/search'            => $this->make_hook('ref_search',                 AUTH_COOKIE),
 +            'referent/ssect'             => $this->make_hook('ref_sect',                   AUTH_COOKIE, 'user', NO_AUTH),
 +            'referent/country'           => $this->make_hook('ref_country',                AUTH_COOKIE, 'user', NO_AUTH),
 +
 +            'groupes-x'                  => $this->make_hook('xnet',                       AUTH_COOKIE),
 +
 +            'vcard'                      => $this->make_hook('vcard',                      AUTH_COOKIE, 'user', NO_HTTPS),
 +            'admin/binets'               => $this->make_hook('admin_binets',               AUTH_MDP, 'admin'),
 +            'admin/medals'               => $this->make_hook('admin_medals',               AUTH_MDP, 'admin'),
 +            'admin/education'            => $this->make_hook('admin_education',            AUTH_MDP, 'admin'),
 +            'admin/education_field'      => $this->make_hook('admin_education_field',      AUTH_MDP, 'admin'),
 +            'admin/education_degree'     => $this->make_hook('admin_education_degree',     AUTH_MDP, 'admin'),
 +            'admin/education_degree_set' => $this->make_hook('admin_education_degree_set', AUTH_MDP, 'admin'),
 +            'admin/sections'             => $this->make_hook('admin_sections',             AUTH_MDP, 'admin'),
 +            'admin/secteurs'             => $this->make_hook('admin_secteurs',             AUTH_MDP, 'admin'),
 +            'admin/networking'           => $this->make_hook('admin_networking',           AUTH_MDP, 'admin'),
 +            'admin/trombino'             => $this->make_hook('admin_trombino',             AUTH_MDP, 'admin'),
 +            'admin/ss_secteurs'          => $this->make_hook('admin_ss_secteurs',          AUTH_MDP, 'admin'),
 +            'admin/fonctions'            => $this->make_hook('admin_fonctions',            AUTH_MDP, 'admin'),
 +            'admin/corps_enum'           => $this->make_hook('admin_corps_enum',           AUTH_MDP, 'admin'),
 +            'admin/corps_rank'           => $this->make_hook('admin_corps_rank',           AUTH_MDP, 'admin'),
  
          );
      }
          exit;
      }
  
 +    function handler_name_info(&$page)
 +    {
 +        header('Content-Type: text/html; charset=utf-8');
 +        $page->changeTpl('profile/name_info.tpl', SIMPLE);
 +        $res = XDB::iterator("SELECT  name, explanations,
 +                                      FIND_IN_SET('public', flags) AS public,
 +                                      FIND_IN_SET('has_particle', flags) AS has_particle
 +                                FROM  profile_name_search_enum
 +                               WHERE  NOT FIND_IN_SET('not_displayed', flags)
 +                            ORDER BY  NOT FIND_IN_SET('public', flags)");
 +        $page->assign('types', $res);
 +    }
 +
 +    function handler_networking(&$page, $mid)
 +    {
 +        $res = XDB::query("SELECT  icon
 +                             FROM  profile_networking_enum
 +                            WHERE  network_type = {?}",
 +                          $mid);
 +        $img  = dirname(__FILE__) . '/../htdocs/images/networking/' . $res->fetchOneCell();
 +        $type = mime_content_type($img);
 +        header("Content-Type: $type");
 +        echo file_get_contents($img);
 +        exit;
 +    }
 +
      function handler_photo_change(&$page)
      {
          global $globals;
  
          // Build the page
          $page->addJsLink('ajax.js');
 -        $page->addJsLink('applis.js');
 +        $page->addJsLink('education.js');
          $page->addJsLink('grades.js');
          $page->addJsLink('profile.js');
          $page->addJsLink('jquery.autocomplete.js');
                              WHERE  user_id = {?} AND naissance = '0000-00-00'", S::i('uid'));
          if ($res->numRows()) {
              $page->trigWarning("Ta date de naissance n'est pas renseignée, ce qui t'empêcheras de réaliser"
 -                      . " la procédure de récupération de mot de passe si un jour tu le perdais");
 +                      . " la procédure de récupération de mot de passe si un jour tu le perdais.");
          }
  
         $page->setTitle('Mon Profil');
      }
  
 -    function handler_applis_js(&$page)
 +    function handler_education_js(&$page)
      {
          header('Content-Type: text/javascript; charset=utf-8');
          header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
          header('Last-Modified:' . gmdate('D, d M Y H:i:s') . ' GMT');
          header('Cache-Control: no-cache, must-revalidate');
          header('Pragma: no-cache');
 -        $page->changeTpl('profile/applis.js.tpl', NO_SKIN);
 -        require_once "applis.func.inc.php";
 +        $page->changeTpl('profile/education.js.tpl', NO_SKIN);
 +        require_once "education.func.inc.php";
      }
  
      function handler_grades_js(&$page)
          $page->assign('adr', array());
      }
  
 -    function handler_ajax_tel(&$page, $adid, $telid)
 +    function handler_ajax_tel(&$page, $prefid, $prefname, $telid)
      {
          header('Content-Type: text/html; charset=utf-8');
 -        $page->changeTpl('profile/adresses.tel.tpl', NO_SKIN);
 -        $page->assign('i', $adid);
 -        $page->assign('adid', "addresses_$adid");
 -        $page->assign('adpref', "addresses[$adid]");
 -        $page->assign('t', $telid);
 +        $page->changeTpl('profile/phone.tpl', NO_SKIN);
 +        $page->assign('prefid', $prefid);
 +        $page->assign('prefname', $prefname);
 +        $page->assign('telid', $telid);
          $page->assign('tel', array());
      }
  
 +    function handler_ajax_edu(&$page, $eduid, $class)
 +    {
 +        header('Content-Type: text/html; charset=utf-8');
 +        $page->changeTpl('profile/general.edu.tpl', NO_SKIN);
 +        $res = XDB::iterator("SELECT  id, field
 +                                FROM  profile_education_field_enum
 +                            ORDER BY  field");
 +        $page->assign('edu_fields', $res->fetchAllAssoc());
 +        $page->assign('eduid', $eduid);
 +        $page->assign('class', $class);
 +        require_once "education.func.inc.php";
 +    }
 +
      function handler_ajax_medal(&$page, $id)
      {
          header('Content-Type: text/html; charset=utf-8');
          $page->assign('i', $id);
          $page->assign('job', array());
          $page->assign('new', true);
 -        $res = XDB::query("SELECT  id, label
 -                             FROM  emploi_secteur");
 +        $res = XDB::query("SELECT  id, name AS label
 +                             FROM  profile_job_sector_enum");
          $page->assign('secteurs', $res->fetchAllAssoc());
          $res = XDB::query("SELECT  id, fonction_fr, FIND_IN_SET('titre', flags) AS title
                               FROM  fonctions_def
                           ORDER BY  id");
          $page->assign('fonctions', $res->fetchAllAssoc());
 +        require_once "emails.combobox.inc.php";
 +        fill_email_combobox($page);
      }
  
 -    function handler_ajax_secteur(&$page, $id, $sect, $ssect = -1)
 +    function handler_ajax_secteur(&$page, $id, $jobid, $jobpref, $sect, $ssect = -1)
      {
          header('Content-Type: text/html; charset=utf-8');
 -        $res = XDB::iterator("SELECT  id, label
 -                                FROM  emploi_ss_secteur
 -                               WHERE  secteur = {?}", $sect);
 +        $res = XDB::iterator("SELECT  id, name AS label, FIND_IN_SET('optgroup', flags) AS optgroup
 +                                FROM  profile_job_subsector_enum
 +                               WHERE  sectorid = {?}", $sect);
          $page->changeTpl('profile/jobs.secteur.tpl', NO_SKIN);
          $page->assign('id', $id);
          $page->assign('ssecteurs', $res);
          $page->assign('sel', $ssect);
 +        if ($id != -1) {
 +            $page->assign('change', 1);
 +            $page->assign('jobid', $jobid);
 +            $page->assign('jobpref', $jobpref);
 +        }
 +    }
 +
 +    function handler_ajax_ssecteur(&$page, $id, $ssect, $sssect = -1)
 +    {
 +        header('Content-Type: text/html; charset=utf-8');
 +        $res = XDB::iterator("SELECT  id, name AS label
 +                                FROM  profile_job_subsubsector_enum
 +                               WHERE  subsectorid = {?}", $ssect);
 +        $page->changeTpl('profile/jobs.soussecteur.tpl', NO_SKIN);
 +        $page->assign('id', $id);
 +        $page->assign('sssecteurs', $res);
 +        $page->assign('sel', $sssect);
      }
  
      function handler_ajax_skill(&$page, $cat, $id)
          }
      }
  
 +    function handler_ajax_searchname(&$page, $id)
 +    {
 +        header('Content-Type: text/html; charset=utf-8');
 +        $page->changeTpl('profile/general.searchname.tpl', NO_SKIN);
 +        $res = XDB::query("SELECT  id, name, FIND_IN_SET('public', flags) AS pub
 +                             FROM  profile_name_search_enum
 +                            WHERE  NOT FIND_IN_SET('not_displayed', flags)
 +                                   AND NOT FIND_IN_SET('always_displayed', flags)");
 +        $page->assign('sn_type_list', $res->fetchAllAssoc());
 +        $page->assign('i', $id);
 +    }
 +
 +    function handler_ajax_buildnames(&$page, $data)
 +    {
 +        header('Content-Type: text/html; charset=utf-8');
 +        $page->changeTpl('profile/general.buildnames.tpl', NO_SKIN);
 +        require_once 'name.func.inc.php';
 +        $page->assign('names', build_names_display($data));
 +    }
 +
      function handler_p_orange(&$page)
      {
          $page->changeTpl('profile/orange.tpl');
  
          require_once 'validations.inc.php';
  
 -        $res = XDB::query(
 -                "SELECT  u.promo, u.promo_sortie
 -                   FROM  auth_user_md5  AS u
 -                  WHERE  user_id={?}", S::v('uid'));
 +        $res = XDB::query("SELECT  e.entry_year, e.grad_year, d.promo, FIND_IN_SET('femme', u.flags) AS sexe
 +                             FROM  auth_user_md5     AS u
 +                       INNER JOIN  profile_display   AS d ON (d.pid = u.user_id)
 +                       INNER JOIN  profile_education AS e ON (e.uid = u.user_id AND FIND_IN_SET('primary', e.flags))
 +                            WHERE  u.user_id = {?}", S::v('uid'));
  
 -        list($promo, $promo_sortie_old) = $res->fetchOneRow();
 +        list($promo, $promo_sortie_old, $promo_display, $sexe) = $res->fetchOneRow();
          $page->assign('promo_sortie_old', $promo_sortie_old);
 -        $page->assign('promo',  $promo);
 +        $page->assign('promo', $promo);
 +        $page->assign('promo_display', $promo_display);
 +        $page->assign('sexe', $sexe);
  
          if (!Env::has('promo_sortie')) {
              return;
          $promo_sortie = Env::i('promo_sortie');
  
          if ($promo_sortie < 1000 || $promo_sortie > 9999) {
 -            $page->trigError('L\'année de sortie doit être un nombre de quatre chiffres');
 +            $page->trigError('L\'année de sortie doit être un nombre de quatre chiffres.');
          }
          elseif ($promo_sortie < $promo + 3) {
 -            $page->trigError('Trop tôt');
 +            $page->trigError('Trop tôt !');
          }
          elseif ($promo_sortie == $promo_sortie_old) {
              $page->trigWarning('Tu appartiens déjà à la promotion correspondante à cette année de sortie.');
          }
          elseif ($promo_sortie == $promo + 3) {
 -            XDB::execute(
 -                "UPDATE  auth_user_md5 set promo_sortie={?}
 -                  WHERE  user_id={?}", $promo_sortie, S::v('uid'));
 +            XDB::execute("UPDATE  profile_education
 +                             SET  grad_year = {?}
 +                           WHERE  uid = {?} AND FIND_IN_SET('primary', flags)", $promo_sortie, S::v('uid'));
                  $page->trigSuccess('Ton statut "orange" a été supprimé.');
                  $page->assign('promo_sortie_old', $promo_sortie);
          }
          /////  recuperations infos referent
  
          //expertise
 -        $res = XDB::query("SELECT expertise FROM mentor WHERE uid = {?}", $user->id());
 +        $res = XDB::query("SELECT expertise FROM profile_mentor WHERE uid = {?}", $user->id());
          $page->assign('expertise', $res->fetchOneCell());
  
          //secteurs
          $secteurs = $ss_secteurs = Array();
          $res = XDB::iterRow(
 -                "SELECT  s.label, ss.label
 -                   FROM  mentor_secteurs AS m
 -              LEFT JOIN  emploi_secteur AS s ON(m.secteur = s.id)
 -              LEFT JOIN  emploi_ss_secteur AS ss ON(m.secteur = ss.secteur AND m.ss_secteur = ss.id)
 +                "SELECT  s.name AS label, ss.name AS label
 +                   FROM  profile_mentor_sector      AS m
 +              LEFT JOIN  profile_job_sector_enum    AS s  ON(m.sectorid = s.id)
 +              LEFT JOIN  profile_job_subsector_enum AS ss ON(m.sectorid = ss.sectorid AND m.subsectorid = ss.id)
                    WHERE  uid = {?}", $user->id());
          while (list($sec, $ssec) = $res->next()) {
              $secteurs[]    = $sec;
          //pays
          $res = XDB::query(
                  "SELECT  gp.pays
 -                   FROM  mentor_pays AS m
 -              LEFT JOIN  geoloc_pays AS gp ON(m.pid = gp.a2)
 +                   FROM  profile_mentor_country AS m
 +              LEFT JOIN  geoloc_pays            AS gp ON (m.country = gp.a2)
                    WHERE  uid = {?}", $user->id());
          $page->assign('pays', $res->fetchColumn());
  
          $page->setTitle('Conseil Pro');
  
          //recuperation des noms de secteurs
 -        $res = XDB::iterRow("SELECT id, label FROM emploi_secteur");
 +        $res = XDB::iterRow("SELECT id, name AS label FROM profile_job_sector_enum");
          $secteurs[''] = '';
          while (list($tmp_id, $tmp_label) = $res->next()) {
              $secteurs[$tmp_id] = $tmp_label;
          $page->assign_by_ref('secteurs', $secteurs);
  
          // nb de mentors
 -        $res = XDB::query("SELECT count(*) FROM mentor");
 +        $res = XDB::query("SELECT count(*) FROM profile_mentor");
          $page->assign('mentors_number', $res->fetchOneCell());
  
          // On vient d'un formulaire
          $expertise_champ = XDB::escape(Env::v('expertise'));
  
          if ($pays_sel != "''") {
 -            $where[] = "mp.pid = $pays_sel";
 +            $where[] = "mp.country = $pays_sel";
          }
          if ($secteur_sel != "''") {
 -            $where[] = "ms.secteur = $secteur_sel";
 +            $where[] = "ms.sectorid = $secteur_sel";
              if ($ss_secteur_sel != "''") {
 -                $where[] = "ms.ss_secteur = $ss_secteur_sel";
 +                $where[] = "ms.subsectorid = $ss_secteur_sel";
              }
          }
          if ($expertise_champ != "''") {
          if ($where) {
              $where = join(' AND ', $where);
  
 -            $set = new UserSet("INNER JOIN  mentor          AS m ON (m.uid = u.user_id)
 -                                 LEFT JOIN  mentor_pays     AS mp ON (mp.uid = m.uid)
 -                                 LEFT JOIN  mentor_secteurs AS ms ON (ms.uid = m.uid)",
 +            $set = new UserSet("INNER JOIN  profile_mentor          AS m  ON (m.uid = u.user_id)
 +                                 LEFT JOIN  profile_mentor_country  AS mp ON (mp.uid = m.uid)
 +                                 LEFT JOIN  profile_mentor_sector   AS ms ON (ms.uid = m.uid)",
                                 $where);
              $set->addMod('mentor', 'Référents');
              $set->apply('referent/search', $page, $action, $subaction);
          $page->assign('onchange', 'setSSecteurs()');
          $page->assign('id', 'ssect_field');
          $page->assign('name', 'ss_secteur');
 -        $it = XDB::iterator("SELECT  id,label AS field
 -                               FROM  emploi_ss_secteur
 -                              WHERE  secteur = {?}", $sect);
 +        $it = XDB::iterator("SELECT  id, name AS field
 +                               FROM  profile_job_subsector_enum
 +                              WHERE  sectorid = {?}", $sect);
          $page->assign('list', $it);
      }
  
          header('Content-Type: text/html; charset=utf-8');
          $page->changeTpl('include/field.select.tpl', NO_SKIN);
          $page->assign('name', 'pays_sel');
 -        $where = ($ssect ? ' AND ms.ss_secteur = {?}' : '');
 +        $where = ($ssect ? ' AND ms.subsectorid = {?}' : '');
          $it = XDB::iterator("SELECT  a2 AS id, pays AS field
 -                              FROM  geoloc_pays AS g
 -                        INNER JOIN  mentor_pays AS mp ON (mp.pid = g.a2)
 -                        INNER JOIN  mentor_secteurs AS ms ON (ms.uid = mp.uid)
 -                             WHERE  ms.secteur = {?} $where
 -                          GROUP BY  a2
 -                          ORDER BY  pays", $sect, $ssect);
 +                               FROM  geoloc_pays            AS g
 +                         INNER JOIN  profile_mentor_country AS mp ON (mp.country = g.a2)
 +                         INNER JOIN  profile_mentor_sector  AS ms ON (ms.uid = mp.uid)
 +                              WHERE  ms.sectorid = {?} $where
 +                           GROUP BY  a2
 +                           ORDER BY  pays", $sect, $ssect);
          $page->assign('list', $it);
      }
  
          $table_editor->describe('text','intitulé',true);
          $table_editor->apply($page, $action, $id);
      }
 -    function handler_admin_formations(&$page, $action = 'list', $id = null) {
 +    function handler_admin_education(&$page, $action = 'list', $id = null) {
          $page->setTitle('Administration - Formations');
          $page->assign('title', 'Gestion des formations');
 -        $table_editor = new PLTableEditor('admin/formations','applis_def','id');
 -        $table_editor->add_join_table('applis_ins','aid',true);
 -        $table_editor->describe('text','intitulé',true);
 -        $table_editor->describe('url','site web',false);
 +        $table_editor = new PLTableEditor('admin/education', 'profile_education_enum', 'id');
 +        $table_editor->add_join_table('profile_education', 'eduid', true);
 +        $table_editor->add_join_table('profile_education_degree', 'eduid', true);
 +        $table_editor->describe('name', 'intitulé', true);
 +        $table_editor->describe('url', 'site web', false);
 +        $table_editor->apply($page, $action, $id);
 +    }
 +    function handler_admin_education_field(&$page, $action = 'list', $id = null) {
 +        $page->setTitle('Administration - Domaines de formation');
 +        $page->assign('title', 'Gestion des domaines de formation');
 +        $table_editor = new PLTableEditor('admin/education_field', 'profile_education_field_enum', 'id', true);
 +        $table_editor->add_join_table('profile_education', 'fieldid', true);
 +        $table_editor->describe('field', 'domaine', true);
 +        $table_editor->apply($page, $action, $id);
 +    }
 +    function handler_admin_education_degree(&$page, $action = 'list', $id = null) {
 +        $page->setTitle('Administration - Niveau de formation');
 +        $page->assign('title', 'Gestion des niveau de formation');
 +        $table_editor = new PLTableEditor('admin/education_degree', 'profile_education_degree_enum', 'id', true);
 +        $table_editor->add_join_table('profile_education_degree', 'degreeid', true);
 +        $table_editor->add_join_table('profile_education', 'degreeid', true);
 +        $table_editor->describe('degree', 'niveau', true);
 +        $table_editor->apply($page, $action, $id);
 +    }
 +    function handler_admin_education_degree_set(&$page, $action = 'list', $id = null) {
 +        $page->setTitle('Administration - Correspondances formations - niveau de formation');
 +        $page->assign('title', 'Gestion des correspondances formations - niveau de formation');
 +        $table_editor = new PLTableEditor('admin/education_degree_set', 'profile_education_degree', 'eduid', true);
 +        $table_editor->describe('eduid', 'formation', true);
 +        $table_editor->describe('degreeid', 'niveau', true);
          $table_editor->apply($page, $action, $id);
      }
      function handler_admin_sections(&$page, $action = 'list', $id = null) {
          $table_editor->describe('label', 'intitulé', true);
          $table_editor->apply($page, $action, $id);
      }
 +    function handler_admin_networking(&$page, $action = 'list', $id = null) {
 +        $page->assign('xorg_title', 'Polytechnique.org - Administration - Networking');
 +        $page->assign('title', 'Gestion des types de networking');
 +        $table_editor = new PLTableEditor('admin/networking', 'profile_networking_enum', 'network_type');
 +        $table_editor->describe('name', 'intitulé', true);
 +        $table_editor->describe('icon', 'nom de l\'icône', false);
 +        $table_editor->describe('filter', 'filtre', true);
 +        $table_editor->describe('link', 'lien web', true);
 +        $table_editor->apply($page, $action, $id);
 +    }
 +    function handler_admin_corps_enum(&$page, $action = 'list', $id = null) {
 +        $page->setTitle('Administration - Corps');
 +        $page->assign('title', 'Gestion des Corps');
 +        $table_editor = new PLTableEditor('admin/corps_enum', 'profile_corps_enum', 'id');
 +        $table_editor->describe('name', 'intitulé', true);
 +        $table_editor->describe('abbreviation', 'abbréviation', true);
 +        $table_editor->describe('still_exists', 'existe encore ?', true);
 +        $table_editor->apply($page, $action, $id);
 +    }
 +    function handler_admin_corps_rank(&$page, $action = 'list', $id = null) {
 +        $page->setTitle('Administration - Grade dans les Corps');
 +        $page->assign('title', 'Gestion des grade dans les Corps');
 +        $table_editor = new PLTableEditor('admin/corps_rank', 'profile_corps_rank_enum', 'id');
 +        $table_editor->describe('name', 'intitulé', true);
 +        $table_editor->describe('abbreviation', 'abbréviation', true);
 +        $table_editor->apply($page, $action, $id);
 +    }
      function handler_admin_medals(&$page, $action = 'list', $id = null) {
          $page->setTitle('Administration - Distinctions');
          $page->assign('title', 'Gestion des Distinctions');
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -23,24 -23,34 +23,24 @@@ class ProfileAddress extends ProfileGeo
  {
      private $bool;
      private $pub;
 -    private $tel;
  
      public function __construct()
      {
          $this->bool = new ProfileBool();
          $this->pub  = new ProfilePub();
 -        $this->tel  = new ProfileTel();
      }
  
 -    private function cleanAddress(ProfilePage &$page, array &$address, &$success)
 +    private function cleanAddress(ProfilePage &$page, $adrid, array &$address, &$success)
      {
          if (@$address['changed']) {
              $address['datemaj'] = time();
          }
          $success = true;
 -        foreach ($address['tel'] as $t=>&$tel) {
 -            if (@$tel['removed'] || !trim($tel['tel'])) {
 -                unset($address['tel'][$t]);
 -            } else {
 -                $tel['pub'] = $this->pub->value($page, 'pub', $tel['pub'], $s);
 -                $tel['tel'] = $this->tel->value($page, 'tel', $tel['tel'], $s);
 -                if (!$s) {
 -                    $tel['error'] = true;
 -                    $success = false;
 -                }
 -            }
 -            unset($tel['removed']);
 +        if (!isset($address['tel'])) {
 +            $address['tel'] = array();
          }
 +        $profiletel  = new ProfilePhones('address', $adrid);
 +        $address['tel'] = $profiletel->value($page, 'tel', $address['tel'], $s);
          $address['checked'] = $this->bool->value($page, 'checked', $address['checked'], $s);
          $address['secondaire'] = $this->bool->value($page, 'secondaire', $address['secondaire'], $s);
          $address['mail'] = $this->bool->value($page, 'mail', $address['mail'], $s);
@@@ -84,7 -94,7 +84,7 @@@
              $ls = true;
              $this->geolocAddress($adr, $s);
              $ls = ($ls && $s);
 -            $this->cleanAddress($page, $adr, $s);
 +            $this->cleanAddress($page, $key, $adr, $s);
              $ls = ($ls && $s);
              if (!trim($adr['text'])) {
                  unset($value[$key]);
  
      private function saveTel($adrid, $telid, array &$tel)
      {
 -        XDB::execute("INSERT INTO  tels (uid, adrid, telid,
 -                                         tel_type, tel_pub, tel)
 -                           VALUES  ({?}, {?}, {?},
 +        XDB::execute("INSERT INTO  profile_phones (uid, link_type, link_id, tel_id, tel_type,
 +                                              search_tel, display_tel, pub)
 +                           VALUES  ({?}, 'address', {?}, {?}, {?},
                                      {?}, {?}, {?})",
 -                    S::i('uid'), $adrid, $telid,
 -                    $tel['type'], $tel['pub'], $tel['tel']);
 +                    S::i('uid'), $adrid, $telid, $tel['type'],
 +                    format_phone_number($tel['tel']), $tel['tel'], $tel['pub']);
      }
  
      private function saveAddress($adrid, array &$address)
                                                postcode, city, cityid,
                                                country, region, regiontxt,
                                                pub, datemaj, statut,
 -                                              uid, adrid, glat, glng)
 +                                              uid, adrid, glat, glng, comment)
                             VALUES  ({?}, {?}, {?},
                                      {?}, {?}, {?},
                                      {?}, {?}, {?},
                                      {?}, FROM_UNIXTIME({?}), {?},
 -                                    {?}, {?}, {?}, {?})",
 +                                    {?}, {?}, {?}, {?}, {?})",
                       $address['adr1'], $address['adr2'], $address['adr3'],
                       $address['postcode'], $address['city'], $address['cityid'],
                       $address['country'], $address['region'], $address['regiontxt'],
                       $address['pub'], $address['datemaj'], $flags,
 -                     S::i('uid'), $adrid, $address['precise_lat'], $address['precise_lon']);
 -        foreach ($address['tel'] as $telid=>&$tel) {
 -            $this->saveTel($adrid, $telid, $tel);
 -        }
 +                     S::i('uid'), $adrid, $address['precise_lat'], $address['precise_lon'], $address['comment']);
      }
  
      public function save(ProfilePage &$page, $field, $value)
          XDB::execute("DELETE FROM  adresses
                              WHERE  uid = {?}",
                       S::i('uid'));
 -        XDB::execute("DELETE FROM  tels
 -                            WHERE  uid = {?}",
 +        XDB::execute("DELETE FROM  profile_phones
 +                            WHERE  uid = {?} AND link_type = 'address'",
                       S::i('uid'));
          foreach ($value as $adrid=>&$address) {
              $this->saveAddress($adrid, $address);
 +            $profiletel = new ProfilePhones('address', $adrid);
 +            $profiletel->saveTels('tel', $address['tel']);
          }
      }
  }
@@@ -179,8 -190,7 +179,8 @@@ class ProfileAddresses extends ProfileP
                                     FIND_IN_SET('courrier', a.statut) AS mail,
                                     FIND_IN_SET('temporaire', a.statut) AS temporary,
                                     FIND_IN_SET('active', a.statut) AS current,
 -                                   a.glat AS precise_lat, a.glng AS precise_lon
 +                                   a.glat AS precise_lat, a.glng AS precise_lon,
 +                                   a.comment
                               FROM  adresses AS a
                         INNER JOIN  geoloc_pays AS gp ON(gp.a2 = a.country)
                              WHERE  uid = {?} AND NOT FIND_IN_SET('pro', statut)
              $this->values['addresses'] = $res->fetchAllAssoc();
          }
  
 -        $res = XDB::iterator("SELECT  adrid, tel_type AS type, tel_pub AS pub, tel
 -                                FROM  tels
 -                               WHERE  uid = {?}
 -                            ORDER BY  adrid",
 +        $res = XDB::iterator("SELECT  link_id AS adrid, tel_type AS type, pub, display_tel AS tel, comment
 +                                FROM  profile_phones
 +                               WHERE  uid = {?} AND link_type = 'address'
 +                            ORDER BY  link_id",
                               S::i('uid'));
          $i = 0;
          $adrNb = count($this->values['addresses']);
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -64,170 -64,28 +64,170 @@@ class ProfileNom implements ProfileSett
      }
  }
  
 -class ProfileAppli implements ProfileSetting
 +class ProfileEdu implements ProfileSetting
  {
 +    public function __construct(){}
 +
 +    static function sortByGradYear($line1, $line2) {
 +        $a = (int) $line1['grad_year'];
 +        $b = (int) $line2['grad_year'];
 +        if ($a == $b) {
 +            return 0;
 +        }
 +        return ($a < $b) ? -1 : 1;
 +    }
 +
      public function value(ProfilePage &$page, $field, $value, &$success)
      {
          $success = true;
 +        if (is_null($value) || !is_array($value)) {
 +            $value = array();
 +            $res = XDB::iterator("SELECT  eduid, degreeid, fieldid, grad_year, program
 +                                    FROM  profile_education
 +                                   WHERE  uid = {?} AND !FIND_IN_SET('primary', flags)
 +                                ORDER BY  id",
 +                                 S::v('uid'));
 +            while($edu = $res->next()) {
 +                $value[] = $edu;
 +            }
 +        } else {
 +            $i = 0;
 +            foreach ($value as $key=>&$edu) {
 +                if (($edu['grad_year'] < 1921) || ($edu['grad_year'] > (date('Y') + 4))) {
 +                    Platal::page()->trigError('L\'année d\'obtention du diplôme est mal renseignée, elle doit être du type : 2004.');
 +                    $edu['error'] = true;
 +                    $success = false;
 +                }
 +                if ($key != $i) {
 +                    $value[$i] = $edu;
 +                    unset($value[$key]);
 +                }
 +                $i++;
 +            }
 +            usort($value, array("ProfileEdu", "sortByGradYear"));
 +        }
 +        return $value;
 +    }
 +
 +    public function save(ProfilePage &$page, $field, $value)
 +    {
 +        XDB::execute("DELETE FROM  profile_education
 +                            WHERE  uid = {?} AND !FIND_IN_SET('primary', flags)",
 +                     S::i('uid'));
 +        foreach ($value as $eduid=>&$edu) {
 +            if ($edu['eduid'] != '') {
 +                XDB::execute("INSERT INTO  profile_education
 +                                      SET  id = {?}, uid = {?}, eduid = {?}, degreeid = {?},
 +                                           fieldid = {?}, grad_year = {?}, program = {?}",
 +                             $eduid, S::i('uid'), $edu['eduid'], $edu['degreeid'],
 +                             $edu['fieldid'], $edu['grad_year'], $edu['program']);
 +            }
 +        }
 +    }
 +}
 +
 +class ProfileEmailDirectory implements ProfileSetting
 +{
 +    public function __construct(){}
 +    public function save(ProfilePage &$page, $field, $value){}
 +
 +    public function value(ProfilePage &$page, $field, $value, &$success)
 +    {
 +        $p = Platal::page();
 +
 +        $success = true;
 +        if (!is_null($value)) {
 +            $email_stripped = strtolower(trim($value));
 +            if ((!isvalid_email($email_stripped)) && ($email_stripped) && ($page->values['email_directory'] == "new@example.org")) {
 +                $p->assign('email_error', '1');
 +                $p->assign('email_directory_error', $email_stripped);
 +                $p->trigError('Adresse Email invalide');
 +                $success = false;
 +            } else {
 +                $p->assign('email_error', '0');
 +            }
 +        }
 +        return $value;
 +    }
 +}
 +
 +class ProfileNetworking implements ProfileSetting
 +{
 +    private $email;
 +    private $pub;
 +    private $web;
 +    private $number;
 +
 +    public function __construct()
 +    {
 +        $this->email  = new ProfileEmail();
 +        $this->pub    = new ProfilePub();
 +        $this->web    = new ProfileWeb();
 +        $this->number = new ProfileNumber();
 +    }
 +
 +    public function value(ProfilePage &$page, $field, $value, &$success)
 +    {
          if (is_null($value)) {
 -            return $page->values[$field];
 +            $value = array();
 +            $res = XDB::iterator("SELECT  n.address, n.network_type AS type, n.pub, m.name
 +                                    FROM  profile_networking AS n
 +                              INNER JOIN  profile_networking_enum AS m ON (n.network_type = m.network_type)
 +                                   WHERE  n.uid = {?}",
 +                                 S::i('uid'));
 +            while($network = $res->next()) {
 +                $value[] = $network;
 +            }
 +        }
 +        if (!is_array($value)) {
 +            $value = array();
 +        }
 +        $res = XDB::iterator("SELECT  filter, network_type AS type
 +                                FROM  profile_networking_enum;");
 +        $filters = array();
 +        while($filter = $res->next()) {
 +            $filters[$filter['type']] = $filter['filter'];
 +        }
 +        $success = true;
 +        foreach($value as $i=>&$network) {
 +            if (!trim($network['address'])) {
 +                unset($value[$i]);
 +            } else {
 +                if (!isset($network['pub'])) {
 +                    $network['pub'] = 'private';
 +                }
 +                $network['error'] = false;
 +                $network['pub'] = $this->pub->value($page, 'pub', $network['pub'], $s);
 +                $s = true;
 +                if ($filters[$network['type']] == 'web') {
 +                    $network['address'] = $this->web->value($page, 'address', $network['address'], $s);
 +                } elseif ($filters[$network['type']] == 'email') {
 +                    $network['address'] = $this->email->value($page, 'address', $network['address'], $s);
 +                } elseif ($filters[$network['type']] == 'number') {
 +                    $network['address'] = $this->number->value($page, 'address', $network['address'], $s);
 +                }
 +                if (!$s) {
 +                    $success = false;
 +                    $network['error'] = true;
 +                }
 +            }
          }
          return $value;
      }
  
 -    public function save(ProfilePage &$page, $field, $new_value)
 +    public function save(ProfilePage &$page, $field, $value)
      {
 -        $index = ($field == 'appli1' ? 0 : 1);
 -        if ($new_value['id'] > 0) {
 -            XDB::execute("REPLACE INTO  applis_ins
 -                                   SET  uid = {?}, aid = {?}, type = {?}, ordre = {?}",
 -                         S::i('uid'), $new_value['id'], $new_value['type'], $index);
 -        } else {
 -            XDB::execute("DELETE FROM  applis_ins
 -                                WHERE  uid = {?} AND ordre = {?}",
 -                         S::i('uid'), $index);
 +        XDB::execute("DELETE FROM profile_networking
 +                            WHERE uid = {?}",
 +                     S::i('uid'));
 +        if (!count($value)) {
 +            return;
 +        }
 +        $insert = array();
 +        foreach ($value as $id=>$network) {
 +            XDB::execute("INSERT INTO  profile_networking (uid, nwid, network_type, address, pub)
 +                               VALUES  ({?}, {?}, {?}, {?}, {?})",
 +                         S::i('uid'), $id, $network['type'], $network['address'], $network['pub']);
          }
      }
  }
@@@ -239,56 -97,56 +239,56 @@@ class ProfileGeneral extends ProfilePag
      public function __construct(PlWizard &$wiz)
      {
          parent::__construct($wiz);
 -        $this->settings['nom'] = $this->settings['prenom']
 -                               = new ProfileNom();
          $this->settings['naissance'] = new ProfileDate();
 -        $this->settings['mobile_pub']
 -                                  = $this->settings['web_pub']
 -                                  = $this->settings['freetext_pub']
 +        $this->settings['freetext_pub']
                                    = $this->settings['photo_pub']
                                    = new ProfilePub();
          $this->settings['freetext']
                                    = $this->settings['nationalite']
 +                                  = $this->settings['nationalite2']
 +                                  = $this->settings['nationalite3']
                                    = $this->settings['nick']
 +                                  = $this->settings['yourself']
 +                                  = $this->settings['display_name']
 +                                  = $this->settings['sort_name']
 +                                  = $this->settings['tooltip_name']
 +                                  = $this->settings['promo_display']
 +                                  = $this->settings['search_names']
                                    = null;
          $this->settings['synchro_ax']
                                    = new ProfileBool();
 -        $this->settings['mobile'] = new ProfileTel();
 -        $this->settings['web'] = new ProfileWeb();
 -        $this->settings['appli1']
 -                                  = $this->settings['appli2']
 -                                  = new ProfileAppli();
 -        $this->watched= array('nom' => true, 'freetext' => true, 'mobile' => true, 'web' => true,
 -                       'appli1' => true, 'appli2' => true, 'nationalite' => true, 'nick' => true);
 +        $this->settings['email_directory']
 +                                  = new ProfileEmail();
 +        $this->settings['email_directory_new']
 +                                  = new ProfileEmailDirectory();
 +        $this->settings['networking'] = new ProfileNetworking();
 +        $this->settings['tels']   = new ProfilePhones('user', 0);
 +        $this->settings['edus']   = new ProfileEdu();
 +        $this->watched= array('freetext' => true, 'tels' => true,
 +                              'networking' => true, 'edus' => true,
 +                              'nationalite' => true, 'nationalite2' => true,
 +                              'nationalite3' => true);
      }
  
      protected function _fetchData()
      {
          // Checkout all data...
 -        $res = XDB::query("SELECT  u.promo, u.promo_sortie, u.nom_usage, u.nationalite, u.naissance,
 -                                   q.profile_mobile as mobile, q.profile_mobile_pub as mobile_pub,
 -                                   q.profile_web as web, q.profile_web_pub as web_pub,
 +        $res = XDB::query("SELECT  p.promo AS promo_display, e.entry_year AS entry_year, e.grad_year AS grad_year,
 +                                   u.nationalite, u.nationalite2, u.nationalite3, u.naissance,
 +                                   t.display_tel as mobile, t.pub as mobile_pub,
 +                                   d.email_directory as email_directory,
                                     q.profile_freetext as freetext, q.profile_freetext_pub as freetext_pub,
 -                                   q.profile_nick as nick, q.profile_from_ax as synchro_ax, u.matricule_ax,
 -                                   IF(a1.aid IS NULL, -1, a1.aid) as appli_id1, a1.type as appli_type1,
 -                                   IF(a2.aid IS NULL, -1, a2.aid) as appli_id2, a2.type as appli_type2
 -                             FROM  auth_user_md5   AS u
 -                       INNER JOIN  auth_user_quick AS q  USING(user_id)
 -                        LEFT JOIN  applis_ins      AS a1 ON(a1.uid = u.user_id and a1.ordre = 0)
 -                        LEFT JOIN  applis_ins      AS a2 ON(a2.uid = u.user_id and a2.ordre = 1)
 +                                   q.profile_from_ax as synchro_ax, u.matricule_ax,
 +                                   p.public_name, p.private_name, p.yourself
 +                             FROM  auth_user_md5         AS u
 +                       INNER JOIN  auth_user_quick       AS q ON (u.user_id = q.user_id)
 +                       INNER JOIN  profile_display       AS p ON (p.pid = u.user_id)
 +                       INNER JOIN  profile_education     AS e ON (e.uid = u.user_id AND FIND_IN_SET('primary', e.flags))
 +                        LEFT JOIN  profile_phones        AS t ON (u.user_id = t.uid AND link_type = 'user')
 +                        LEFT JOIN  profile_directory     AS d ON (d.uid = u.user_id)
                              WHERE  u.user_id = {?}", S::v('uid', -1));
          $this->values = $res->fetchOneAssoc();
  
 -        // Reformat formation data
 -        $this->values['appli1'] = array('id'    => $this->values['appli_id1'],
 -                                        'type'  => $this->values['appli_type1']);
 -        unset($this->values['appli_id1']);
 -        unset($this->values['appli_type1']);
 -        $this->values['appli2'] = array('id'    => $this->values['appli_id2'],
 -                                        'type'  => $this->values['appli_type2']);
 -        unset($this->values['appli_id2']);
 -        unset($this->values['appli_type2']);
 -
          // Retreive photo informations
          $res = XDB::query("SELECT  pub
                               FROM  photo
                              WHERE  type='photo' AND user_id = {?}",
                            S::v('uid'));
          $this->values['nouvellephoto'] = $res->fetchOneCell();
 +
 +        // Retreive search names info
 +        $sn_all = XDB::iterator("SELECT  IF(sn.particle = '', sn.name, CONCAT(sn.particle, ' ', sn.name)) AS name,
 +                                         sn.particle, sn.typeid, e.name AS type,
 +                                         FIND_IN_SET('has_particle', e.flags) AS has_particle,
 +                                         FIND_IN_SET('always_displayed', e.flags) AS always_displayed,
 +                                         FIND_IN_SET('public', e.flags) AS pub
 +                                   FROM  profile_name_search      AS sn
 +                             INNER JOIN  profile_name_search_enum AS e  ON (e.id = sn.typeid)
 +                                  WHERE  sn.pid = {?} AND NOT FIND_IN_SET('not_displayed', e.flags)
 +                               ORDER BY  NOT FIND_IN_SET('always_displayed', e.flags), e.id, sn.name",
 +                                S::v('uid'));
 +
 +        $sn_types = XDB::iterator("SELECT  id, name, FIND_IN_SET('has_particle', flags) AS has_particle
 +                                     FROM  profile_name_search_enum
 +                                    WHERE  NOT FIND_IN_SET('not_displayed', flags)
 +                                           AND FIND_IN_SET('always_displayed', flags)
 +                                 ORDER BY  id");
 +
 +        $this->values['search_names'] = array();
 +        $sn = $sn_all->next();
 +        while ($sn_type = $sn_types->next()) {
 +            if ($sn_type['id'] == $sn['typeid']) {
 +                $this->values['search_names'][] = $sn;
 +                $sn = $sn_all->next();
 +            } else {
 +                $this->values['search_names'][] = array('typeid' => $sn_type['id'],
 +                                                        'type'   => $sn_type['name'],
 +                                                        'pub'    => 1,
 +                                                        'has_particle'     => $sn_type['has_particle'],
 +                                                        'always_displayed' => 1);
 +            }
 +        }
 +        do {
 +            $this->values['search_names'][] = $sn;
 +        } while ($sn = $sn_all->next());
 +
 +        // Proposes choice for promo_display
 +        if ($this->values['entry_year'] != $this->values['grad_year'] - 3) {
 +            for ($i = $this->values['entry_year']; $i < $this->values['grad_year'] - 2; $i++) {
 +                $this->values['promo_choice'][] = "X" . $i;
 +            }
 +        }
      }
  
      protected function _saveData()
      {
 -        if ($this->changed['nationalite'] || $this->changed['nom'] || $this->changed['prenom']
 +        if ($this->changed['nationalite'] || $this->changed['nationalite2'] || $this->changed['nationalite3']
              || $this->changed['naissance']) {
 -           XDB::execute("UPDATE  auth_user_md5
 -                            SET  nationalite = {?}, nom={?}, prenom={?}, naissance={?}
 -                          WHERE  user_id = {?}",
 -                         $this->values['nationalite'], $this->values['nom'], $this->values['prenom'],
 +            if ($this->values['nationalite3'] == "") {
 +                $this->values['nationalite3'] = NULL;
 +            }
 +            if ($this->values['nationalite2'] == "") {
 +                $this->values['nationalite2'] = $this->values['nationalite3'];
 +                $this->values['nationalite3'] = NULL;
 +            }
 +            if ($this->values['nationalite'] == "") {
 +                $this->values['nationalite']  = $this->values['nationalite2'];
 +                $this->values['nationalite2'] = $this->values['nationalite3'];
 +                $this->values['nationalite3'] = NULL;
 +            }
 +
 +            XDB::execute("UPDATE  auth_user_md5
 +                             SET  nationalite = {?}, nationalite2 = {?}, nationalite3 = {?}, naissance={?}
 +                           WHERE  user_id = {?}",
 +                         $this->values['nationalite'], $this->values['nationalite2'], $this->values['nationalite3'],
                           preg_replace('@(\d{2})/(\d{2})/(\d{4})@', '\3-\2-\1', $this->values['naissance']),
                           S::v('uid'));
          }
 -        if ($this->changed['nick'] || $this->changed['mobile'] || $this->changed['mobile_pub']
 -            || $this->changed['web'] || $this->changed['web_pub'] || $this->changed['freetext']
 -            || $this->changed['freetext_pub'] || $this->changed['synchro_ax']) {
 +        if ($this->changed['freetext'] || $this->changed['freetext_pub'] || $this->changed['synchro_ax']) {
              XDB::execute("UPDATE  auth_user_quick
 -                             SET  profile_nick= {?}, profile_mobile={?}, profile_mobile_pub={?}, 
 -                                  profile_web={?}, profile_web_pub={?}, profile_freetext={?}, 
 -                                  profile_freetext_pub={?}, profile_from_ax = {?} 
 -                           WHERE  user_id = {?}", 
 -                         $this->values['nick'], $this->values['mobile'], $this->values['mobile_pub'],
 -                         $this->values['web'], $this->values['web_pub'],
 +                             SET  profile_freetext={?}, profile_freetext_pub={?}, profile_from_ax = {?}
 +                           WHERE  user_id = {?}",
                           $this->values['freetext'], $this->values['freetext_pub'],
                           $this->values['synchro_ax'], S::v('uid'));
          }
 -        if ($this->changed['nick']) {
 -            require_once('user.func.inc.php');
 -            user_reindex(S::v('uid'));
 +        if ($this->changed['email_directory']) {
 +            $new_email = ($this->values['email_directory'] == "new@example.org") ?
 +                $this->values['email_directory_new'] : $this->values['email_directory'];
 +            if ($new_email == "") {
 +                $new_email = NULL;
 +            }
 +            XDB::execute("REPLACE INTO  profile_directory (uid, email_directory)
 +                                VALUES  ({?}, {?})",
 +                         S::v('uid'), $new_email);
          }
          if ($this->changed['photo_pub']) {
              XDB::execute("UPDATE  photo
                             WHERE  uid = {?}",
                           $this->values['photo_pub'], S::v('uid'));
          }
 +
 +       if ($this->changed['yourself'] || $this->changed['search_names']) {
 +            if ($this->changed['search_names']) {
 +                XDB::execute("DELETE FROM  s
 +                                    USING  profile_name_search      AS s
 +                               INNER JOIN  profile_name_search_enum AS e ON (s.typeid = e.id)
 +                                    WHERE  s.pid = {?} AND NOT FIND_IN_SET('not_displayed', e.flags)",
 +                             S::i('uid'));
 +                $search_names = array();
 +                foreach ($this->values['search_names'] as $sn) {
 +                    if ($sn['name'] != '') {
 +                        if ($sn['particle']) {
 +                            list($particle, $name) = explode(' ', $sn['name'], 2);
 +                            if (!$name) {
 +                                list($particle, $name) = explode('\'', $sn['name'], 2);
 +                            }
 +                        } else {
 +                            $particle = '';
 +                            $name     = $sn['name'];
 +                        }
 +                        $particle   = trim($particle);
 +                        $name       = trim($name);
 +                        $sn['name'] = trim($sn['name']);
 +                        XDB::execute("INSERT INTO  profile_name_search (particle, name, typeid, pid)
 +                                           VALUES  ({?}, {?}, {?}, {?})",
 +                                     $particle, $name, $sn['typeid'], S::i('uid'));
 +                        if (!isset($search_names[$sn['typeid']])) {
 +                            $search_names[$sn['typeid']] = array($sn['name'], $name);
 +                        } else {
 +                            $search_names[$sn['typeid']] = array_merge($search_names[$sn['typeid']], array($name));
 +                        }
 +                    }
 +                }
 +
 +                require_once 'name.func.inc.php';
 +                $sn_types_public  = build_types('public');
 +                $sn_types_private = build_types('private');
 +                $full_name      = build_full_name($search_names, $sn_types_public);
 +                $directory_name = build_directory_name($search_names, $sn_types_public, $full_name);
 +                $short_name     = short_name($search_names, $sn_types_public);
 +                $sort_name      = short_name($search_names, $sn_types_public);
 +                $this->values['public_name']  = build_public_name($search_names, $sn_types_public, $full_name);
 +                $this->values['private_name'] = $public_name . build_private_name($search_names, $sn_types_private);
 +                XDB::execute("UPDATE  profile_display
 +                                 SET  yourself = {?}, public_name = {?}, private_name = {?},
 +                                      directory_name = {?}, short_name = {?}, sort_name = {?}
 +                               WHERE  pid = {?}",
 +                             $this->values['yourself'], $this->values['public_name'],
 +                             $this->values['private_name'], $directory_name, $short_name,
 +                             $sort_name, S::v('uid'));
 +                /*if ($this->changed['search_names']) {
 +                    require_once('user.func.inc.php');
 +                    user_reindex(S::v('uid'));
 +                }*/
 +            } else {
 +                XDB::execute("UPDATE  profile_display
 +                                 SET  yourself = {?}
 +                               WHERE  pid = {?}",
 +                             $this->values['yourself'], S::v('uid'));
 +            }
 +        }
 +        if ($this->changed['promo_display']) {
 +            XDB::execute("UPDATE  profile_display
 +                             SET  promo = {?}
 +                           WHERE  pid = {?}",
 +                         $this->values['promo_display'], S::v('uid'));
 +        }
      }
  
      public function _prepare(PlPage &$page, $id)
      {
 -        require_once "applis.func.inc.php";
 +        require_once "education.func.inc.php";
 +
 +        $res = XDB::iterator("SELECT  id, field
 +                                FROM  profile_education_field_enum
 +                            ORDER BY  field");
 +        $page->assign('edu_fields', $res->fetchAllAssoc());
 +
 +        require_once "emails.combobox.inc.php";
 +        fill_email_combobox($page);
 +
 +        $res = XDB::iterator("SELECT  nw.network_type AS type, nw.name
 +                                FROM  profile_networking_enum AS nw
 +                            ORDER BY  name");
 +        $page->assign('network_list', $res->fetchAllAssoc());
      }
  }
  
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
  class ProfileJob extends ProfileGeoloc
  {
      private $pub;
 +    private $mail_new;
      private $mail;
      private $web;
 -    private $tel;
      private $bool;
      private $checks;
  
      public function __construct()
      {
 -        $this->pub  = new ProfilePub();
 -        $this->mail = new ProfileEmail();
 -        $this->web  = new ProfileWeb();
 -        $this->tel  = new ProfileTel();
 -        $this->bool = new ProfileBool();
 -        $this->checks = array('web' => array('web'),
 -                              'mail' => array('email'),
 -                              'tel' => array('tel', 'fax', 'mobile'),
 -                              'pub' => array('pub', 'tel_pub', 'email_pub'));
 +        $this->pub    = new ProfilePub();
 +        $this->mail
 +                      = $this->mail_new
 +                      = new ProfileEmail();
 +        $this->web    = new ProfileWeb();
 +        $this->bool   = new ProfileBool();
 +        $this->checks = array('web'      => array('w_web'),
 +                              'mail_new' => array('w_email_new'),
 +                              'mail'     => array('w_email'),
 +                              'pub'      => array('pub', 'w_email_pub'));
      }
  
 -    private function cleanJob(ProfilePage &$page, array &$job, &$success)
 +    private function cleanJob(ProfilePage &$page, $jobid, array &$job, &$success)
      {
          $success = true;
          foreach ($this->checks as $obj=>&$fields) {
              $chk =& $this->$obj;
              foreach ($fields as $field) {
 +                if ($field == "w_email_new") {
 +                    if ($job['w_email'] == "new@example.org") {
 +                        $job['w_email'] = $job[$field];
 +                    }
 +                    continue;
 +                }
                  $job[$field] = $chk->value($page, $field, $job[$field], $s);
                  if (!$s) {
                      $success = false;
                  }
              }
          }
 -        $job['adr']['pub'] = $this->pub->value($page, 'adr_pub', @$job['adr']['pub'], $s);
 -        $job['adr']['checked'] = $this->bool->value($page, 'adr_checked', @$job['adr']['checked'], $s);
 +        if (!$job['sss_secteur_name']) {
 +            $res = XDB::query("SELECT  name
 +                                 FROM  profile_job_subsubsector_enum
 +                                WHERE  id = {?}",
 +                              $job['sss_secteur']);
 +            $job['sss_secteur_name'] = $res->fetchOneCell();
 +        } else {
 +            $res = XDB::query("SELECT  sectorid, subsectorid, id
 +                                 FROM  profile_job_subsubsector_enum
 +                                WHERE  name = {?}",
 +                              $job['sss_secteur_name']);
 +            if ($res->numRows() != 1) {
 +                $success = false;
 +                $job['sector_error'] = true;
 +            } else {
 +                list($job['secteur'], $job['ss_secteur'], $job['sss_secteur']) = $res->fetchOneRow();
 +            }
 +        }
 +        if ($job['name']) {
 +            $res = XDB::query("SELECT  id
 +                                 FROM  profile_job_enum
 +                                WHERE  name = {?}",
 +                              $job['name']);
 +            if ($res->numRows() != 1) {
 +                $user = S::user();
 +                $req = new EntrReq($user, $jobid, $job['name'], $job['acronym'], $job['hq_web'], $job['hq_email'], $job['hq_tel'], $job['hq_fax']);
 +                $req->submit();
 +                $job['jobid'] = null;
 +            } else {
 +                $job['jobid'] = $res->fetchOneCell();
 +            }
 +        }
 +        $job['w_adr']['pub'] = $this->pub->value($page, 'adr_pub', @$job['w_adr']['pub'], $s);
 +        $job['w_adr']['checked'] = $this->bool->value($page, 'adr_checked', @$job['w_adr']['checked'], $s);
 +        if (!isset($job['w_tel'])) {
 +            $job['w_tel'] = array();
 +        }
 +        $profiletel = new ProfilePhones('pro', $jobid);
 +        $job['w_tel'] = $profiletel->value($page, 'tel', $job['w_tel'], $s);
          unset($job['removed']);
          unset($job['new']);
 -        unset($job['adr']['changed']);
 -        unset($job['adr']['parsevalid']);
 -        unset($job['adr']['display']);
 +        unset($job['w_adr']['changed']);
 +        unset($job['w_adr']['parsevalid']);
 +        unset($job['w_adr']['display']);
      }
  
      public function value(ProfilePage &$page, $field, $value, &$success)
      {
 +        require_once('validations.inc.php');
 +        $entreprise = Validate::get_typed_requests(S::i('uid'), 'entreprise');
 +        $entr_val = 0;
 +
          $init = false;
          if (is_null($value)) {
              $value = $page->values['jobs'];
          }
          $success = true;
          foreach ($value as $key=>&$job) {
 -            if (@$job['removed'] || !trim($job['name'])) {
 +            $job['name'] = trim($job['name']);
 +            if (!$job['name']) {
 +                $job['tmp_name'] = $entreprise[$entr_val]->name;
 +                $entr_val ++;
 +            }
 +            if (@$job['removed']) {
                  unset($value[$key]);
              }
          }
          foreach ($value as $key=>&$job) {
              $ls = true;
 -            $this->geolocAddress($job['adr'], $s);
 +            $this->geolocAddress($job['w_adr'], $s);
              $ls = ($ls && $s);
 -            $this->cleanJob($page, $job, $s);
 +            $this->cleanJob($page, $key, $job, $s);
              $ls = ($ls && $s);
              if (!$init) {
                  $success = ($success && $ls);
  
      public function save(ProfilePage &$page, $field, $value)
      {
 -        XDB::execute("DELETE FROM  entreprises
 +        require_once('profil.func.inc.php');
 +        require_once('validations.inc.php');
 +
 +        XDB::execute("DELETE FROM  profile_job
                              WHERE  uid = {?}",
                       S::i('uid'));
 -        $i = 0;
 -        foreach ($value as &$job) {
 -            XDB::execute("INSERT INTO  entreprises (uid, entrid, entreprise, secteur, ss_secteur,
 -                                                    fonction, poste, adr1, adr2, adr3, postcode,
 -                                                    city, cityid, country, region, regiontxt,
 -                                                    tel, fax, mobile, email, web,
 -                                                    pub, adr_pub, tel_pub, email_pub, flags,
 -                                                    glat, glng)
 -                               VALUES  ({?}, {?}, {?}, {?}, {?},
 -                                        {?}, {?}, {?}, {?}, {?}, {?},
 -                                        {?}, {?}, {?}, {?}, {?},
 -                                        {?}, {?}, {?}, {?}, {?},
 -                                        {?}, {?}, {?}, {?}, {?},
 -                                        {?}, {?})",
 -                         S::i('uid'), $i++, $job['name'], $job['secteur'], $job['ss_secteur'],
 -                         $job['fonction'], $job['poste'], $job['adr']['adr1'], $job['adr']['adr2'], $job['adr']['adr3'],
 -                         $job['adr']['postcode'],
 -                         $job['adr']['city'], $job['adr']['cityid'], $job['adr']['country'], $job['adr']['region'], 
 -                         $job['adr']['regiontxt'],
 -                         $job['tel'], $job['fax'], $job['mobile'], $job['email'], $job['web'],
 -                         $job['pub'], $job['adr']['pub'], $job['tel_pub'], $job['email_pub'],
 -                         $job['adr']['checked'] ? 'geoloc' : '', $job['adr']['precise_lat'],
 -                         $job['adr']['precise_lon']);
 +        XDB::execute("DELETE FROM  profile_phones
 +                            WHERE  uid = {?} AND link_type = 'pro'",
 +                     S::i('uid'));
 +        foreach ($value as $id=>&$job) {
 +            if ($job['w_email'] == "new@example.org") {
 +                $job['w_email'] = $job['w_email_new'];
 +            }
 +            if ($job['jobid']) {
 +                XDB::execute("INSERT INTO  profile_job (uid, id, functionid, description, sectorid, subsectorid,
 +                                                        subsubsectorid, email, url, pub, email_pub, jobid)
 +                                   VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
 +                             S::i('uid'), $id, $job['fonction'], $job['description'], $job['secteur'], $job['ss_secteur'],
 +                             $job['sss_secteur'], $job['w_email'], $job['w_web'], $job['pub'], $job['w_email_pub'], $job['jobid']);
 +            } else {
 +                XDB::execute("INSERT INTO  profile_job (uid, id, functionid, description, sectorid, subsectorid,
 +                                                        subsubsectorid, email, url, pub, email_pub)
 +                                   VALUES  ({?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?})",
 +                             S::i('uid'), $id, $job['fonction'], $job['description'], $job['secteur'], $job['ss_secteur'],
 +                             $job['sss_secteur'], $job['w_email'], $job['w_web'], $job['pub'], $job['w_email_pub']);
 +            }
 +            $profiletel = new ProfilePhones('pro', $id);
 +            $profiletel->saveTels('tel', $job['w_tel']);
          }
      }
  }
@@@ -184,9 -129,8 +184,9 @@@ class ProfileJobs extends ProfilePag
      {
          parent::__construct($wiz);
          $this->settings['cv'] = null;
 +        $this->settings['corps'] = null;
          $this->settings['jobs'] = new ProfileJob();
 -        $this->watched['cv'] = $this->watched['jobs'] = true;
 +        $this->watched = array('cv' => true, 'jobs' => true, 'corps' => true);
      }
  
      protected function _fetchData()
                            S::i('uid'));
          $this->values['cv'] = $res->fetchOneCell();
  
 +        // Checkout the corps
 +        $res = XDB::query("SELECT  original_corpsid AS original, current_corpsid AS current,
 +                                   rankid AS rank, corps_pub AS pub
 +                             FROM  profile_corps
 +                            WHERE  uid = {?}",
 +                          S::i('uid'));
 +        $this->values['corps'] = $res->fetchOneAssoc();
 +
          // Build the jobs tree
 -        $res = XDB::iterRow("SELECT  e.entreprise, e.secteur, e.ss_secteur,
 -                                     e.fonction, e.poste, e.adr1, e.adr2, e.adr3,
 +        $res = XDB::iterRow("SELECT  j.id, je.name, j.functionid, j.sectorid, j.subsectorid,
 +                                     j.subsubsectorid, j.description, e.adr1, e.adr2, e.adr3,
                                       e.postcode, e.city, e.cityid, e.region, e.regiontxt,
                                       e.country, gp.pays, gp.display,
                                       FIND_IN_SET('geoloc', flags),
 -                                     e.tel, e.fax, e.mobile, e.email, e.web, e.pub,
 -                                     e.adr_pub, e.tel_pub, e.email_pub,
 -                                     e.glat AS precise_lat, e.glng AS precise_lon
 -                               FROM  entreprises AS e
 -                          LEFT JOIN  geoloc_pays AS gp ON(gp.a2 = e.country)
 -                              WHERE  uid = {?} AND entreprise != ''
 +                                     j.email, j.url, j.pub,
 +                                     e.adr_pub, j.email_pub,
 +                                     e.glat, e.glng, s.name
 +                               FROM  profile_job                   AS j
 +                          LEFT JOIN  profile_job_enum              AS je ON (j.jobid = je.id)
 +                          LEFT JOIN  entreprises                   AS e  ON (j.uid = e.uid AND j.id = e.entrid)
 +                          LEFT JOIN  geoloc_pays                   AS gp ON (gp.a2 = e.country)
 +                          LEFT JOIN  profile_job_subsubsector_enum AS s  ON (s.id = j.subsubsectorid)
 +                              WHERE  j.uid = {?}
                             ORDER BY  entrid", S::i('uid'));
          $this->values['jobs'] = array();
 -        while (list($name, $secteur, $ss_secteur, $fonction, $poste,
 -                    $adr1, $adr2, $adr3, $postcode, $city, $cityid,
 -                    $region, $regiontxt, $country, $countrytxt, $display,
 -                    $checked, $tel, $fax, $mobile, $email, $web,
 -                    $pub, $adr_pub, $tel_pub, $email_pub, $glat, $glng) = $res->next()) {
 -            $this->values['jobs'][] = array('name'       => $name,
 -                                            'secteur'    => $secteur,
 -                                            'ss_secteur' => $ss_secteur,
 -                                            'fonction'   => $fonction,
 -                                            'poste'      => $poste,
 -                                            'adr'        => array('adr1'       => $adr1,
 -                                                                  'adr2'       => $adr2,
 -                                                                  'adr3'       => $adr3,
 -                                                                  'postcode'   => $postcode,
 -                                                                  'city'       => $city,
 -                                                                  'cityid'     => $cityid,
 -                                                                  'region'     => $region,
 -                                                                  'regiontxt'  => $regiontxt,
 -                                                                  'country'    => $country,
 -                                                                  'countrytxt' => $countrytxt,
 -                                                                  'display'    => $display,
 -                                                                  'pub'        => $adr_pub,
 -                                                                  'checked'    => $checked,
 -                                                                  'precise_lat'=> $glat,
 -                                                                  'precise_lon'=> $glng),
 -                                            'tel'        => $tel,
 -                                            'fax'        => $fax,
 -                                            'mobile'     => $mobile,
 -                                            'email'      => $email,
 -                                            'web'        => $web,
 -                                            'pub'        => $pub,
 -                                            'tel_pub'    => $tel_pub,
 -                                            'email_pub'  => $email_pub);
 +        while (list($id, $name, $function, $secteur, $ss_secteur, $sss_secteur, $description,
 +                    $w_adr1, $w_adr2, $w_adr3, $w_postcode, $w_city, $w_cityid,
 +                    $w_region, $w_regiontxt, $w_country, $w_countrytxt, $w_display,
 +                    $w_checked, $w_email, $w_web,
 +                    $pub, $w_adr_pub, $w_email_pub, $w_glat, $w_glng, $sss_secteur_name
 +                   ) = $res->next()) {
 +            $this->values['jobs'][] = array('id'               => $id,
 +                                            'name'             => $name,
 +                                            'fonction'         => $function,
 +                                            'secteur'          => $secteur,
 +                                            'ss_secteur'       => $ss_secteur,
 +                                            'sss_secteur'      => $sss_secteur,
 +                                            'sss_secteur_name' => $sss_secteur_name,
 +                                            'description'      => $description,
 +                                            'w_adr'            => array('adr1'        => $w_adr1,
 +                                                                        'adr2'        => $w_adr2,
 +                                                                        'adr3'        => $w_adr3,
 +                                                                        'postcode'    => $w_postcode,
 +                                                                        'city'        => $w_city,
 +                                                                        'cityid'      => $w_cityid,
 +                                                                        'region'      => $w_region,
 +                                                                        'regiontxt'   => $w_regiontxt,
 +                                                                        'country'     => $w_country,
 +                                                                        'countrytxt'  => $w_countrytxt,
 +                                                                        'display'     => $w_display,
 +                                                                        'pub'         => $w_adr_pub,
 +                                                                        'checked'     => $w_checked,
 +                                                                        'precise_lat' => $w_glat,
 +                                                                        'precise_lon' => $w_glng),
 +                                            'w_email'          => $w_email,
 +                                            'w_web'            => $w_web,
 +                                            'pub'              => $pub,
 +                                            'w_email_pub'      => $w_email_pub);
 +        }
 +
 +        $res = XDB::iterator("SELECT  link_id AS jobid, tel_type AS type, pub, display_tel AS tel, comment
 +                                FROM  profile_phones
 +                               WHERE  uid = {?} AND link_type = 'pro'
 +                            ORDER BY  link_id",
 +                             S::i('uid'));
 +        $i = 0;
 +        $jobNb = count($this->values['jobs']);
 +        while ($tel = $res->next()) {
 +            $jobid = $tel['jobid'];
 +            unset($tel['jobid']);
 +            while ($i < $jobNb && $this->values['jobs'][$i]['id'] < $jobid) {
 +                $i++;
 +            }
 +            if ($i >= $jobNb) {
 +                break;
 +            }
 +            $job =& $this->values['jobs'][$i];
 +            if (!isset($job['w_tel'])) {
 +                $job['w_tel'] = array();
 +            }
 +            if ($job['id'] == $jobid) {
 +                $job['w_tel'][] = $tel;
 +            }
 +        }
 +        foreach ($this->values['jobs'] as $id=>&$job) {
 +            if (!isset($job['w_tel'])) {
 +                $job['w_tel'] = array();
 +            }
 +            unset($job['id']);
          }
      }
  
                             WHERE  user_id = {?}",
                           $this->values['cv'], S::i('uid'));
          }
 +
 +        if ($this->changed['corps']) {
 +            XDB::execute("UPDATE  profile_corps
 +                             SET  original_corpsid = {?}, current_corpsid = {?},
 +                                  rankid = {?}, corps_pub = {?}
 +                           WHERE  uid = {?}",
 +                          $this->values['corps']['original'], $this->values['corps']['current'],
 +                          $this->values['corps']['rank'], $this->values['corps']['pub'], S::i('uid'));
 +        }
      }
  
      public function _prepare(PlPage &$page, $id)
      {
 -        $res = XDB::query("SELECT  id, label
 -                             FROM  emploi_secteur");
 +        require_once "emails.combobox.inc.php";
 +        fill_email_combobox($page);
 +
 +        $res = XDB::query("SELECT  id, name AS label
 +                             FROM  profile_job_sector_enum");
          $page->assign('secteurs', $res->fetchAllAssoc());
          $res = XDB::query("SELECT  id, fonction_fr, FIND_IN_SET('titre', flags) AS title
                               FROM  fonctions_def
                           ORDER BY  id");
          $page->assign('fonctions', $res->fetchAllAssoc());
 +
 +        $res = XDB::iterator("SELECT  id, name
 +                                FROM  profile_corps_enum
 +                            ORDER BY  id = 1 DESC, name");
 +        $page->assign('original_corps', $res->fetchAllAssoc());
 +
 +        $res = XDB::iterator("SELECT  id, name
 +                                FROM  profile_corps_enum
 +                               WHERE  still_exists = 1
 +                            ORDER BY  id = 1 DESC, name");
 +        $page->assign('current_corps', $res->fetchAllAssoc());
 +
 +        $res = XDB::iterator("SELECT  id, name
 +                                FROM  profile_corps_rank_enum");
 +        $page->assign('corps_rank', $res->fetchAllAssoc());
      }
  }
  
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -26,10 -26,10 +26,10 @@@ class ProfileSecteurs implements Profil
          $success = true;
          if (is_null($value)) {
              $value = array();
 -            $res = XDB::iterRow("SELECT  m.secteur, m.ss_secteur, ss.label
 -                                   FROM  mentor_secteurs AS m
 -                             INNER JOIN  emploi_secteur  AS s ON(m.secteur = s.id)
 -                             INNER JOIN  emploi_ss_secteur AS ss ON(s.id = ss.secteur AND m.ss_secteur = ss.id)
 +            $res = XDB::iterRow("SELECT  m.sectorid, m.subsectorid, ss.name
 +                                   FROM  profile_mentor_sector      AS m
 +                             INNER JOIN  profile_job_sector_enum    AS s  ON (m.sectorid = s.id)
 +                             INNER JOIN  profile_job_subsector_enum AS ss ON (s.id = ss.sectorid AND m.subsectorid = ss.id)
                                    WHERE  m.uid = {?}",
                                  S::i('uid'));
              while (list($s, $ss, $ssname) = $res->next()) {
@@@ -42,7 -42,7 +42,7 @@@
          } else if (!is_array($value)) {
              $value = array();
          } else if (count($value) > 10) {
 -            Platal::page()->trigError("Le nombre de secteurs d'expertise est limité à 10");
 +            Platal::page()->trigError("Le nombre de secteurs d'expertise est limité à 10.");
              $success = false;
          }
          ksort($value);
@@@ -55,7 -55,7 +55,7 @@@
      public function save(ProfilePage &$page, $field, $value)
      {
  
 -        XDB::execute("DELETE FROM  mentor_secteurs
 +        XDB::execute("DELETE FROM  profile_mentor_sector
                              WHERE  uid = {?}",
                       S::i('uid'));
          if (!count($value)) {
@@@ -63,7 -63,7 +63,7 @@@
          }
          foreach ($value as $id=>&$sect) {
              foreach ($sect as $sid=>&$name) {
 -                XDB::execute("INSERT INTO  mentor_secteurs (uid, secteur, ss_secteur)
 +                XDB::execute("INSERT INTO  profile_mentor_sector (uid, sectorid, subsectorid)
                                     VALUES  ({?}, {?}, {?})",
                               S::i('uid'), $id, $sid);
              }
@@@ -78,9 -78,9 +78,9 @@@ class ProfileCountry implements Profile
          $success = true;
          if (is_null($value)) {
              $value = array();
 -            $res = XDB::iterRow("SELECT  m.pid, p.pays
 -                                   FROM  mentor_pays AS m
 -                             INNER JOIN  geoloc_pays AS p ON(m.pid = p.a2)
 +            $res = XDB::iterRow("SELECT  m.country, p.pays
 +                                   FROM  profile_mentor_country AS m
 +                             INNER JOIN  geoloc_pays            AS p ON (m.country = p.a2)
                                    WHERE  m.uid = {?}",
                                  S::i('uid'));
              while (list($id, $name) = $res->next()) {
  
      public function save(ProfilePage &$page, $field, $value)
      {
 -        XDB::execute("DELETE FROM  mentor_pays
 +        XDB::execute("DELETE FROM  profile_mentor_country
                              WHERE  uid = {?}",
                       S::i('uid'));
          foreach ($value as $id=>&$name) {
 -            XDB::execute("INSERT INTO  mentor_pays (uid, pid)
 +            XDB::execute("INSERT INTO  profile_mentor_country (uid, country)
                                 VALUES  ({?}, {?})",
                           S::i('uid'), $id);
          }
@@@ -151,8 -151,8 +151,8 @@@ class ProfileMentor extends ProfilePag
  
      public function _prepare(PlPage &$page, $id)
      {
 -        $page->assign('secteurs_sel', XDB::iterator("SELECT  id, label
 -                                                       FROM  emploi_secteur"));
 +        $page->assign('secteurs_sel', XDB::iterator("SELECT  id, name AS label
 +                                                       FROM  profile_job_sector_enum"));
      }
  }
  
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -76,22 -76,6 +76,22 @@@ class ProfileEmail extends ProfileNoSav
      }
  }
  
 +class ProfileNumber extends ProfileNoSave
 +{
 +    public function value(ProfilePage &$page, $field, $value, &$success)
 +    {
 +        if (is_null($value)) {
 +            return isset($page->values[$field]) ? $page->values[$field] : S::v($field);
 +        }
 +        $value = trim($value);
 +        $success = empty($value) || is_numeric($value);
 +        if (!$success) {
 +            Platal::page()->trigError('Numéro invalide');
 +        }
 +        return $value;
 +    }
 +}
 +
  
  class ProfileTel extends ProfileNoSave
  {
          if (is_null($value)) {
              return isset($page->values[$field]) ? $page->values[$field] : S::v($field);
          }
 -        $success = !preg_match('/[<>{}@&#~\/:;?,!§*_`\[\]|%$^=]/', $value, $matches);
 +        require_once('profil.func.inc.php');
 +        $value = format_phone_number($value);
 +        if($value == '') {
 +            $success = true;
 +            return $value;
 +        }
 +        $value = format_display_number($value,$error);
 +        $success = !$error;
          if (!$success) {
 -            Platal::page()->trigError('Le numéro de téléphone contient un caractère interdit : ' . pl_entities($matches[0][0]));
 +            Platal::page()->trigError('Le préfixe international du numéro de téléphone est inconnu. ');
 +        }
 +        return $value;
 +    }
 +}
 +
 +class ProfilePhones implements ProfileSetting
 +{
 +    private $tel;
 +    private $pub;
 +    protected $id;
 +    protected $link_type;
 +    protected $link_id;
 +
 +    public function __construct($type, $link_id, $id = 0)
 +    {
 +        if ($id != 0) {
 +            $this->id = $id;
 +        } else {
 +            $this->id = S::i('uid');
 +        }
 +        $this->tel = new ProfileTel();
 +        $this->pub = new ProfilePub();
 +        $this->link_type = $type;
 +        $this->link_id   = $link_id;
 +    }
 +
 +    public function value(ProfilePage &$page, $field, $value, &$success)
 +    {
 +        $success = true;
 +        if (is_null($value) || !is_array($value)) {
 +            $value = array();
 +            $res = XDB::iterator("SELECT  t.display_tel AS tel, t.tel_type AS type, t.pub, t.comment
 +                                    FROM  profile_phones AS t
 +                                   WHERE  t.uid = {?} AND t.link_type = {?}
 +                                ORDER BY  t.tel_id",
 +                                 $this->id, $this->link_type);
 +            $value = $res->fetchAllAssoc();
 +        }
 +        foreach ($value as $key=>&$phone) {
 +            if (@$phone['removed']) {
 +                unset($value[$key]);
 +            } else {
 +                unset($phone['removed']);
 +                $phone['pub'] = $this->pub->value($page, 'pub', $phone['pub'], $s);
 +                $phone['tel'] = $this->tel->value($page, 'tel', $phone['tel'], $s);
 +                if(!isset($phone['type']) || ($phone['type'] != 'fixed' && $phone['type'] != 'mobile' && $phone['type'] != 'fax')) {
 +                    $phone['type'] = 'fixed';
 +                    $s = false;
 +                }
 +                if (!$s) {
 +                    $phone['error'] = true;
 +                    $success = false;
 +                }
 +                if (!isset($phone['comment'])) {
 +                    $phone['comment'] = '';
 +                }
 +            }
          }
          return $value;
      }
 +
 +    private function saveTel($telid, array &$phone)
 +    {
 +        if ($phone['tel'] != '') {
 +            XDB::execute("INSERT INTO  profile_phones (uid, link_type, link_id, tel_id, tel_type,
 +                                       search_tel, display_tel, pub, comment)
 +                               VALUES  ({?}, {?}, {?}, {?}, {?},
 +                                       {?}, {?}, {?}, {?})",
 +                         $this->id, $this->link_type, $this->link_id, $telid, $phone['type'],
 +                         format_phone_number($phone['tel']), $phone['tel'], $phone['pub'], $phone['comment']);
 +        }
 +    }
 +
 +    public function save(ProfilePage &$page, $field, $value)
 +    {
 +        XDB::execute("DELETE FROM  profile_phones
 +                            WHERE  uid = {?} AND link_type = {?} AND link_id = {?}",
 +                            $this->id, $this->link_type, $this->link_id);
 +        $this->saveTels($field, $value);
 +    }
 +
 +    //Only saves phones without a delete operation
 +    public function saveTels($field, $value)
 +    {
 +        foreach ($value as $telid=>&$phone) {
 +            $this->saveTel($telid, $phone);
 +        }
 +    }
  }
  
  class ProfilePub extends ProfileNoSave
diff --combined modules/search.php
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -24,11 -24,11 +24,11 @@@ class SearchModule extends PLModul
      function handlers()
      {
          return array(
 -            'search'     => $this->make_hook('quick', AUTH_PUBLIC),
 -            'search/adv' => $this->make_hook('advanced', AUTH_COOKIE),
 +            'search'              => $this->make_hook('quick',          AUTH_PUBLIC),
 +            'search/adv'          => $this->make_hook('advanced',       AUTH_COOKIE),
              'advanced_search.php' => $this->make_hook('redir_advanced', AUTH_PUBLIC),
 -            'search/autocomplete' => $this->make_hook('autocomplete', AUTH_COOKIE, 'user', NO_AUTH),
 -            'search/list' => $this->make_hook('list', AUTH_COOKIE, 'user', NO_AUTH),
 +            'search/autocomplete' => $this->make_hook('autocomplete',   AUTH_COOKIE, 'user', NO_AUTH),
 +            'search/list'         => $this->make_hook('list',           AUTH_COOKIE, 'user', NO_AUTH),
          );
      }
  
              $school = Env::i('school');
          }
  
 -        if (!is_null($school)) {
 -            $sql = 'SELECT type FROM applis_def WHERE id=' . $school;
 +        if ((!is_null($school)) && ($school != '')) {
 +            $sql = 'SELECT  degreeid
 +                      FROM  profile_education_degree
 +                     WHERE  eduid=' . $school;
          } else {
 -            $sql = 'DESCRIBE applis_def type';
 +            $sql = 'SELECT  id
 +                      FROM  profile_education_degree_enum
 +                  ORDER BY  id';
          }
  
          $res = XDB::query($sql);
 -        $row = $res->fetchOneRow();
 -        if (!is_null($school)) {
 -            $types = $row[0];
 -        } else {
 -            $types = explode('(',$row[1]);
 -            $types = str_replace("'","",substr($types[1],0,-1));
 -        }
 -        Platal::page()->assign('choix_diplomas', explode(',',$types));
 +        Platal::page()->assign('choix_diplomas', $res->fetchColumn());
 +
 +        $sql = 'SELECT  degree
 +                  FROM  profile_education_degree_enum
 +              ORDER BY  id';
 +        $res = XDB::query($sql);
 +        Platal::page()->assign('name_diplomas', $res->fetchColumn());
      }
  
      function handler_quick(&$page, $action = null, $subaction = null)
              $this->form_prepare();
          } else {
              $textFields = array(
 -                'country' => array('field' => 'a2', 'table' => 'geoloc_pays', 'text' => 'pays', 'exact' => false),
 -                'fonction' => array('field' => 'id', 'table' => 'fonctions_def', 'text' => 'fonction_fr', 'exact' => true),
 -                'secteur' => array('field' => 'id', 'table' => 'emploi_secteur', 'text' => 'label', 'exact' => false),
 -                'nationalite' => array('field' => 'a2', 'table' => 'geoloc_pays', 'text' => 'nat', 'exact' => 'false'),
 -                'binet' => array('field' => 'id', 'table' => 'binets_def', 'text' => 'text', 'exact' => false),
 -                'groupex' => array('field' => 'id', 'table' => 'groupex.asso',
 -                                   'text' => "(cat = 'GroupesX' OR cat = 'Institutions') AND pub = 'public' AND nom",
 -                                   'exact' => false),
 -                'section' => array('field' => 'id', 'table' => 'sections', 'text' => 'text', 'exact' => false),
 -                'school' => array('field' => 'id', 'table' => 'applis_def', 'text' => 'text', 'exact' => false),
 -                'city' => array('table' => 'geoloc_city', 'text' => 'name', 'exact' => false)
 +                'country'         => array('field' => 'a2', 'table' => 'geoloc_pays', 'text' => 'pays', 'exact' => false),
 +                'fonction'        => array('field' => 'id', 'table' => 'fonctions_def', 'text' => 'fonction_fr', 'exact' => true),
 +                'secteur'         => array('field' => 'id', 'table' => 'profile_job_sector_enum', 'text' => 'name', 'exact' => false),
 +                'nationalite'     => array('field' => 'a2', 'table' => 'geoloc_pays', 'text' => 'nat', 'exact' => 'false'),
 +                'binet'           => array('field' => 'id', 'table' => 'binets_def', 'text' => 'text', 'exact' => false),
 +                'networking_type' => array('field' => 'network_type', 'table' => 'profile_networking_enum',
 +                                           'text' => 'name', 'exact' => false),
 +                'groupex'         => array('field' => 'id', 'table' => 'groupex.asso',
 +                                           'text' => "(cat = 'GroupesX' OR cat = 'Institutions') AND pub = 'public' AND nom",
 +                                           'exact' => false),
 +                'section'         => array('field' => 'id', 'table' => 'sections', 'text' => 'text', 'exact' => false),
 +                'school'          => array('field' => 'id', 'table' => 'profile_education_enum', 'text' => 'name', 'exact' => false),
 +                'city'            => array('table' => 'geoloc_city', 'text' => 'name', 'exact' => false)
              );
              if (!Env::has('page')) {
                  S::logger()->log('search', 'adv=' . var_export($_GET, true));
          $beginwith = true;
          $field2 = false;
          $qsearch = str_replace(array('%', '_'), '', $q);
 +        $distinct = true;
  
          switch ($type) {
            case 'binetTxt':
              $db = '`binets_def` INNER JOIN
                     `binets_ins` ON(`binets_def`.`id` = `binets_ins`.`binet_id`)';
 -            $field='`binets_def`.`text`';
 +            $field = '`binets_def`.`text`';
              if (strlen($q) > 2)
                  $beginwith = false;
              $realid = '`binets_def`.`id`';
              break;
 +          case 'networking_typeTxt':
 +            $db = '`profile_networking_enum` INNER JOIN
 +                   `profile_networking` ON(`profile_networking`.`network_type` = `profile_networking_enum`.`network_type`)';
 +            $field = '`profile_networking_enum`.`name`';
 +            $unique = 'uid';
 +            $realid = '`profile_networking_enum`.`network_type`';
 +            break;
            case 'city':
              $db = '`geoloc_city` INNER JOIN
                     `adresses` ON(`geoloc_city`.`id` = `adresses`.`cityid`)';
            case 'countryTxt':
              $db = '`geoloc_pays` INNER JOIN
                     `adresses` ON(`geoloc_pays`.`a2` = `adresses`.`country`)';
 -            $unique='`uid`';
 +            $unique = '`uid`';
              $field = '`geoloc_pays`.`pays`';
              $field2 = '`geoloc_pays`.`country`';
 -            $realid='`geoloc_pays`.`a2`';
 +            $realid = '`geoloc_pays`.`a2`';
              break;
            case 'entreprise':
 -            $db = '`entreprises`';
 -            $field = '`entreprise`';
 -            $unique='`uid`';
 +            $db     = 'profile_job_enum INNER JOIN
 +                       profile_job ON (profile_job.jobid = profile_job_enum.id)';
 +            $field  = 'profile_job_enum.name';
 +            $unique = 'profile_job.uid';
              break;
            case 'firstname':
              $field = '`prenom`';
              $beginwith = false;
              break;
            case 'fonctionTxt':
 -            $db = '`fonctions_def` INNER JOIN
 -                   `entreprises` ON(`entreprises`.`fonction` = `fonctions_def`.`id`)';
 -            $field = '`fonction_fr`';
 -            $unique = '`uid`';
 -            $realid = '`fonctions_def`.`id`';
 +            $db        = 'fonctions_def INNER JOIN
 +                          profile_job ON (profile_job.fonctionid = fonctions_def.id)';
 +            $field     = 'fonction_fr';
 +            $unique    = 'uid';
 +            $realid    = 'fonctions_def.id';
              $beginwith = false;
              break;
            case 'groupexTxt':
              break;
            case 'nationaliteTxt':
              $db = '`geoloc_pays` INNER JOIN
 -                   `auth_user_md5` ON(`geoloc_pays`.`a2` = `auth_user_md5`.`nationalite`)';
 +                   `auth_user_md5` ON (`geoloc_pays`.`a2` = `auth_user_md5`.`nationalite` OR
 +                                       `geoloc_pays`.`a2` = `auth_user_md5`.`nationalite2` OR
 +                                       `geoloc_pays`.`a2` = `auth_user_md5`.`nationalite3`)';
              $field = 'IF(`geoloc_pays`.`nat`=\'\',
                                         `geoloc_pays`.`pays`,
                                         `geoloc_pays`.`nat`)';
              $db = '`auth_user_quick`';
              $beginwith = false;
              break;
 -          case 'poste':
 -            $db = '`entreprises`';
 -            $field = '`poste`';
 -            $unique='`uid`';
 +          case 'description':
 +            $db     = 'profile_job';
 +            $field  = 'description';
 +            $unique = 'uid';
              break;
            case 'schoolTxt':
 -            $db = '`applis_def` INNER JOIN
 -                   `applis_ins` ON(`applis_def`.`id` = `applis_ins`.`aid`)';
 -            $field='`applis_def`.`text`';
 -            $unique = '`uid`';
 -            $realid = '`applis_def`.`id`';
 +            $db = 'profile_education_enum INNER JOIN
 +                   profile_education ON (profile_education_enum.id = profile_education.eduid)';
 +            $field = 'profile_education_enum.name';
 +            $unique = 'uid';
 +            $realid = 'profile_education_enum.id';
              if (strlen($q) > 2)
                  $beginwith = false;
              break;
            case 'secteurTxt':
 -            $db = '`emploi_secteur` INNER JOIN
 -                   `entreprises` ON(`entreprises`.`secteur` = `emploi_secteur`.`id`)';
 -            $field = '`emploi_secteur`.`label`';
 -            $realid = '`emploi_secteur`.`id`';
 -            $unique = '`uid`';
 +            $db        = 'profile_job_sector_enum INNER JOIN
 +                          profile_job ON (profile_job.sectorid = profile_job_sector_enum.id)';
 +            $field     = 'profile_job_sector_enum.name';
 +            $realid    = 'profile_job_sector_enum.id';
 +            $unique    = 'uid';
 +            $beginwith = false;
 +            break;
 +          case 'sss_secteur':
 +            $db        = 'profile_job_subsubsector_enum';
 +            $field     = 'name';
              $beginwith = false;
 +            $unique    = 'name';
 +            $distinct  = false;
              break;
            case 'sectionTxt':
              $db = '`sections` INNER JOIN
              $field2_t = make_field_test($field2, $beginwith);
              $field_select = 'IF(' . $field_t . ', ' . $field . ', ' . $field2. ')';
          }
 -        $list = XDB::iterator('SELECT  ' . $field_select . ' AS field,
 -                                       COUNT(DISTINCT ' . $unique . ') AS nb
 -                                       . ($realid ? (', ' . $realid . ' AS id') : '') . '
 +        $list = XDB::iterator('SELECT  ' . $field_select . ' AS field'
 +                                       . ($distinct ? (', COUNT(DISTINCT ' . $unique . ') AS nb') : '')
 +                                       . ($realid ? (', ' . $realid . ' AS id') : '') . '
                                   FROM  ' . $db . '
                                  WHERE  ' . $field_t .
                                          ($field2 ? (' OR ' . $field2_t) : '') . '
                               GROUP BY  ' . $field_select . '
 -                             ORDER BY  nb DESC
 +                             ORDER BY  ' . ($distinct ? 'nb DESC' : $field_select) . '
                                  LIMIT  11',
                                 $qsearch, $qsearch, $qsearch, $qsearch, $qsearch, $qsearch, $qsearch, $qsearch,
                                 $qsearch, $qsearch, $qsearch, $qsearch, $qsearch, $qsearch, $qsearch, $qsearch);
 +
          $nbResults = 0;
          $res = "";
          while ($result = $list->next()) {
                  $res .= $q."|-1\n";
              } else {
                  $res .= $result['field'].'|';
 -                $res .= $result['nb'];
 +                if (isset($result['nb'])) {
 +                    $res .= $result['nb'];
 +                }
                  if (isset($result['id'])) {
                      $res  .= '|'.$result['id'];
                  }
            case 'binet':
              $db = '`binets_def`';
              break;
 +          case 'networking_type':
 +            $db = '`profile_networking_enum`';
 +            $field = '`name`';
 +            $id = '`network_type`';
 +            break;
            case 'country':
              $db = '`geoloc_pays`';
              $field = '`pays`';
              break;
            case 'nationalite':
              $db = '`geoloc_pays` INNER JOIN
 -                   `auth_user_md5` ON (`geoloc_pays`.`a2` = `auth_user_md5`.`nationalite`)';
 +                   `auth_user_md5` ON (`geoloc_pays`.`a2` = `auth_user_md5`.`nationalite` OR
 +                                       `geoloc_pays`.`a2` = `auth_user_md5`.`nationalite2` OR
 +                                       `geoloc_pays`.`a2` = `auth_user_md5`.`nationalite3`)';
              $field = 'IF(`nat`=\'\', `pays`, `nat`)';
              $id = '`a2`';
              break;
              }
              break;
            case 'school':
 -            $db = '`applis_def`';
 +            $db = 'profile_education_enum';
 +            $field = 'name';
 +            $id = 'id';
              $page->assign('onchange', 'changeSchool(this.value)');
              break;
            case 'section':
              $db = '`sections`';
              break;
            case 'secteur':
 -            $db = '`emploi_secteur`';
 -            $field = '`label`';
 +            $db    = 'profile_job_sector_enum INNER JOIN
 +                      profile_job ON (profile_job.sectorid = profile_job_sector_enum.id)';
 +            $field = 'profile_job_sector_enum.name';
 +            $id    = 'profile_job_sector_enum.id';
              break;
            default: exit();
          }
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
      u.perms IN (\'admin\',\'user\', \'disabled\') AS inscrit,
      u.perms != \'pending\' AS wasinscrit,
      FIND_IN_SET(\'femme\', u.flags) AS sexe,
 -    a.alias AS forlife,
 -    ad0.text AS app0text, ad0.url AS app0url, ai0.type AS app0type,
 -    ad1.text AS app1text, ad1.url AS app1url, ai1.type AS app1type,
 -    es.label AS secteur, ef.fonction_fr AS fonction,
 -    IF(n.nat=\'\',n.pays,n.nat) AS nat, n.a2 AS iso3166,
 +    ede0.name AS eduname0, ede0.url AS eduurl0, edd0.degree AS edudegree0,
 +    edu0.grad_year AS edugrad_year0, f0.field AS edufield0, edu0.program AS eduprogram0,
 +    ede1.name AS eduname1, ede1.url AS eduurl1, edd1.degree AS edudegree1,
 +    edu1.grad_year AS edugrad_year1, f1.field AS edufield1, edu1.program AS eduprogram1,
 +    ede2.name AS eduname2, ede2.url AS eduurl2, edd2.degree AS edudegree2,
 +    edu2.grad_year AS edugrad_year2, f2.field AS edufield2, edu2.program AS eduprogram2,
 +    ede3.name AS eduname3, ede3.url AS eduurl3, edd3.degree AS edudegree3,
 +    edu3.grad_year AS edugrad_year3, f3.field AS edufield3, edu3.program AS eduprogram3,
 +    es.name AS secteur, ef.fonction_fr AS fonction,
 +    IF(n1.nat=\'\',n1.pays,n1.nat) AS nat1, n1.a2 AS iso3166_1,
 +    IF(n2.nat=\'\',n2.pays,n2.nat) AS nat2, n2.a2 AS iso3166_2,
 +    IF(n3.nat=\'\',n3.pays,n3.nat) AS nat3, n3.a2 AS iso3166_3,
      (COUNT(em.email) > 0 OR FIND_IN_SET("googleapps", u.mail_storage) > 0) AS actif,';
  // hide private information if not logged
  if (S::logged())
      $globals->search->result_fields .='
 -        q.profile_web AS web,
 -        q.profile_mobile AS mobile,
          q.profile_freetext AS freetext,
          adr.city, gp.pays AS countrytxt, gr.name AS region,
 -        e.entreprise,';
 +        ee.name,
 +        nw.address AS networking_address,
 +        nwe.name AS networking_name,';
  else
      $globals->search->result_fields .="
 -    IF(q.profile_web_pub='public', q.profile_web, '') AS web,
 -        IF(q.profile_mobile_pub='public', q.profile_mobile, '') AS mobile,
          IF(q.profile_freetext_pub='public', q.profile_freetext, '') AS freetext,
 -        IF(adr.pub='public', adr.city, '') AS city,
 -        IF(adr.pub='public', gp.pays, '') AS countrytxt,
 -        IF(adr.pub='public', gr.name, '') AS region,
 -        IF(e.pub='public', e.entreprise, '') AS entreprise,";
 +        IF(adr.pub='public', adr.city, '')   AS city,
 +        IF(adr.pub='public', gp.pays, '')    AS countrytxt,
 +        IF(adr.pub='public', gr.name, '')    AS region,
 +        IF(e.pub='public', je.name, '')      AS entreprise,
 +        IF(nw.pub='public', nw.address, '')  AS networking_address,
 +        IF(nw.pub='public', nwe.name, '')    AS networking_name,";
  @$globals->search->result_where_statement = '
 -    LEFT JOIN  applis_ins     AS ai0 ON (u.user_id = ai0.uid AND ai0.ordre = 0)
 -    LEFT JOIN  applis_def     AS ad0 ON (ad0.id = ai0.aid)
 -    LEFT JOIN  applis_ins     AS ai1 ON (u.user_id = ai1.uid AND ai1.ordre = 1)
 -    LEFT JOIN  applis_def     AS ad1 ON (ad1.id = ai1.aid)
 -    LEFT JOIN  entreprises    AS e   ON (e.entrid = 0 AND e.uid = u.user_id)
 -    LEFT JOIN  emploi_secteur AS es  ON (e.secteur = es.id)
 -    LEFT JOIN  fonctions_def  AS ef  ON (e.fonction = ef.id)
 -    LEFT JOIN  geoloc_pays    AS n   ON (u.nationalite = n.a2)
 -    LEFT JOIN  adresses       AS adr ON (u.user_id = adr.uid AND FIND_IN_SET(\'active\',adr.statut))
 -    LEFT JOIN  geoloc_pays    AS gp  ON (adr.country = gp.a2)
 -    LEFT JOIN  geoloc_region  AS gr  ON (adr.country = gr.a2 AND adr.region = gr.region)
 -    LEFT JOIN  emails         AS em  ON (em.uid = u.user_id AND em.flags = \'active\')';
 +    LEFT JOIN  profile_education             AS edu0 ON (u.user_id = edu0.uid AND edu0.id = 0)
 +    LEFT JOIN  profile_education_enum        AS ede0 ON (ede0.id = edu0.eduid)
 +    LEFT JOIN  profile_education_degree_enum AS edd0 ON (edd0.id = edu0.degreeid)
 +    LEFT JOIN  profile_education_field_enum  AS f0   ON (f0.id = edu0.fieldid)
 +    LEFT JOIN  profile_education             AS edu1 ON (u.user_id = edu1.uid AND edu1.id = 1)
 +    LEFT JOIN  profile_education_enum        AS ede1 ON (ede1.id = edu1.eduid)
 +    LEFT JOIN  profile_education_degree_enum AS edd1 ON (edd1.id = edu1.degreeid)
 +    LEFT JOIN  profile_education_field_enum  AS f1   ON (f1.id = edu1.fieldid)
 +    LEFT JOIN  profile_education             AS edu2 ON (u.user_id = edu2.uid AND edu2.id = 2)
 +    LEFT JOIN  profile_education_enum        AS ede2 ON (ede2.id = edu2.eduid)
 +    LEFT JOIN  profile_education_degree_enum AS edd2 ON (edd2.id = edu2.degreeid)
 +    LEFT JOIN  profile_education_field_enum  AS f2   ON (f2.id = edu2.fieldid)
 +    LEFT JOIN  profile_education             AS edu3 ON (u.user_id = edu3.uid AND edu3.id = 3)
 +    LEFT JOIN  profile_education_enum        AS ede3 ON (ede3.id = edu3.eduid)
 +    LEFT JOIN  profile_education_degree_enum AS edd3 ON (edd3.id = edu3.degreeid)
 +    LEFT JOIN  profile_education_field_enum  AS f3   ON (f3.id = edu3.fieldid)
 +    LEFT JOIN  profile_job                   AS e    ON (e.uid = u.user_id)
 +    LEFT JOIN  profile_job_enum              AS ee   ON (e.jobid = ee.id)
 +    LEFT JOIN  profile_job_sector_enum       AS es   ON (es.id = e.sectorid)
 +    LEFT JOIN  fonctions_def                 AS ef   ON (e.fonction = ef.id)
 +    LEFT JOIN  geoloc_pays                   AS n1   ON (u.nationalite = n1.a2)
 +    LEFT JOIN  geoloc_pays                   AS n2   ON (u.nationalite2 = n2.a2)
 +    LEFT JOIN  geoloc_pays                   AS n3   ON (u.nationalite3 = n3.a2)
 +    LEFT JOIN  adresses                      AS adr  ON (u.user_id = adr.uid AND FIND_IN_SET(\'active\',adr.statut))
 +    LEFT JOIN  geoloc_pays                   AS gp   ON (adr.country = gp.a2)
 +    LEFT JOIN  geoloc_region                 AS gr   ON (adr.country = gr.a2 AND adr.region = gr.region)
 +    LEFT JOIN  emails                        AS em   ON (em.uid = u.user_id AND em.flags = \'active\')
 +    LEFT JOIN  profile_networking            AS nw   ON (nw.uid = u.user_id)
 +    LEFT JOIN  profile_networking_enum       AS nwe  ON (nwe.network_type = nw.network_type)';
  
  // }}}
  // {{{ class ThrowError
@@@ -233,8 -209,6 +233,8 @@@ class QuickSearch extends SFiel
      /** stores admin searches */
      var $email;
      var $ip;
 +    /** stores phone number */
 +    var $phone;
  
      // }}}
      // {{{ constructor
  
      function isempty()
      {
 -        return empty($this->strings) && empty($this->ranges) && empty($this->email) && empty($this->ip);
 +        return empty($this->strings) && empty($this->ranges) && empty($this->email) && empty($this->ip) && empty($this->phone);
      }
  
      // }}}
          foreach ($ranges as $r) {
              if (preg_match('!^([<>]\d{4}|\d{4}(-\d{4})?)$!', $r)) $this->ranges[] = $r;
          }
 +
 +        $t = preg_replace('!(\d{4}-\d{4}|>\d{4}|<\d{4})!', '', $s);
 +        $t = preg_replace('![<>\- ]!', '', $t);
 +        if (strlen($t) > 4) {
 +            $this->phone = $t;
 +        }
      }
  
      // }}}
              $ip = ip_to_uint($this->ip);
              $where[] = "( ls.ip = $ip OR ls.forward_ip = $ip ) AND ls.suid = 0";
          }
 +        if (!empty($this->phone)){
 +            require_once("profil.func.inc.php");
 +            $phone = format_phone_number($this->phone) . "%";
 +            $where[] = 't.search_tel LIKE ' . XDB::escape($phone);
 +        }
  
          return join(" AND ", $where);
      }
          if (!empty($this->ip)) {
              $join .= "INNER JOIN logger.sessions AS ls ON (ls.uid = u.user_id)\n";
          }
 +        if (!empty($this->phone)) {
 +            if (!S::logged()) {
 +                $join .= "INNER JOIN profile_phones AS t ON (t.uid = u.user_id AND t.pub = 'public')";
 +            } else {
 +                $join .= "INNER JOIN profile_phones AS t ON (t.uid = u.user_id)";
 +            }
 +        }
          return $join;
      }
      // }}}
@@@ -536,39 -492,6 +536,39 @@@ class RefSField extends SFiel
  // }}}
  
  // {{{ class RefSFieldMultipleTable
 +class PhoneSField extends RefSField
 +{
 +    function PhoneSField($_fieldFormName, $_fieldDbName='', $_refTable, $_refAlias, $_refCondition)
 +    {
 +        $this->RefSField($_fieldFormName, $_fieldDbName, $_refTable, $_refAlias, $_refCondition, true);
 +    }
 +
 +    function get_request()
 +    {
 +        require_once("profil.func.inc.php");
 +        $this->value = trim(Env::v($this->fieldFormName));
 +        $this->value = format_phone_number($this->value);
 +    }
 +
 +    function compare()
 +    {
 +        return " LIKE '" . addslashes($this->value) . "%'";
 +    }
 +}
 +
 +class IndexSField extends RefSField
 +{
 +    function IndexSField($_fieldFormName, $_fieldDbName='', $_refTable, $_refAlias, $_refCondition)
 +    {
 +        $this->RefSField($_fieldFormName, $_fieldDbName, $_refTable, $_refAlias, $_refCondition, true);
 +    }
 +
 +    function get_request()
 +    {
 +        $this->value = trim(Env::v($this->fieldFormName));
 +    }
 +}
 +
  class MapSField extends RefSField
  {
      var $mapId;
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -23,7 -23,7 +23,7 @@@ require_once dirname(__FILE__).'/classe
  
  // {{{ function advancedSearchFromInput
  function getadr_join($table) {
 -    return 'u.user_id='.$table.'.uid'.(Env::v('only_current',false)?' AND FIND_IN_SET(\'active\','.$table.'.statut)':'');
 +    return 'u.user_id = ' . $table . '.uid' . (Env::v('only_current', false) ? ' AND FIND_IN_SET(\'active\', ' . $table . '.statut)' : '');
  }
  function advancedSearchFromInput()
  {
          $nameField      = new RefWithSoundexSField('name',array('rn.nom1_soundex','rn.nom2_soundex','rn.nom3_soundex'),'recherche_soundex','rn','u.matricule = rn.matricule');
          $firstnameField = new RefWithSoundexSField('firstname',array('rp.prenom1_soundex','rp.prenom2_soundex'),'recherche_soundex','rp','u.matricule = rp.matricule');
      } else {
 -        $nameField      = new NameSField('name',array('u.nom','u.nom_usage'),'');
 -        $firstnameField = new StringSField('firstname',array('u.prenom'),'');
 +        $nameField      = new NameSField('name', array('u.nom','u.nom_usage'), '');
 +        $firstnameField = new StringSField('firstname', array('u.prenom'), '');
      }
 -    $nicknameField   = new StringSField('nickname',array('q.profile_nick'),'');
 +    $nicknameField      = new StringSField('nickname', array('q.profile_nick'), '');
  
 -    $promo1Field     = new PromoSField('promo1','egal1',array('u.promo'),'');
 -    $promo2Field     = new PromoSField('promo2','egal2',array('u.promo'),'');
 -    $womanField      = new RefSField('woman',array('FIND_IN_SET(\'femme\',u.flags)+1'),'','','');
 -    $subscriberField = new RefSField('subscriber',array('!(u.perms IN (\'admin\',\'user\'))+1'),'','','');
 -    $aliveField      = new RefSField('alive',array('(u.deces!=0)+1'),'','','');
 +    $promo1Field        = new PromoSField('promo1', 'egal1', array('u.promo'), '');
 +    $promo2Field        = new PromoSField('promo2', 'egal2', array('u.promo'), '');
 +    $womanField         = new RefSField('woman', array('FIND_IN_SET(\'femme\', u.flags) + 1'), '', '', '');
 +    $subscriberField    = new RefSField('subscriber', array('!(u.perms IN (\'admin\', \'user\')) + 1'), '', '', '');
 +    $aliveField         = new RefSField('alive', array('(u.deces != 0) + 1'), '', '', '');
      if (Env::v('only_referent') == 'on') {
 -        $referentField = new RefSField('only_referent', array('"on"'), 'mentor', 'mt', 'mt.expertise != "" AND mt.uid=u.user_id');
 +        $referentField  = new RefSField('only_referent', array('"on"'), 'mentor', 'mt', 'mt.expertise != "" AND mt.uid = u.user_id');
      } else {
 -        $referentField = null;
 +        $referentField  = null;
      }
  
      if (!Env::i('cityid')) {
 -        $townField  = new RefSField('city',array('ac.city', 'ac.postcode'),'adresses','ac',getadr_join('ac'),false);
 +        $townField      = new RefSField('city', array('ac.city', 'ac.postcode'), 'adresses', 'ac', getadr_join('ac'), false);
      } else {
 -        $townField  = new RefSField('cityid',array('av.cityid', 'av.postcode'),'adresses','av',getadr_join('av'));
 +        $townField      = new RefSField('cityid', array('av.cityid', 'av.postcode'), 'adresses', 'av', getadr_join('av'));
      }
 -    $countryField   = new RefSField('country',array('ap.country'),'adresses','ap',getadr_join('ap'));
 -    $regionField    = new RefSField('region',array('ar.region'),'adresses','ar',getadr_join('ar'));
 -    $mapField       = new MapSField('mapid', array('sgcim.map_id'), array('adresses','geoloc_city_in_maps'), array('amp','sgcim'), array(getadr_join('amp'), 'amp.cityid = sgcim.city_id'));
 +    $countryField       = new RefSField('country', array('ap.country'), 'adresses', 'ap', getadr_join('ap'));
 +    $regionField        = new RefSField('region',array('ar.region'), 'adresses', 'ar', getadr_join('ar'));
 +    $mapField           = new MapSField('mapid',  array('sgcim.map_id'), array('adresses', 'geoloc_city_in_maps'),
 +                                        array('amp', 'sgcim'), array(getadr_join('amp'), 'amp.cityid = sgcim.city_id'));
  
 -    $entrepriseField = new RefSField('entreprise',array('ee.entreprise'),'entreprises','ee','u.user_id=ee.uid',false);
 -    $posteField      = new RefSField('poste',array('ep.poste'),'entreprises','ep','u.user_id=ep.uid', false);
 -    $fonctionField = new RefSField('fonction',array('en.fonction'),'entreprises','en','u.user_id=en.uid');
 -    $secteurField    = new RefSField('secteur',array('fm.secteur'),'entreprises','fm','u.user_id=fm.uid');
 -    $cvField         = new RefSField('cv',array('u.cv'),'','','',false);
 +    $entrepriseField    = new RefSField('entreprise', array('je.name'), '', '','');
 +    $posteField         = new RefSField('poste', array('ep.description'), 'profile_job', 'ep', 'u.user_id = ep.uid', false);
 +    $fonctionField      = new RefSField('fonction', array('en.fonction_fr'), 'fonctions_def', 'en',
 +                                        'u.user_id = profile_job.uid AND fonctions_def.id = profile_job.functionid');
 +    $secteurField       = new RefSField('secteur', array('fm.sectorid'), 'profile_job', 'fm', 'u.user_id = fm.uid');
 +    $cvField            = new RefSField('cv', array('u.cv'), '', '', '', false);
  
 -    $natField        = new RefSField('nationalite',array('u.nationalite'),'','','');
 -    $binetField      = new RefSField('binet',array('b.binet_id'),'binets_ins','b','u.user_id=b.user_id');
 -    $groupexField    = new RefSField('groupex',array('g.id'),array('groupex.asso', 'groupex.membres'),array('g', 'gm'),
 -                                     array("(g.cat = 'GroupesX' OR g.cat = 'Institutions') AND g.pub = 'public'",
 -                                           'gm.asso_id = g.id AND u.user_id=gm.uid'));
 -    $sectionField    = new RefSField('section',array('u.section'),'','','');
 -    $schoolField     = new RefSField('school',array('as.aid'),'applis_ins','`as`','u.user_id=as.uid');
 -    $diplomaField    = new RefSField('diploma',array('ad.type'),'applis_ins','ad','u.user_id=ad.uid');
 +    $natField           = new RefSField('nationalite', array('u.nationalite', 'u.nationalite2', 'u.nationalite3'), '', '', '');
 +    $binetField         = new RefSField('binet', array('b.binet_id'), 'binets_ins', 'b', 'u.user_id=b.user_id');
 +    $groupexField       = new RefSField('groupex', array('g.id'), array('groupex.asso', 'groupex.membres'), array('g', 'gm'),
 +                                        array("(g.cat = 'GroupesX' OR g.cat = 'Institutions') AND g.pub = 'public'",
 +                                              'gm.asso_id = g.id AND u.user_id = gm.uid'));
 +    $sectionField       = new RefSField('section', array('u.section'), '', '', '');
 +    $schoolField        = new RefSField('school', array('edu.eduid'), 'profile_education', 'edu', 'u.user_id = edu.uid');
 +    $diplomaField       = new RefSField('diploma', array('edd.degreeid'), 'profile_education', 'edd', 'u.user_id = edd.uid');
  
 -    $freeField       = new RefSField('free',array('q.profile_freetext'),'','','',false);
 +    $freeField          = new RefSField('free', array('q.profile_freetext'), '', '', '', false);
  
 +    $nwAddressField     = new RefSField('networking_address', array('nw.address'), 'profile_networking', 'nw', 'nw.uid=u.user_id', false);
 +    if (Env::v('networking_address') == '') {
 +        $nwTypeField    = new IndexSField('networking_type', array('nwe.network_type'), array('profile_networking', 'profile_networking_enum'),
 +                                          array('nw', 'nwe'), array('nw.uid = u.user_id', 'nwe.network_type = nw.network_type'));
 +    } else {
 +        $nwTypeField    = new IndexSField('networking_type',
 +                                          array('nwe.network_type'), 'profile_networking_enum', 'nwe', 'nwe.network_type = nw.network_type');
 +    }
 +    $nwPhoneField       = new PhoneSField('phone_number', array('t.search_tel'), 'profile_phones', 't', 't.uid = u.user_id');
      return array(
                  $nameField, $firstnameField, $nicknameField, $promo1Field,
 -                $promo2Field, $womanField, $subscriberField, $aliveField, $referentField,
 +                $promo2Field, $womanField, $subscriberField, $aliveField,
                  $townField, $countryField, $regionField, $mapField, $entrepriseField,
                  $posteField, $secteurField, $cvField, $natField, $binetField,
                  $groupexField, $sectionField, $schoolField, $diplomaField,
 -                $freeField, $fonctionField);
 +                $freeField, $fonctionField, $nwAddressField, $nwTypeField,
 +                $nwPhoneField, $referentField);
  }
  
  // }}}
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
@@@ -40,9 -40,12 +40,9 @@@ function smarty_function_display_addres
  {
      require_once('geoloc.inc.php');
      $txtad = get_address_text($param['adr']);
 -    if (!$txtad &&
 -        !$param['adr']['tels'] && !count($param['adr']['tels']) &&
 -        !$param['adr']['tel'] &&
 -        !$param['adr']['fax'] &&
 -        !$param['adr']['mobile']) return "";
 -
 +    if (!$txtad && !$param['adr']['tels'] && !count($param['adr']['tels'])) {
 +        return "";
 +    }
  
      $lines = explode("\n", $txtad);
      $idt   = array_shift($lines);
      $map = "<a href=\"http://maps.google.fr/?q="
          .   urlencode(implode(", ", $lines) . " ($idt)")
          . "\"><img src=\"images/icons/map.gif\" alt=\"Google Maps\" title=\"Carte\"/></a>";
 +    $comment = "";
 +    if ($param['adr']['comment'] != "")
 +    {
 +        $commentHtml = str_replace(array('&', '"'), array('&amp;', '&quot;'), $param['adr']['comment']);
 +        $commentJs = str_replace(array('\\', '\''), array('\\\\', '\\\''), $commentHtml);
 +        $comment = "<img style=\"margin-left: 5px;\" src=\"images/icons/comments.gif\""
 +            . " onmouseover=\"return overlib('"
 +            . $commentJs
 +            . "',WIDTH,250);\""
 +            . " onmouseout=\"nd();\""
 +            . " alt=\"Commentaire\" title=\""
 +            . $commentHtml
 +            . "\"/>";
 +    }
      if ($restore) {
          array_unshift($lines, $idt);
      }
      if ($param['titre'])
      {
          if ($param['titre_div'])
 -            $txthtml .= "<div class='titre'>".pl_entity_decode($param['titre'])."&nbsp;".$map."</div>\n";
 +            $txthtml .= "<div class='titre'>".pl_entity_decode($param['titre'])."&nbsp;".$map.$comment."</div>\n";
          else
 -            $txthtml .= "<em>".pl_entity_decode($param['titre'])."&nbsp;</em>".$map."<br />\n";
 +            $txthtml .= "<em>".pl_entity_decode($param['titre'])."&nbsp;</em>".$map.$comment."<br />\n";
      }
      foreach ($lines as $line)
      {
          $txthtml .= "<strong>".$line."</strong><br/>\n";
      }
 -    if ($param['adr']['tel'])
 -        $txthtml .= "<div>\n<em>Tél : </em>\n<strong>".$param['adr']['tel']."</strong>\n</div>\n";
 -    if ($param['adr']['fax'])
 -        $txthtml .= "<div>\n<em>Fax : </em>\n<strong>".$param['adr']['fax']."</strong>\n</div>\n";
 -    if ($param['adr']['mobile'])
 -        $txthtml .= "<div>\n<em>Tél : </em>\n<strong>".$param['adr']['mobile']."</strong>\n</div>\n";
 -    if ($param['adr']['tels'] && count($param['adr']['tels'])) {
 -        foreach ($param['adr']['tels'] as $tel)
 -            $txthtml .= "<div>\n<em>".$tel['tel_type']."&nbsp;: </em>\n<strong>".$tel['tel']."</strong>\n</div>\n";
 +    if(isset($param['adr']['tels'])) {
 +        require_once('function.display_phones.php');
 +        $txthtml .= smarty_function_display_phones($param['adr'],$smarty);
      }
      if (!$param['nodiv']) {
          $pos = $param['pos'] ? " style='float: " . $param['pos'] . "'" : '';
index db21384,0000000..b9589b2
mode 100644,000000..100644
--- /dev/null
@@@ -1,61 -1,0 +1,61 @@@
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
 +<?php
 +/***************************************************************************
++ *  Copyright (C) 2003-2009 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                *
 + ***************************************************************************/
 +
 +function smarty_function_display_phones($param, &$smarty)
 +{
 +    $txthtml = "";
 +    if (count($param['tels'])) {
 +        foreach ($param['tels'] as $tel) {
 +            switch ($tel['tel_type']) {
 +            case 'fixed':
 +                $tel_type = 'Tél';
 +                break;
 +            case 'fax':
 +                $tel_type = 'Fax';
 +                break;
 +            case 'mobile':
 +                $tel_type = 'Mob';
 +                break;
 +            default:
 +                $tel_type = $tel['tel_type'];
 +            }
 +            $txthtml .= "<div>\n<em>" . $tel_type . "&nbsp;: </em>\n<strong>" . $tel['tel'] . "</strong>\n";
 +            $comment = "";
 +            if ($tel['comment'] != "") {
 +                $commentHtml = str_replace(array('&', '"'), array('&amp;', '&quot;'), $tel['comment']);
 +                $commentJs = str_replace(array('\\', '\''), array('\\\\', '\\\''), $commentHtml);
 +                $txthtml .= "<img style=\"margin-left: 5px;\" src=\"images/icons/comments.gif\""
 +                            . " onmouseover=\"return overlib('"
 +                            . $commentJs
 +                            . "',WIDTH,250);\""
 +                            . " onmouseout=\"nd();\""
 +                            . " alt=\"Commentaire\" title=\""
 +                            . $commentHtml
 +                            . "\"/>\n";
 +            }
 +            $txthtml .= "</div>\n";
 +        }
 +    }
 +    return $txthtml;
 +}
 +
 +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 +?>
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-  *  Copyright (C) 2003-2008 Polytechnique.org                              *
+  *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *
   ***************************************************************************/
  
  
 -function select_nat($valeur,$pad=false) {
 -    $sql = "SELECT a2 AS id,IF(nat='',pays,nat) AS text FROM geoloc_pays WHERE nat IS NOT NULL ORDER BY text";
 +function select_nat($valeur, $pad=false) {
 +    $sql = "SELECT a2 AS id, IF(nat='', pays, nat) AS text FROM geoloc_pays WHERE nat IS NOT NULL ORDER BY text";
      $res = XDB::iterRow($sql);
      $sel = ' selected="selected"';
  
      // on ajoute une entree vide si $pad est vrai
      $html = "";
      if ($pad) {
 -      $html.= '<option value="0"'.($valeur==0?$sel:"")."></option>\n";
 +            $html .= sprintf("<option value=\"\"%s></option>\n", ($valeur ? $sel : ""));
      }
 -    while (list($my_id,$my_text) = $res->next()) {
 -      $html .= sprintf("<option value=\"%s\" %s>%s</option>\n",$my_id,($valeur==$my_id?$sel:""),$my_text);
 +    while (list($my_id, $my_text) = $res->next()) {
 +        $html .= sprintf("<option value=\"%s\"%s>%s</option>\n", $my_id, ($valeur==$my_id ? $sel : ""), $my_text);
      }
 +
      return $html;
  }
  
  function smarty_function_select_nat($params, &$smarty) {
 -    if(empty($params['pad']) || !($params['pad']))
 -      $pad = false;
 -    else
 -      $pad = true;
 +    if (empty($params['pad']) || !($params['pad'])) {
 +            $pad = false;
 +    } else {
 +            $pad = true;
 +    }
 +
      return select_nat($params['valeur'], $pad);
  }
  
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  
    <tr><th colspan="2">{icon name=user_gray} Champs</th></tr>
    <tr class="impair">
 -    <td class="titre">Emploi</td>
 +    <td class="titre">Formation</td>
      <td>
 -      <a href="admin/formations">Formations</a>
 +      <a href="admin/education">Formations</a>
 +      &nbsp;&nbsp;|&nbsp;&nbsp;
 +      <a href="admin/education_field">Domaines de formation</a>
 +      &nbsp;&nbsp;|&nbsp;&nbsp;
 +      <a href="admin/education_degree">Niveau de formation</a>
        &nbsp;&nbsp;|&nbsp;&nbsp;
 +      <a href="admin/education_degree_set">Niveau par formation</a>
 +    </td>
 +  </tr>
 +  <tr class="impair">
 +    <td class="titre">Emploi</td>
 +    <td>
        <a href="admin/secteurs">Secteurs</a>
        &nbsp;&nbsp;|&nbsp;&nbsp;
        <a href="admin/ss_secteurs">Sous-secteurs</a>
        &nbsp;&nbsp;|&nbsp;&nbsp;
        <a href="admin/fonctions">Fonctions</a>
 +      &nbsp;&nbsp;|&nbsp;&nbsp;
 +      <a href="admin/networking">Networking</a>
 +      &nbsp;&nbsp;|&nbsp;&nbsp;
 +      <a href="admin/corps_enum">Corps</a>
 +      &nbsp;&nbsp;|&nbsp;&nbsp;
 +      <a href="admin/corps_rank">Grade</a>
      </td>
    </tr>
    <tr class="pair">
      </td>
    </tr>
    <tr class="pair">
-     <td class="titre">Newletter</td>
+     <td class="titre">Newsletter</td>
      <td>
        <a href="admin/newsletter">Liste</a>
        &nbsp;&nbsp;|&nbsp;&nbsp;
    <tr class="impair">
      <td class="titre">AX-Letter</td>
      <td>
-       <a href="ax/edit">Edition</a>
+       <a href="ax/edit">Édition</a>
        &nbsp;&nbsp;|&nbsp;&nbsp;
-       <a href="admin/axletter">Inscriptions et Permissions</a>
+       <a href="admin/axletter">Inscriptions et permissions</a>
      </td>
    </tr>
    <tr class="pair">
diff --combined templates/core/vcard.tpl
index 0d9cab5,0000000..fd0f95b
mode 100644,000000..100644
--- /dev/null
@@@ -1,99 -1,0 +1,99 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +{iterate from=$users item=vcard}
 +BEGIN:VCARD
 +VERSION:3.0
 +{if $vcard.nom_usage}
 +FN:{$vcard.prenom|vcard_enc} {$vcard.nom_usage|vcard_enc} ({$vcard.nom|vcard_enc})
 +{else}
 +FN:{$vcard.prenom|vcard_enc} {$vcard.nom|vcard_enc}
 +{/if}
 +N:{$vcard.nom|vcard_enc};{$vcard.prenom|vcard_enc};{$vcard.nom_usage|vcard_enc};;
 +{if $vcard.nickname}
 +NICKNAME:{$vcard.nickname|vcard_enc}
 +{/if}
 +EMAIL;TYPE=internet,pref:{$vcard.bestalias}@{#globals.mail.domain#}
 +EMAIL;TYPE=internet:{$vcard.bestalias}@{#globals.mail.domain2#}
 +{if $vcard.bestalias neq $vcard.forlife}
 +EMAIL;TYPE=internet:{$vcard.forlife}@{#globals.mail.domain#}
 +EMAIL;TYPE=internet:{$vcard.forlife}@{#globals.mail.domain2#}
 +{/if}
 +{if $vcard.virtualalias}
 +EMAIL;TYPE=internet:{$vcard.virtualalias}
 +{/if}
 +{if $vcard.tels}
 +{foreach item=tel from=$vcard.tels}
 +{if $tel.tel_type eq 'mobile'}TEL;TYPE=cell{else}{if $tel.tel_type eq 'fax'}FAX{else}TEL{/if};TYPE=home{/if}:{$tel.tel|vcard_enc}
 +{/foreach}
 +{/if}
 +{if $vcard.adr_pro}
 +{if $vcard.adr_pro[0].entreprise}
 +ORG:{$vcard.adr_pro[0].entreprise|vcard_enc}
 +{/if}
 +{if $vcard.adr_pro[0].poste}
 +TITLE:{$vcard.adr_pro[0].poste|vcard_enc}
 +{/if}
 +{if $vcard.adr_pro[0].fonction}
 +ROLE:{$vcard.adr_pro[0].fonction|vcard_enc}
 +{/if}
 +{if $vcard.adr_pro[0].tels}
 +{foreach item=tel from=$vcard.adr_pro[0].tels}
 +{if $tel.tel_type eq 'mobile'}TEL;TYPE=cell,work{else}{if $tel.tel_type eq 'fax'}FAX{else}TEL{/if};TYPE=work{/if}:{$tel.tel|vcard_enc}
 +{/foreach}
 +{/if}
 +ADR;TYPE=work:{format_adr adr=$vcard.adr_pro[0]}
 +{/if}
 +{foreach item=adr from=$vcard.adr}
 +ADR;TYPE=home{if $adr.courier},postal{/if}:{format_adr adr=$adr}
 +{if $adr.tels}
 +{foreach item=tel from=$adr.tels}
 +{if $tel.tel_type eq 'mobile'}TEL;TYPE=cell,home{else}{if $tel.tel_type eq 'fax'}FAX{else}TEL{/if};TYPE=home{/if}:{$tel.tel|vcard_enc}
 +{/foreach}
 +{/if}
 +{/foreach}
 +{foreach from=$vcard.networking item=nw}
 +{if $nw.filter eq 'web'}
 +URL:{$nw.address}
 +{/if}
 +{/foreach}
 +{if strlen(trim($vcard.freetext)) == 0}
 +NOTE:(X{$vcard.promo})
 +{else}
 +NOTE:(X{$vcard.promo})\n{$vcard.freetext|miniwiki:'no_title':'text'|vcard_enc}
 +{/if}
 +{if $vcard.section}
 +X-SECTION:{$vcard.section}
 +{/if}
 +{if $vcard.binets_vcardjoin}
 +X-BINETS:{$vcard.binets_vcardjoin}
 +{/if}
 +{if $vcard.gpxs_vcardjoin}
 +X-GROUPS:{$vcard.gpxs_vcardjoin}
 +{/if}
 +{if $vcard.photo}
 +PHOTO;ENCODING=b;TYPE={$vcard.photo.attachmime}:{$vcard.photo.attach|base64_encode|vcard_enc}
 +{/if}
 +SORT-STRING:{$vcard.nom|vcard_enc}
 +REV:{$vcard.date|date_format:"%Y%m%dT000000Z"}
 +END:VCARD{"\n"}
 +{/iterate}
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
          </td>
        </tr>
        {/foreach}
 -      <tr class="{cycle values="pair,impair"}"><td colspan="4">
 -        <form action="emails/redirect" method="post">
 -        <div>
 -          &nbsp;<br />
 -          Ajouter une adresse email&nbsp;:
 -          <input type="text" size="35" maxlength="60" name="email" value="" />
 -          &nbsp;&nbsp;<input type="submit" value="ajouter" name="emailop" />
 +      <form action="emails/redirect" method="post">
 +        {cycle values="pair,impair" assign=class_combobox}
 +        {include file="include/emails.combobox.tpl" name="email" val=$email class=$class_combobox error=$error_email i="0"}
 +        <tr class=$class_combobox><td colspan="4"><div>
 +          <input type="submit" value="ajouter" name="emailop" />
            {xsrf_token_field}
 -        </div>
 -        </form>
 -      </td></tr>
 +        </div></td></tr>
 +      </form>
      </table>
      <script type="text/javascript">showRemove(); activeEnable();</script>
    </div>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -27,7 -27,7 +27,7 @@@
  {else}
  
  <h1 id='pagetop'>
 -Bienvenue {$smarty.session.prenom}{if $birthday}
 +Bienvenue {$smarty.session.yourself_name}{if $birthday}
    &nbsp;et joyeux anniversaire de la part de toute l'équipe !
  {else},
  {/if}
          </div>
          Annonce proposée par
          <a href="profile/{$ev.hruid}" class="popup2">
 -          {$ev.prenom} {$ev.nom} X{$ev.promo}
 +          {$ev.prenom} {$ev.nom} {$ev.promo_display}
          </a>
        </td>
      </tr>
index 888c17e,0000000..6e99c47
mode 100644,000000..100644
--- /dev/null
@@@ -1,59 -1,0 +1,59 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX<a> / Décès</h2>
 +
 +{if $deceasedErrors}
 +<p>Voici les {$deceasedErrors} différences entre les deux annuaires pour les renseignements de
 +décès.</p>
 +
 +{if $nbDeceasedMissingInXorg > 0}
 +<p>Anciens déclarés décédés dans l'annuaire AX mais pas sur Xorg</p>
 +{include file='fusionax/listFusion.tpl' fusionList=$deceasedMissingInXorg field1='deces_ax' namefield1='Décès AX'}
 +
 +<a href="fusionax/deceased/updateXorg">Inclure toutes les dates de décès connues par l'AX sur Xorg.</a>
 +{/if}
 +
 +{if $nbDeceasedMissingInAX > 0}
 +<p>Anciens déclarés décédés dans l'annuaire Xorg mais pas chez l'AX</p>
 +{include file='fusionax/listFusion.tpl' fusionList=$deceasedMissingInAX field1='deces_xorg' namefield1='Décès X.org'}
 +
 +<a href="fusionax/deceased/updateAX">Considérer ces cas comme traités (il n'y a rien à importer).</a>
 +{/if}
 +
 +{if $nbDeceasedDifferent > 0}
 +<p>Anciens déclarés décédés dans les deux annuaires mais pas avec la même date</p>
 +{include file='fusionax/listFusion.tpl' fusionList=$deceasedDifferent field1='deces_xorg' field2='deces_ax' namefield1='Décès X.org' namefield2='Décès AX'}
 +
 +<h3>Mettre en correspondance</h3>
 +<form action="fusionax/deceased/update" method="post">
 +  User ID X.org : <input type="text" name="user_id" value=""/><br/>
 +  Date de décès : <input type="text" name="date" value""/><br/>
 +  <input type="submit" value="Mettre à jour"/>
 +</form>
 +{/if}
 +
 +{else}
 +<p>Aucune différence pour les renseignements de décès entre les deux annuaires.</p>
 +{/if}
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 3f48241,0000000..e2cd34d
mode 100644,000000..100644
--- /dev/null
@@@ -1,87 -1,0 +1,87 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX</a> / Identifiants</h2>
 +
 +<p>Le préalable à toute fusion de renseignements pour une personne entre ce
 +que contient la base AX et ce que contient ce site est bien évidemment de
 +trouver une correspondance entre les personnes renseignés dans ces annuaires.</p>
 +
 +{if $nbMissingInAX}
 +<h3>Anciens manquants à l'AX</h3>
 +
 +<p><a href="fusionax/ids/missingInAX">{$nbMissingInAX} ancien{if $nbMissingInAX > 1}s{/if}</a>.</p>
 +{/if}
 +
 +{if $nbMissingInXorg > 0}
 +<h3>Anciens manquants à x.org</h3>
 +
 +<p><a href="fusionax/ids/missingInXorg">{$nbMissingInXorg} ancien{if $nbMissingInXorg > 1}s{/if}</a>.</p>
 +{/if}
 +
 +{if $wrongInXorg > 0}
 +<h3>Anciens ayant un matricule_ax sur Xorg ne correspondant à rien dans la base de l'AX</h3>
 +
 +<p><a href="fusionax/ids/wrongInXorg">{$wrongInXorg} ancien{if $wrongInXorg > 1}s{/if}</a>.</p>
 +{/if}
 +
 +<h3>Mettre en correspondance</h3>
 +<form action="fusionax/ids/lier" method="post">
 +      Matricule AX : <input type="text" name="matricule_ax" value""/><br/>
 +      User ID X.org : <input type="text" name="user_id" value=""/><br/>
 +      <input type="submit" value="Lier"/>
 +</form>
 +
 +<p></p>
 +<div id="autolink" name="autolink">
 +<h3>Mise en correspondance automatique</h3>
 +{if $easyToLink}
 +<p>
 +  Ces anciens sont probablement les mêmes (à peu près mêmes nom, prénom, promo)<br />
 +  {$nbMatch} correspondances trouvées.
 +</p>
 +
 +{include file="fusionax/listFusion.tpl" fusionList=$easyToLink fusionAction="fusionax/ids/link" name="lier" field1="display_name_ax" namefield1="Ancien AX"}
 +<p><a href="fusionax/ids/linknext">Lier toutes les fiches affichées</a> <span id="fusion-reload" style="display:none"> - <a href="fusionax/ids#autolink">Trouver d'autres correspondances</a></span></p>
 +<script type="text/javascript">
 +{literal}
 +//<!--
 +$(document).ready(function() {
 +    $('#autolink a.fusion-action').click(function(a){
 +        $.get(a.currentTarget.href,{},function(){
 +            $(a.currentTarget).hide();
 +            $('#fusion-reload').show();
 +            $('#fusion-reload a').click(function(a) {
 +                document.location = a.currentTarget.href;
 +                document.location.reload();
 +            }); 
 +        });
 +        return false;
 +    });
 +});
 +//-->
 +{/literal}
 +</script>
 +{else}
 +<p>Aucune correspondance automatique n'a été trouvée (mêmes nom, prénom, promo d'étude).</p>
 +{/if}
 +</div>
index 8d5ba8c,0000000..2fa5d20
mode 100644,000000..100644
--- /dev/null
@@@ -1,29 -1,0 +1,29 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX<a> / <a href="fusionax/ids">Identifiants<a> /  Manquants dans l'annuaire de l'AX</h2>
 +
 +<p></p>
 +
 +{if $missingInAX}
 +{include file='fusionax/listFusion.tpl' fusionList=$missingInAX field1='user_id' namefield1='ID X.org'}
 +{/if}
index 036d6d4,0000000..c2bd5ec
mode 100644,000000..100644
--- /dev/null
@@@ -1,29 -1,0 +1,29 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX<a> / <a href="fusionax/ids">Identifiants<a> /  Manquants dans l'annuaire d'X.org</h2>
 +
 +<p></p>
 +
 +{if $missingInXorg}
 +{include file='fusionax/listFusion.tpl' fusionList=$missingInXorg field1='id_ancien' namefield1='matricule AX'}
 +{/if}
index 4701aa4,0000000..8cf158b
mode 100644,000000..100644
--- /dev/null
@@@ -1,32 -1,0 +1,32 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX<a> / <a href="fusionax/ids">Identifiants<a> /  Présents dans Xorg avec un matricule_ax ne correspondant à rien
 +dans la base de l'AX (mises à part les promo 1921 et 1923 qui ne figurent pas dans les données de l'AX)</h2>
 +
 +<p></p>
 +
 +{if $wrongInXorg}
 +{include file='fusionax/listFusion.tpl' fusionList=$wrongInXorg field1='user_id' namefield1='ID X.org'}
 +
 +<p><a href="fusionax/ids/cleanwronginxorg">Mettre à NULL le matricule_ax de ces camarades pour marquer le fait qu'ils ne figurent pas dans l'annuaire de l'AX</a></p>
 +{/if}
index f798c96,0000000..6e04ee5
mode 100644,000000..100644
--- /dev/null
@@@ -1,52 -1,0 +1,52 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<script type="text/javascript">
 +{literal}
 +//<!--
 +    $(document).ready(function() {
 +        $('#fusionax_import input').click(function() {
 +            $('#fusionax_import input').hide();
 +            $('#fusionax_import').append('Lancement de l\'import.<br/>');
 +            $.getScript('fusionax/import/launch');
 +        });
 +    });
 +//-->
 +{/literal}
 +</script> 
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX</a></h2>
 +
 +<h2>Import de l'annuaire AX</h2>
 +{if $lastimport}
 +<p>Dernier import {$lastimport}</p>
 +{/if}
 +
 +{if $keymissing}
 +<p>Impossible de faire l'import, il manque la clef d'authentification :</p>
 +<pre>{$keymissing}</pre>
 +{else}
 +<div id="fusionax_import">
 +<input type="button" value="Lancer l'import"/>
 +</div>
 +{/if}
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 67e9cf5,0000000..d11a8b5
mode 100644,000000..100644
--- /dev/null
@@@ -1,37 -1,0 +1,37 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2>Fusion des annuaires X.org - AX</h2>
 +<ul>
 +<li>Voir la <a href="Fusion">documentation</a></li>
 +<li><a href="fusionax/import">Import de la base AX</a> {if $lastimport} - (dernier import le {$lastimport}){/if}</li> 
 +<li>Mise en <a href="fusionax/ids">correspondance simple</a></li>
 +<li>Création des <a href="fusionax/view">VIEW annexes nécessaires aux corrélations</a></li>
 +<li>Corrélation des <a href="fusionax/deceased">dates de décès</a></li>
 +<li>Corrélation des <a href="fusionax/promo">promotions</a></li>
 +<li>Corrélation des <a href="fusionax/names">données d'identification</a></li>
 +<li>Corrélation des <a href="fusionax/coords">coordonnées</a></li>
 +<li>Corrélation des <a href="fusionax/pros">informations professionnelles</a></li>
 +<li>Corrélation des <a href="fusionax/studies">informations de formations</a></li>
 +</ul>
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 206c381,0000000..db89cf8
mode 100644,000000..100644
--- /dev/null
@@@ -1,69 -1,0 +1,69 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<table class="bicol">
 +    <tr>
 +        <th>Ancien</th>
 +        <th>Fiches</th>
 +        {if $field1}
 +        <th>{$namefield1}</th>
 +        {/if}
 +        {if $field2}
 +        <th>{$namefield2}</th>
 +        {/if}
 +        {if $field3}
 +        <th>{$namefield3}</th>
 +        {/if}
 +        {if $field4}
 +        <th>{$namefield4}</th>
 +        {/if}
 +        {if $fusionAction}
 +        <th>Action</th>
 +        {/if}
 +    </tr>
 +{if $fusionList}
 +{iterate from=$fusionList item=c}
 +    <tr class="{cycle values="pair,impair"}">
 +        <td>{$c.display_name} (X {$c.promo})</td>
 +        <td style="text-align:center">
 +            {if $c.user_id}<a href="admin/user/{$c.user_id}" class="popup2">{icon name="user_suit" title="Administrer utilisateur"}</a>{/if}
 +            {if $c.id_ancien}<a href="http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&amp;anc_id={$c.id_ancien}" class="popup2">{icon name="user_gray" title="fiche AX"}</a>{/if}
 +        </td>
 +        {if $field1}
 +        <td>{$c.$field1}</td>
 +        {/if}
 +        {if $field2}
 +        <td>{$c.$field2}</td>
 +        {/if}
 +        {if $field3}
 +        <td>{$c.$field3}</td>
 +        {/if}
 +        {if $field4}
 +        <td>{$c.$field4}</td>
 +        {/if}
 +        {if $fusionAction}
 +        <td><a class="fusion-action" href="{$fusionAction}/{$c.user_id}/{$c.id_ancien}">{$name}</a></td>
 +        {/if}
 +    </tr>
 +{/iterate}
 +{/if}
 +</table>
index d237fae,0000000..1095f74
mode 100644,000000..100644
--- /dev/null
@@@ -1,37 -1,0 +1,37 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX</a> / Promotions</h2>
 +
 +<p></p>
 +
 +{if $nbMissmatchingPromos > 0}
 +<p>Il y a {$nbMissmatchingPromos} différences entre les deux bases dans pour les promotions.</p>
 +<p>Grosses différences (oranjisation ?) :</p>
 +{include file='fusionax/listFusion.tpl' fusionList=$missmatchingPromos1 field1='user_id' namefield1='ID X.org' field3='promo_etude_xorg'
 +namefield3='etude_xorg' field4='promo_sortie_xorg' namefield4='sortie_xorg' field2='promo_etude_ax' namefield2='etude_ax'}
 +
 +<p>Petites différences : promo_etude_xorg == promo_etude_ax + 1 et promo_etude_xorg + 3 == promo_sortie_xorg, a priori ce sont les étrangers que nous avons mal
 +inclus</p>
 +{include file='fusionax/listFusion.tpl' fusionList=$missmatchingPromos2 field1='user_id' namefield1='ID X.org' field3='promo_etude_xorg'
 +namefield3='etude_xorg' field4='promo_sortie_xorg' namefield4='sortie_xorg' field2='promo_etude_ax' namefield2='etude_ax'}
 +{/if}
index c0796cc,0000000..cbbbf36
mode 100644,000000..100644
--- /dev/null
@@@ -1,25 -1,0 +1,25 @@@
- {*  Copyright (C) 2003-2007 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<h2><a href="fusionax">Fusion des annuaires X.org - AX<a> / Création des VIEW annexes nécessaires aux corrélations </h2>
 +
 +<p><a href="fusionax/view/create">Création des VIEW annexes nécessaires aux corrélations</a></p>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
      {if !$c.dcd && ($c.inscrit || $smarty.session.auth eq AUTH_PUBLIC)}</a>{/if}
    </div>
    <div class="autre">
 -    {if $c.iso3166}
 -    <img src='images/flags/{$c.iso3166}.gif' alt='{$c.nat}' height='11' title='{$c.nat}' />&nbsp;
 +    {if $c.iso3166_1}
 +    <img src='images/flags/{$c.iso3166_1}.gif' alt='{$c.nat1}' height='11' title='{$c.nat1}' />&nbsp;
 +    {/if}
 +    {if $c.iso3166_2}
 +    <img src='images/flags/{$c.iso3166_2}.gif' alt='{$c.nat2}' height='11' title='{$c.nat2}' />&nbsp;
 +    {/if}
 +    {if $c.iso3166_3}
 +    <img src='images/flags/{$c.iso3166_3}.gif' alt='{$c.nat3}' height='11' title='{$c.nat3}' />&nbsp;
      {/if}
      (X {$c.promo})
      {if $c.dcd}décédé{if $c.sexe}e{/if} le {$c.deces|date_format}{/if}
index e24d782,0000000..db4a630
mode 100644,000000..100644
--- /dev/null
@@@ -1,144 -1,0 +1,144 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +{assign var=new value="new"|cat:$i}
 +{assign var=combobox value="combobox"|cat:$i}
 +{if !$isjob}
 +<tr {if $class}class="{$class}"{/if}>
 +  <td>
 +{/if}
 +    <span class="titre">{if $name eq "email_directory"}Email annuaire AX
 +    {elseif $name eq "email"}Ajouter une adresse email{else}
 +    Email professionnel{/if}</span>
 +{if !$isjob}
 +  </td>
 +  {if $name eq "email"}<td></td>{/if}
 +  <td>
 +{else}
 +  <br />
 +  <span class="flags">
 +    {include file="include/flags.radio.tpl" name="`$jobpref`[`$prefix`email_pub]" val=$pub}
 +  </span>
 +  <br />
 +{/if}
 +    <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">
 +          {if $melix}
 +            <option value="{$melix}@{#globals.mail.alias_dom#}" {if
 +            $val eq $melix|cat:'@'|cat:#globals.mail.alias_dom#}selected="selected"{/if}>
 +            {$melix}@{#globals.mail.alias_dom#}</option>
 +            <option value="{$melix}@{#globals.mail.alias_dom2#}" {if
 +            $val eq $melix|cat:'@'|cat:#globals.mail.alias_dom2#}selected="selected"{/if}>
 +            {$melix}@{#globals.mail.alias_dom2#}</option>
 +          {/if}
 +          {foreach from=$list_email_X item=email}
 +            <option value="{$email.alias}@{#globals.mail.domain#}" {if
 +            $val eq $email.alias|cat:'@'|cat:#globals.mail.domain#}selected="selected"{/if}>
 +            {$email.alias}@{#globals.mail.domain#}</option>
 +            <option value="{$email.alias}@{#globals.mail.domain2#}" {if
 +            $val eq $email.alias|cat:'@'|cat:#globals.mail.domain2#}selected="selected"{/if}>
 +            {$email.alias}@{#globals.mail.domain2#}</option>
 +          {/foreach}
 +        </optgroup>
 +      {/if}
 +      {if (($name neq "email") && ($list_email_redir|@count neq 0))}
 +        <optgroup label="Redirections">
 +          {foreach from=$list_email_redir 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}
 +      <optgroup label="Autres choix">
 +        <option value="new@example.org" {if $error}selected="selected"{/if}>Utiliser une autre adresse email</option>
 +        <option value="" {if (($val eq '') && (!$error))}selected="selected"{/if}>{if
 +        $name neq "email"}Ne pas mettre d'adresse email{else}&nbsp;{/if}</option>
 +      </optgroup>
 +    </select>
 +    {if $name eq "email_directory"}
 +      <input type="checkbox" disabled="disabled" checked="checked"/>
 +      {icon name="flag_orange" title="Visible sur l'annuaire"}
 +    {elseif ($name neq "email") && (!$isjob)}
 +      <span class="flags">
 +        {include file="include/flags.radio.tpl" name="`$jobpref`[`$prefix`email_pub]" val=$pub}
 +      </span>
 +    {/if}
 +    <br />
 +    <span class="{$new}" style="display: none">
 +      <input type="text" maxlength="60" {if $error}class="error" value="{$val}"{/if} name="{if (($name neq "email_directory")
 +      && ($name neq "email"))}jobs[{$i}][{$prefix}email_new]{else}{$name}_new{/if}"/>
 +    </span>
 +    <script type="text/javascript">//<![CDATA[
 +      {literal}
 +      $(function() {
 +        var i = {/literal}{$i}{literal};
 +        $('select#combobox' + i).change(function() {
 +          $('.new' + i).hide();
 +          if ($('select#combobox' + i).val() == "new@example.org") {
 +            $('.new' + i).show();
 +          }
 +        }).change();
 +      });
 +      {/literal}
 +    // ]]></script>
 +{if !$isjob}
 +  </td>
 +  {if $name eq "email"}<td></td>{/if}
 +</tr>
 +{else}
 +<br />
 +{/if}
 +{if $name neq "email"}
 +{if !$isjob}
 +  <tr {if $class}class="{$class} {$new}"{else}class="{$new}"{/if} style="display: none">
 +    <td colspan="2">
 +{else}
 +  <div class="{$new}" style="display: none">
 +{/if}
 +      <p><small><strong><em>Attention :</em></strong> cette adresse email figurera dans
 +      {if $name eq "email_directory"}l'annuaire papier{else}tes informations professionnelles
 +      {/if} mais n'est pas ajoutée à la liste de tes redirections. Nous te conseillons fortement de
 +      <strong><a href="emails/redirect">l'ajouter là</a></strong>, surtout
 +      si tu n'en as plus de valide.</small></p>
 +{if !$isjob}
 +    </td>
 +  </tr>
 +{else}
 +  </div>
 +{/if}
 +{/if}
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -26,8 -26,7 +26,8 @@@
          {if $address.entreprise || $address.web}
          <tr>
            <td><em>Ent/Org&nbsp;: </em></td>
 -          <td><strong>{$address.entreprise}{if $address.web} [<a href='{$address.web}'>site</a>]{/if}</strong></td>
 +          <td><strong>{if $address.web}<a href='{$address.web}'>{$address.entreprise}</a>{$address.entreprise}{else}{$address.entreprise}{/if}
 +          {if $address.w_web} [<a href='{$address.w_web}'>Page perso</a>]{/if}</strong></td>
          </tr>
          {/if}
          {if $address.secteur}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  {*                                                                        *}
  {**************************************************************************}
  
 -<script type="text/javascript">//<![CDATA[ 
 +<script type="text/javascript">//<![CDATA[
      var prefix = "{$prefix}";
 -    {literal} 
 -    function updateRange() 
 -    { 
 -      var range = document.getElementById(prefix + 'promo_range'); 
 -      min = document.getElementById(prefix + 'promo_min').value; 
 -      max = document.getElementById(prefix + 'promo_max').value; 
 -      if (isNaN(min) || (min != 0 && (min < 1900 || min > 2020))) { 
 +    {literal}
 +    function updateRange()
 +    {
 +      var range = document.getElementById(prefix + 'promo_range');
 +      min = document.getElementById(prefix + 'promo_min').value;
 +      max = document.getElementById(prefix + 'promo_max').value;
 +      if (isNaN(min) || (min != 0 && (min < 1900 || min > 2020))) {
          range.innerHTML = '<span class="erreur">La promotion minimum n\'est pas valide.</span>';
 -        return false; 
 -      } else if (isNaN(max) || (max != 0 && (max < 1900  || max > 2020))) { 
 +        return false;
 +      } else if (isNaN(max) || (max != 0 && (max < 1900  || max > 2020))) {
          range.innerHTML = '<span class="erreur">La promotion maximum n\'est pas valide.</span>';
 -        return false; 
 -      } else if (max != 0 && min != 0 && max < min) { 
 +        return false;
 +      } else if (max != 0 && min != 0 && max < min) {
          range.innerHTML = '<span class="erreur">L\'intervalle de promotion est inversé.</span>';
 -        return false; 
 -      } else if (max == 0 && min == 0) { 
 +        return false;
 +      } else if (max == 0 && min == 0) {
          range.innerHTML = 'L\'annonce est destinée à toutes les promotions.';
 -      } else if (max == 0) { 
 +      } else if (max == 0) {
          range.innerHTML = 'L\'annonce est destinée aux promotions plus jeunes que ' + min + ' (incluse).';
 -      } else if (min == 0) { 
 +      } else if (min == 0) {
          range.innerHTML = "L\'annonce est destinée aux promotions plus anciennes que " + max + ' (incluse).';
        } else if (min == max - 1) {
          range.innerHTML = "L\'annonce est destinée aux promotions " + min + " et " + max + ".";
        } else if (min == max) {
          range.innerHTML = "L\'annonce est destinée à la promotion " + min + ".";
 -      } else { 
 +      } else {
          range.innerHTML = "L\'annonce est destinée aux promotions de " + min + " à " + max + ' (incluses).';
        } 
 -      return true; 
 +      return true;
      } 
 -    {/literal} 
 -//]]></script> 
 +    {/literal}
 +//]]></script>
  
  {if $full}
  <table class="bicol">
  {/if}
 -  <tr id="{$prefix}promo_min_tr" class="impair"> 
 -    <td class="titre">Promotion la plus ancienne</td> 
 -    <td> 
 +  <tr id="{$prefix}promo_min_tr" class="impair">
 +    <td class="titre">Promotion la plus ancienne</td>
 +    <td>
        <input type="text" name="{$min_field_name|default:"promo_min"}" id="{$prefix}promo_min"
 -             size="4" maxlength="4" value="{$promo_min|default:0}" 
 -             onkeyup="return updateRange();" onchange="return updateRange();" /> incluse 
 -      &nbsp;<span class="smaller">(ex&nbsp;: 1980)</span> 
 -    </td> 
 -  </tr> 
 -  <tr id="{$prefix}promo_max_tr" class="impair"> 
 -    <td class="titre">Promotion la plus jeune</td> 
 -    <td> 
 +             size="4" maxlength="4" value="{$promo_min|default:0}"
 +             onkeyup="return updateRange();" onchange="return updateRange();" /> incluse
 +      &nbsp;<span class="smaller">(ex&nbsp;: 1980)</span>
 +    </td>
 +  </tr>
 +  <tr id="{$prefix}promo_max_tr" class="impair">
 +    <td class="titre">Promotion la plus jeune</td>
 +    <td>
        <input type="text" name="{$max_field_name|default:"promo_max"}" id="{$prefix}promo_max"
 -             size="4" maxlength="4" value="{$promo_max|default:0}" 
 -             onkeyup="return updateRange();" onchange="return updateRange();" /> incluse 
 -      &nbsp;<span class="smaller">(ex&nbsp;: 2000)</span> 
 -    </td> 
 -  </tr> 
 -  <tr id="{$prefix}promo_range_tr" class="impair"> 
 -    <td colspan="2" id="promo_range" class="smaller"> 
 -      <script type="text/javascript">updateRange();</script> 
 -    </td> 
 -  </tr> 
 +             size="4" maxlength="4" value="{$promo_max|default:0}"
 +             onkeyup="return updateRange();" onchange="return updateRange();" /> incluse
 +      &nbsp;<span class="smaller">(ex&nbsp;: 2000)</span>
 +    </td>
 +  </tr>
 +  <tr id="{$prefix}promo_range_tr" class="impair">
 +    <td colspan="2" id="promo_range" class="smaller">
 +      <script type="text/javascript">updateRange();</script>
 +    </td>
 +  </tr>
  {if $full}
  </table>
  {/if}
index 89b19e0,0000000..09457df
mode 100644,000000..100644
--- /dev/null
@@@ -1,42 -1,0 +1,42 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<strong>Nom&nbsp;:</strong>
 +<input type="text" name="name" size="25" maxlength="200" value="{$valid->name}" /><br />
 +<strong>Acronyme&nbsp;:</strong>
 +<input type="text" name="acronym" size="25" maxlength="200" value="{$valid->acronym}" /><br />
 +<strong>Site web&nbsp;:</strong>
 +<input type="text" name="url" size="25" maxlength="200" value="{$valid->url}" /><br />
 +<strong>Email&nbsp;:</strong>
 +<input type="text" name="url" size="25" maxlength="200" value="{$valid->email}" /><br />
 +<strong>Holding&nbsp;:</strong>
 +<input type="text" name="holdingid" size="25" maxlength="200" value="{$valid->holdingid}" /><br />
 +<strong>Code NAF&nbsp;:</strong>
 +<input type="text" name="NAF_code" size="25" maxlength="200" value="{$valid->NAF_code}" /><br />
 +<strong>Code AX&nbsp;:</strong>
 +<input type="text" name="AX_code" size="25" maxlength="200" value="{$valid->AX_code}" /><br />
 +<strong>Téléphone&nbsp;:</strong>
 +<input type="text" name="tel" size="25" maxlength="200" value="{$valid->tel}" /><br />
 +<strong>Fax&nbsp;:</strong>
 +<input type="text" name="fax" size="25" maxlength="200" value="{$valid->fax}" /><br />
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 637d7c3,0000000..6ed7534
mode 100644,000000..100644
--- /dev/null
@@@ -1,70 -1,0 +1,70 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +
 +<tr class="pair">
 +  <td class="titre">Nom&nbsp;:</td>
 +  <td>{$valid->name}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Noms similaires existants&nbsp;:</td>
 +  <td>{$valid->suggestions}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Acronyme&nbsp;:</td>
 +  <td>{$valid->acronym}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Site web&nbsp;:</td>
 +  <td>{$valid->url}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Email&nbsp;:</td>
 +  <td>{$valid->email}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Holding&nbsp;:</td>
 +  <td>{$valid->holdingid}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Code NAF&nbsp;:</td>
 +  <td>{$valid->NAF_code}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Code AX&nbsp;:</td>
 +  <td>{$valid->AX_code}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Téléphone&nbsp;:</td>
 +  <td>{$valid->tel}</td>
 +</tr>
 +<tr class="pair">
 +  <td class="titre">Fax&nbsp;:</td>
 +  <td>{$valid->fax}</td>
 +</tr>
 +<tr class="pair">
 +  <td colspan="2" class="center">
 +    <small>Bien remplir tous les champs, en particulier les <a href="http://societe.com/">codes NAF</a> et AX !</small>
 +  </td>
 +</tr>
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
      {if $smarty.session.auth ge AUTH_COOKIE}
      <div class="photo">
        <img src="photo/{$c.hruid}"
 -           alt="{$c.prenom} {$c.nom}" />
 +           alt="{$c.name_display}" />
      </div>
      {/if}
  
      <div class="nom">
        {if $c.sexe}&bull;{/if}
        {if !$c.dcd && ($c.inscrit || $smarty.session.auth eq AUTH_PUBLIC)}<a href="profile/{$c.hruid}" class="popup2">{/if}
 -      {if $c.nom_usage}{$c.nom_usage} {$c.prenom}<br />({$c.nom}){else}{$c.nom} {$c.prenom}{/if}
 +      <span {if $c.name_tooltip}class="hinted" title="{$c.name_tooltip}"{/if}>{$c.name_display}</span>
        {if !$c.dcd && ($c.inscrit || $smarty.session.auth eq AUTH_PUBLIC)}</a>{/if}
      </div>
  
 -    <div class="appli">
 -      {if $c.iso3166}
 -      <img src='images/flags/{$c.iso3166}.gif' alt='{$c.nat}' height='11' title='{$c.nat}' />&nbsp;
 +    <div class="edu">
 +      {if $c.iso3166_1}
 +      <img src='images/flags/{$c.iso3166_1}.gif' alt='{$c.nat1}' height='11' title='{$c.nat1}' />&nbsp;
        {/if}
 -      X {$c.promo}{if $c.app0text}, {applis_fmt type=$c.app0type text=$c.app0text url=$c.app0url}{*
 -      *}{/if}{if $c.app1text}, {applis_fmt type=$c.app1type text=$c.app1text url=$c.app1url}{/if}{*
 -      *}{if $c.dcd}, décédé{if $c.sexe}e{/if} le {$c.deces|date_format}{/if}
 +      {if $c.iso3166_2}
 +      <img src='images/flags/{$c.iso3166_2}.gif' alt='{$c.nat2}' height='11' title='{$c.nat2}' />&nbsp;
 +      {/if}
 +      {if $c.iso3166_3}
 +      <img src='images/flags/{$c.iso3166_3}.gif' alt='{$c.nat3}' height='11' title='{$c.nat3}' />&nbsp;
 +      {/if}
 +      {$c.promo_display}{if $c.eduname0}, {education_fmt name=$c.eduname0 url=$c.eduurl0 degree=$c.edudegree0
 +                                     grad_year=$c.edugrad_year0 field=$c.edufield0 program=$c.eduprogram0 sexe=$c.sexe}{*
 +      *}{/if}{if $c.eduname1}, {education_fmt name=$c.eduname1 url=$c.eduurl1 degree=$c.edudegree1
 +                                     grad_year=$c.edugrad_year1 field=$c.edufield1 program=$c.eduprogram1 sexe=$c.sexe}{*
 +      *}{/if}{if $c.eduname2}, {education_fmt name=$c.eduname2 url=$c.eduurl2 degree=$c.edudegree2
 +                                     grad_year=$c.edugrad_year2 field=$c.edufield2 program=$c.eduprogram2 sexe=$c.sexe}{*
 +      *}{/if}{if $c.eduname3}, {education_fmt name=$c.eduname3 url=$c.eduurl3 degree=$c.edudegree3
 +                                     grad_year=$c.edugrad_year3 field=$c.edufield3 program=$c.eduprogram3 sexe=$c.sexe}{*
 +      *}{/if}{if $c.dcd}, décédé{if $c.sexe}e{/if} le {$c.deces|date_format}{/if}
      </div>
    </div>
  
          <td class="lt">Profession&nbsp;:</td>
          <td class="rt">
            {if $c.job_web}<a href="{$c.job_web}">{$c.entreprise}</a>{else}{$c.entreprise}{/if}
-           {if $c.secteur}({$c.secteur}){/if} {if $c.fonction}<br />{$c.fonction}{/if}
+           {if $c.secteur} ({$c.secteur}){/if}{if $c.fonction}<br />{$c.fonction}{/if}
          </td>
        </tr>
        {/if}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  {**************************************************************************}
  
  <div class="contact-list" style="clear: both">
 -{foreach from=$set item=p} 
 -  <div class="contact"> 
 -    <div class="nom"> 
 -      {$p.nom} {$p.prenom} 
 -    </div> 
 -    <div class="appli"> 
 -      X{$p.promo} 
 -    </div> 
 -    <div class="bits" style="width: 40%;"> 
 -      <span class='smaller'> 
 +{foreach from=$set item=p}
 +  <div class="contact">
 +    <div class="nom">
 +      <span {if $p.name_tooltip}class="hinted" title="{$p.name_tooltip}"{/if}>{$p.name_display}</span>
 +    </div>
 +    <div class="edu">
 +      {$p.promo_display}
 +    </div>
 +    <div class="bits" style="width: 40%;">
 +      <span class='smaller'>
        <a href="profile/{$p.hruid}" class="popup2">
 -        {icon name=user_suit title="Voir sa fiche"}</a> - 
 +        {icon name=user_suit title="Voir sa fiche"}</a> -
          <a href="referent/{$p.hruid}" class="popup2">Voir sa fiche référent</a>
 -      </span> 
 -    </div> 
 -    <div class="long"> 
 -     <table cellspacing="0" cellpadding="0"> 
 -      <tr> 
 -        <td class="lt">Expertise&nbsp;:</td> 
 -        <td class="rt" colspan="2">{$p.expertise|nl2br}</td> 
 -      </tr> 
 -     </table> 
 -    </div> 
 -  </div> 
 +      </span>
 +    </div>
 +    <div class="long">
 +     <table cellspacing="0" cellpadding="0">
 +      <tr>
 +        <td class="lt">Expertise&nbsp;:</td>
 +        <td class="rt" colspan="2">{$p.expertise|nl2br}</td>
 +      </tr>
 +     </table>
 +    </div>
 +  </div>
  {/foreach}
  </div>
  
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
    <tr>
      <td class="center" style="vertical-align: bottom; padding-bottom: 15px">
        <a href="{$mainsiteurl}profile/{$set[trombi.index_prev].hruid}" class="popup2">
 -        {$set[trombi.index_prev].prenom} {$set[trombi.index_prev].nom}{if $trombi_with_promo} ({$set[trombi.index_prev].promo}){/if}
 +        <span {if $set[trombi.index_prev].name_tooltip}class="hinted"
 +        title="{$set[trombi.index_prev].name_tooltip}"{/if}>{$set[trombi.index_prev].name_display}</span>{if $trombi_with_promo} ({$set[trombi.index_prev].promo_display}){/if}
        </a>
      </td>
      <td class="center" style="vertical-align: bottom; padding-bottom: 15px">
        <a href="{$mainsiteurl}profile/{$set[trombi].hruid}" class="popup2">
 -        {$set[trombi].prenom} {$set[trombi].nom}{if $trombi_with_promo} ({$set[trombi].promo}){/if}
 +        <span {if $set[trombi].name_tooltip}class="hinted" title="{$set[trombi].name_tooltip}"{/if}>{$set[trombi].name_display}</span>{if $trombi_with_promo} ({$set[trombi].promo_display}){/if}
        </a>
      </td>
      <td class="center" style="vertical-align: bottom; padding-bottom: 15px">
      {if $set[trombi.index_next]}
        <a href="{$mainsiteurl}profile/{$set[trombi.index_next].hruid}" class="popup2">
 -        {$set[trombi.index_next].prenom} {$set[trombi.index_next].nom}{if $trombi_with_promo} ({$set[trombi.index_next].promo}){/if}
 +        <span {if $set[trombi.index_next].name_tooltip}class="hinted" title="{$set[trombi.index_next].name_tooltip}"{/if}>{$set[trombi.index_next].name_display}</span>{if $trombi_with_promo} ({$set[trombi.index_next].promo_display}){/if}
        </a>
      {/if}
      </td>
@@@ -91,8 -90,7 +91,8 @@@
    <tr style="margin-top: 0; padding-top: 0">
      <td class="center" style="vertical-align: bottom">
        <a href="{$mainsiteurl}profile/{$set[trombi].hruid}" class="popup2">
 -        {$set[trombi].prenom} {$set[trombi].nom}{if $trombi_with_promo} ({$set[trombi].promo}){/if}
 +      <a href="{$mainsiteurl}profile/{$set[trombi].forlife}" class="popup2">
 +        <span {if $set[trombi].name_tooltip}class="hinted" title="{$set[trombi].name_tooltip}"{/if}>{$set[trombi].name_display}</span>{if $trombi_with_promo} ({$set[trombi].promo_display}){/if}
        </a>
      </td>
      <td></td><td></td>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -37,7 -37,7 +37,7 @@@
        {/if}
        <br />
        <a href="{if $urlmainsite}{$urlmainsite}{/if}profile/{$p.forlife}" class="popup2">
 -        {$p.prenom} {$p.nom}{if $trombi_show_promo} ({$p.promo}){/if}
 +        <span {if $p.name_tooltip}class="hinted" title="{$p.name_tooltip}"{/if}>{$p.name_display}</span>{if $trombi_show_promo} ({$p.promo_display}){/if}
        </a>
      </td>
    {if $loop eq "3"}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -64,10 -64,7 +64,10 @@@ sa dernière relance date du {$relance|
      {iterate from=$addr item=a}
      <tr class="{cycle values='impair,pair'}">
        <td>{$a.email}</td>
 -      <td>{if $a.alias}<a href="profile/{$a.alias}" class="popup2">{$a.alias}</a> {if $a.type eq user}(*){/if}{/if}</td>
 +      <td>
 +        {if $a.alias neq ''}<a href="profile/{$a.alias}" class="popup2">{$a.alias}</a>
 +        {if $a.type eq user}(*){/if}{else}Email connu de l'AX{/if}
 +      </td>
        <td>{$a.date|date_format|default:'-'}</td>
        <td>{$a.last|date_format|default:'-'}</td>
        <td class='center'>{$a.nb|default:"-"}</td>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
                   {if $adr.mail}checked="checked"{/if} />
            <label for="{$adid}_mail">on peut m'y envoyer du courrier par la poste</label>
          </div>
 +        <div>
 +          <label for="{$adpref}[comment]">Commentaire : </label>
 +          <input type="text" size="35" maxlength="100" name="{$adpref}[comment]" id="{$adpref}_comment" value="{$adr.comment}" />
 +        </div>
        </div>
      </td>
    </tr>
    <tr class="pair">
      <td>
        {foreach from=$adr.tel key=t item=tel}
 -      <div id="{"`$adid`_tel_`$t`"}" style="clear: both">
 -      {include file="profile/adresses.tel.tpl" t=$t tel=$tel}
 -      </div>
 +        <div id="{"`$adid`_tel_`$t`"}" style="clear: both">
 +          {include file="profile/phone.tpl" prefname="`$adpref`[tel]" prefid="`$adid`_tel" telid=$t tel=$tel}
 +        </div>
        {/foreach}
        {if $adr.tel|@count eq 0}
 -      <div id="{"`$adid`_tel_0"}" style="clear: both">
 -      {include file="profile/adresses.tel.tpl" t=0 tel=0}
 -      </div>
 +        <div id="{"`$adid`_tel_0"}" style="clear: both">
 +          {include file="profile/phone.tpl" prefname="`$adpref`[tel]" prefid="`$adid`_tel" telid=0 tel=0}
 +        </div>
        {/if}
 -      <div id="{$adid}_add_tel" class="center" style="clear: both">
 -        <a href="javascript:addTel({$i})">
 +      <div id="{$adid}_tel_add" class="center" style="clear: both; padding-top: 4px">
 +        <a href="javascript:addTel('{$adid}_tel', '{$adpref}[tel]')">
            {icon name=add title="Ajouter un numéro de téléphone"} Ajouter un numéro de téléphone
          </a>
        </div>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  {*                                                                        *}
  {**************************************************************************}
  
 -{assign var=telpref value="`$adpref`[tel][`$t`]"}
 -{assign var=telid value="`$adid`_tel_`$t`"}
 -<div style="float: right" class="flags">
 -  {include file="include/flags.radio.tpl" name="`$telpref`[pub]" val=$tel.pub}
 -</div>
 -<span class="titre">N°{$t+1}</span>
 -<input type="hidden" name="{$telpref}[removed]" value="0" />
 -<input type="text" size="10" maxlength="30" name="{$telpref}[type]" value="{$tel.type|default:"Tél."}" />
 -<input type="text" size="19" maxlength="28" name="{$telpref}[tel]" {if $tel.error}class="error"{/if} value="{$tel.tel}" />
 -<a href="javascript:removeObject('{$telid}', '{$telpref}')">
 -  {icon name=cross title="Supprimer ce numéro de téléphone"}
 -</a>
 +educationDegree     = new Array({education_degree});
 +educationDegreeAll  = new Array({education_degree_all});
 +educationDegreeName = new Array({education_degree_name}); 
  
  {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -26,7 -26,7 +26,7 @@@
    <div id="fiche_identite">
      <div class="civilite">
        <strong>{$user->fullName()}</strong><br />
 -      <span>X{$user->promo()}&nbsp;-&nbsp;</span> <a href="mailto:{$user->bestEmail()}">{$user->bestEmail()}</a>
 +      <span>{$user->promo()}&nbsp;-&nbsp;</span> <a href="mailto:{$user->bestEmail()}">{$user->bestEmail()}</a>
      </div>
    </div>
    <div class="spacer"></div>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -20,6 -20,7 +20,6 @@@
  {*                                                                        *}
  {**************************************************************************}
  
 -applisType = new Array({applis_type});
 -applisTypeAll = new Array({applis_type_all});
 +{$names}
  
  {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index b2307da,0000000..de7bf5d
mode 100644,000000..100644
--- /dev/null
@@@ -1,76 -1,0 +1,76 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +{assign var=eduname value="edus[`$eduid`]"}
 +<tr class="edu_{$eduid} {$class}">
 +  <td colspan="2">
 +    <a href="javascript:removeEdu('{$eduid}')">
 +      {icon name=cross title="Supprimer cette formation"}
 +    </a>
 +    <select name="{$eduname}[eduid]" onchange="fillType(this.form['{$eduname}[degreeid]'], this.selectedIndex - 1);">
 +      {education_options selected=$edu.eduid}
 +    </select>
 +  </td>
 +</tr>
 +<tr class="edu_{$eduid} {$class}">
 +  <td>
 +    <span class="titre">Diplôme&nbsp;:</span>
 +  </td>
 +  <td>
 +    <input type="hidden" name="edu_{$eduid}_tmp" value="{$edu.degreeid}" />
 +    <select name="{$eduname}[degreeid]">
 +      <option value=""></option>
 +    </select>
 +  </td>
 +</tr>
 +<tr class="edu_{$eduid} {$class}">
 +  <td>
 +    <span class="titre">Domaine de formation&nbsp;:</span>
 +  </td>
 +  <td>
 +    <select name="{$eduname}[fieldid]">
 +      {foreach from=$edu_fields item=field}
 +      <option value="{$field.id}" {if $field.id eq $edu.fieldid}selected="selected"{/if}>{$field.field}</option>
 +      {/foreach}
 +    </select>
 +  </td>
 +</tr>
 +<tr class="edu_{$eduid} {$class}">
 +  <td>
 +    <span class="titre">Année d'obtention du diplôme&nbsp;:</span>
 +  </td>
 +  <td>
 +    <input type="text" {if $edu.error}class="error"{/if} name="{$eduname}[grad_year]"
 +    value="{$edu.grad_year}" size="4" maxlength="4" />
 +    <small>(par exemple&nbsp;: 2008)</small>
 +  </td>
 +</tr>
 +<tr class="edu_{$eduid} {$class}">
 +  <td>
 +    <span class="titre">Intitulé de la formation&nbsp;:</span>
 +  </td>
 +  <td>
 +    <input type="text" name="{$eduname}[program]" value="{$edu.program}" size="30" maxlength="255" />
 +  </td>
 +</tr>
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index d4d17f8,0000000..f2bcc5a
mode 100644,000000..100644
--- /dev/null
@@@ -1,48 -1,0 +1,48 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<tr id="networking_{$i}">
 +  <td colspan="2">
 +    <div style="float: left; width: 200px;">
 +      <span class="flags">
 +        <label><input type="checkbox"
 +          {if $nw.pub neq 'private'} checked="checked"{/if}
 +          name="networking[{$i}][pub]"/>
 +        {icon name="flag_green" title="site public"}</label>
 +      </span>&nbsp;
 +      <input type="hidden" name="networking[{$i}][type]" value="{$nw.type}"/>
 +      <input type="hidden" name="networking[{$i}][name]" value="{$nw.name}"/>
 +      <img src="profile/networking/{$nw.type}" alt="{$nw.name}" title="{$nw.name}" />
 +      <span style="">{$nw.name}</span>
 +    </div>
 +    <div style="float: left">
 +      <input type="text" name="networking[{$i}][address]" value="{$nw.address}"
 +        {if $nw.error} class="error" {/if}
 +        size="30"/>
 +      <a href="javascript:removeNetworking({$i})">
 +        {icon name=cross title="Supprimer cet élément"}
 +      </a>
 +    </div>
 +  </td>
 +</tr>
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
index 4e755d4,0000000..8faef48
mode 100644,000000..100644
--- /dev/null
@@@ -1,65 -1,0 +1,65 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<tr id="search_name_{$i}"{if $class} class="{$class}" style="{$style}"{/if}>
 +  <td>
 +    <input type="hidden" name="search_names[{$i}][always_displayed]" value="{$sn.always_displayed}"/>
 +    <input type="hidden" name="search_names[{$i}][has_particle]" value="{$sn.has_particle}"/>
 +    <span class="flags">
 +      <input id="flag_cb_{$i}" type="checkbox" checked="checked" disabled="disabled"/>
 +      <span id="flag_{$i}">{if $sn.pub}{icon name="flag_green" title="site public"}
 +      {else}{icon name="flag_red" title="site privé"}{/if}</span>
 +    </span>&nbsp;
 +    {if $sn_type_list}
 +    <select id="search_name_select_{$i}" name="search_names[{$i}][typeid]" onchange="changeNameFlag({$i});updateNameDisplay();">
 +        {foreach from=$sn_type_list item=sn_type}
 +          <option value="{$sn_type.id}">{$sn_type.name}</option>
 +        {/foreach}
 +    </select>
 +    {foreach from=$sn_type_list item=sn_type}
 +    <input type="hidden" name="sn_type_{$sn_type.id}_{$i}" value="{$sn_type.pub}"/>
 +    {/foreach}
 +    {else}
 +    {$sn.type}
 +    <input type="hidden" name="search_names[{$i}][pub]" value="{$sn.pub}"/>
 +    <input type="hidden" name="search_names[{$i}][type]" value="{$sn.type}"/>
 +    <input type="hidden" name="search_names[{$i}][typeid]" value="{$sn.typeid}"/>
 +    {/if}
 +  </td>
 +  <td>
 +    <input type="text" name="search_names[{$i}][name]" value="{$sn.name}"
 +      {if $sn.has_particle}title="Coche la case en bout de ligne si ton nom commence par une particle."{/if}
 +      {if $sn.error} class="error"{/if} size="25" onkeyup="updateNameDisplay();"/>
 +  </td>
 +  <td>
 +    {if $sn.has_particle}<input name="search_names[{$i}][particle]" type="checkbox"
 +      title="Coche cette case si ton nom commence par une particle."
 +      {if $sn.particle neq ''} checked="checked"{/if} onchange="updateNameDisplay();"/>
 +    {else}
 +      <input type="hidden"  name="search_names[{$i}][particle]" value=""/>{/if}
 +    {if !$sn.always_displayed}<a href="javascript:removeSearchName({$i})">
 +      {icon name=cross title="Supprimer ce nom"}
 +    </a>{/if}
 +  </td>
 +</tr>
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  {*                                                                        *}
  {**************************************************************************}
  
 -<table class="bicol" style="margin-bottom: 1em"
 -  summary="Profil&nbsp;: Informations générales">
 +<table class="bicol" style="margin-bottom: 1em" summary="Profil : Noms">
    <tr>
 -    <th colspan="2">
 -      <div class="flags" style="float: left">
 -        <input type="checkbox" disabled="disabled" checked="checked" />
 -        {icon name="flag_green" title="site public"}
 -      </div>
 -      Informations générales
 -    </th>
 +    <th colspan="3">Noms</th>
    </tr>
    <tr>
 -    <td>
 -      <span class="titre">Nom</span>
 -      <span class="comm"></span>
 +    <td class="titre">
 +      {icon name="flag_green" title="site public"}&nbsp;Affichage public
      </td>
 -    <td>
 -      <input type='text' name='nom' {if $errors.nom}class="error"{/if} value="{$nom}" />
 +    <td id="public_name">
 +      {$public_name}
 +    </td>
 +    <td rowspan="2">
 +      <a href="javascript:displayNamesAdvanced();">
 +        {icon name="page_edit" title="Plus de détail"}
 +      </a>
      </td>
    </tr>
    <tr>
 -    <td>
 -      <span class="titre">Prénom</span>
 -      <span class="comm"></span>
 +    <td class="titre">
 +      {icon name="flag_red" title="site privé"}&nbsp;Affichage privé
      </td>
 -    <td>
 -      <input type='text' name='prenom' {if $errors.prenom}class="error"{/if} value="{$prenom}" />
 +    <td id="private_name">
 +      {$private_name}
      </td>
    </tr>
    <tr>
      <td>
 -      <span class="titre">Promotion</span>
 +      <span class="titre">Comment t'appeller</span><br />
 +      <span class="smaller">sur le site, dans la lettre mensuelle...</span>
      </td>
      <td>
 -      <span class="nom">X{$promo}{if ($promo != $promo_sortie - 3)} - X{math equation="a - b" a=$promo_sortie b=3}{/if}</span>
 -      <span class="lien"><a href="profile/orange">modifier</a>{if ($promo_sortie -3 == $promo)} pour les oranges{/if}</span>
 +      <input type="text" name="yourself" value="{$yourself}" size="25"/>
      </td>
 +    <td></td>
 +  </tr>
 +  <tr class="names_advanced" style="display: none">
 +    <td colspan="3">
 +      <span class="titre">Gestion de tes noms, prénoms, surnoms...</span>
 +      <span class="smaller">Ils déterminent la façon dont ton nom apparaît sur les annuaires
 +      en ligne et papier et ta fiche apparaitra quand on cherche un de ces noms. Pour plus
 +      d'explications sur l'icône suivante
 +      <a href="profile/name_info" class="popup3">{icon name="information" title="Plus d'infos"}</a>.</span><br/>
 +      <div class="small center">Si un de tes noms commence par une particule,
 +      coche la case en bout de ligne.</div>
 +    </td>
 +  </tr>
 +  {foreach from=$search_names item=sn key=id}
 +    {include file="profile/general.searchname.tpl" i=$id sn=$sn class="names_advanced" style="display: none"}
 +  {/foreach}
 +  <tr class="names_advanced" id="searchname" style="display: none">
 +    <td colspan="2">
 +      <div id="sn_add" class="center">
 +        <a href="javascript:addSearchName();">
 +          {icon name=add title="Ajouter un nom"} Ajouter un nom
 +        </a>
 +      </div>
 +    </td>
 +  </tr>
 +</table>
 +
 +<table class="bicol" style="margin-bottom: 1em"
 +  summary="Profil&nbsp;: Informations générales">
 +  <tr>
 +    <th colspan="2">
 +      <div class="flags" style="float: left">
 +        <input type="checkbox" disabled="disabled" checked="checked" />
 +        {icon name="flag_green" title="site public"}
 +      </div>
 +      Informations générales
 +    </th>
    </tr>
    <tr>
      <td>
 -      <span class="titre">Nom d'usage</span><br />
 -      {if $smarty.session.sexe}
 -      <span class="comm">(Notamment nom d'épouse)</span>
 -      {else}
 -      <span class="comm">(si différent de {$nom} seulement)</span>
 -      {/if}
 +      <span class="titre">Promotion</span>
      </td>
      <td>
 -      <span class="nom">{$nom_usage|default:"Aucun"}</span>
 -      <span class="lien"><a href="profile/usage">{if $nom_usage}modifier{else}Faire une demande{/if}</a></span>
 +      {if !$promo_choice}
 +        <span class="nom">{$promo_display}</span>
 +      {else}
 +        <select name="promo_display">
 +        {foreach from=$promo_choice item="promo_to_display"}
 +          <option value="{$promo_to_display}" {if $promo_to_display eq $promo_display}selected="selected"{/if}>{$promo_to_display}</option>
 +        {/foreach}
 +        </select>
 +      {/if}
 +      <span class="lien"><a href="profile/orange" {if ($grad_year -3 == $entry_year)} {popup text="pour les oranges"}{/if}>{icon name="page_edit" title="modifier"}</a></span>
      </td>
    </tr>
    <tr>
 -    <td class="titre">Date de naissance</td>
 +    <td>
 +      <span class="titre">Date de naissance</span>
 +    </td>
      <td><input type="text" {if $errors.naissance}class="error"{/if} name="naissance" value="{$naissance}" /></td>
    </tr>
    <tr>
      </td>
      <td>
        <select name="nationalite">
 -        {select_nat valeur=$nationalite}
 +        {select_nat valeur=$nationalite pad=1}
        </select>
 +      <a href="javascript:addNationality();">{icon name=add title="Ajouter une nationalité"}</a>
      </td>
    </tr>
 -  <tr class="pair">
 +  <tr id="nationalite2" {if !$nationalite2}style="display: none"{/if}>
 +    <td></td>
      <td>
 -      <span class="titre">Application</span><br />
 -      <span class="comm">(4e année de l'X)</span>
 -    </td>
 -    <td>
 -      <select name="appli1[id]" onchange="fillType(this.form['appli1[type]'], this.selectedIndex-1);">
 -        {applis_options selected=$appli1.id}
 -      </select>
 -      <br />
 -      <input type="hidden" name="appli1_tmp" value="{$appli1.type}" />
 -      <select name="appli1[type]">
 -        <option value=""></option>
 +      <select name="nationalite2">
 +        {select_nat valeur=$nationalite2 pad=1}
        </select>
 +      <a href="javascript:delNationality('2');">{icon name=cross title="Supprimer cette nationalité"}</a>
      </td>
    </tr>
 -  <tr class="pair">
 -    <td>
 -      <span class="titre">Post-application</span>
 -    </td>
 +  <tr id="nationalite3" {if !$nationalite3}style="display: none"{/if}>
 +    <td></td>
      <td>
 -      <select name="appli2[id]" onchange="fillType(this.form['appli2[type]'], this.selectedIndex-1);">
 -        {applis_options selected=$appli2.id}
 -      </select>
 -      <br />
 -      <input type="hidden" name="appli2_tmp" value="{$appli2.type}" />
 -      <select name="appli2[type]">
 -        <option value=""></option>
 +      <select name="nationalite3">
 +        {select_nat valeur=$nationalite3 pad=1}
        </select>
 +      <a href="javascript:delNationality('3');">{icon name=cross title="Supprimer cette nationalité"}</a>
      </td>
    </tr>
 -  <tr class="pair">
 +</table>
 +
 +<table class="bicol" style="margin-bottom: 1em" summary="Profil&nbsp;: Formations">
 +  <tr>
 +    <th colspan="2">
 +      <div class="flags" style="float: left">
 +        <input type="checkbox" disabled="disabled" checked="checked" />
 +        {icon name="flag_green" title="site public"}
 +      </div>
 +      Formations
 +    </th>
 +  </tr>
 +  {foreach from=$edus key=eduid item=edu}
 +    {cycle values="impair, pair" assign=class}
 +    {include file="profile/general.edu.tpl" eduid=$eduid edu=$edu edu_fields=$edu_fields class=$class}
 +  {/foreach}
 +  {if $edus|@count eq 0}
 +    {cycle values="impair, pair" assign=class}
 +    {include file="profile/general.edu.tpl" eduid=0 edu=0 class=$class}
 +  {/if}
 +  {cycle values="impair, pair" assign=class}
 +  {assign var=eduaddid value=$edus|@count}
 +  <tr id="edu_add" class="edu_{$eduaddid} {$class}">
 +    <td colspan="2">
 +      <div class="center" style="clear: both; padding-top: 4px;">
 +        <a href="javascript:addEdu();">
 +          {icon name=add title="Ajouter une formation"} Ajouter une formation
 +        </a>
 +      </div>
 +    </td>
 +  </tr>
 +  <tr class="{$class}">
      <td class="center" colspan="2">
        <small>Si ta formation ne figure pas dans la liste,
        <a href="mailto:support@{#globals.mail.domain#}">contacte-nous</a>.</small>
      </th>
    </tr>
    <tr>
 -    <td>
 -      <span class="flags">
 -        <input type="checkbox" checked="checked" disabled="disabled" />
 -        {icon name="flag_red" title="privé"}
 -      </span>&nbsp;
 -      <span class="titre">Surnom</span>
 -    </td>
 -    <td>
 -      <input type="text" size="35" maxlength="64"
 -             {if $errors.nick}class="error"{/if} name="nick" value="{$nick}" />
 +    <td colspan="2">
 +      <span class="titre">Téléphones personnels</span>
      </td>
    </tr>
    <tr>
 -    <td>
 -      <span class="titre">Téléphone mobile</span>
 -    </td>
 -    <td>
 -      <input type="text" size="18" maxlength="18" name="mobile"
 -             {if $errors.mobile}class="error"{/if} value="{$mobile}" />
 -      <span class="flags">
 -        {include file="include/flags.radio.tpl" name="mobile_pub" val=$mobile_pub}
 -      </span>
 +    <td colspan="2">
 +      {foreach from=$tels key=telid item=tel}
 +        <div id="tels_{$telid}" style="clear: both; padding-top: 4px; padding-bottom: 4px">
 +          {include file="profile/phone.tpl" prefname='tels' prefid='tels' telid=$telid tel=$tel}
 +        </div>
 +      {/foreach}
 +      {if $tels|@count eq 0}
 +        <div id="tels_0" style="clear: both; padding-top: 4px; padding-bottom: 4px">
 +          {include file="profile/phone.tpl" prefname='tels' preid='tels' telid=0 tel=0}
 +        </div>
 +      {/if}
 +      <div id="tels_add" class="center" style="clear: both; padding-top: 4px;">
 +        <a href="javascript:addTel('tels', 'tels');">
 +          {icon name=add title="Ajouter un téléphone"} Ajouter un téléphone
 +        </a>
 +      </div>
      </td>
    </tr>
 +  {if $email_error}
 +    {include file="include/emails.combobox.tpl" name="email_directory" val=$email_directory_error error=$email_error i="0"}
 +  {else}{include file="include/emails.combobox.tpl" name="email_directory" val=$email_directory error=$email_error i="0"}{/if}
    <tr>
 -    <td>
 -      <span class="flags">
 -        <label><input type="checkbox" name="web_pub" {if $web_pub eq 'public'}checked="checked"{/if} />
 -        {icon name="flag_green" title="site public"}</label>
 -      </span>&nbsp;
 -      <span class="titre">Page web Perso</span>
 +    <td colspan="2">
 +      <span class="titre">Messageries, networking et sites web</span>
      </td>
 -    <td>
 -      <input type="text" size="35" maxlength="95" name="web"
 -             {if $errors.web}class="error"{/if} value="{$web}" />
 +  </tr>
 +  {foreach from=$networking item=network key=id}
 +    {include file="profile/general.networking.tpl" nw=$network i=$id}
 +  {/foreach}
 +  <tr id="networking">
 +    <script type="text/javascript">//<![CDATA[
 +      var nw_list = new Array();
 +      {foreach from=$network_list item=network}
 +        nw_list['{$network.name}'] = {$network.type};
 +      {/foreach}
 +    //]]></script>
 +    <td colspan="2">
 +      <div id="nw_add" class="center">
 +        <a href="javascript:addNetworking();">
 +          {icon name=add title="Ajouter une adresse"} Ajouter une adresse
 +        </a>
 +      </div>
      </td>
    </tr>
 +<!--  <tr id="networking">
 +    <td colspan="2">
 +      <div style="float: left; width: 200px;">
 +        <span class="titre" style="margin-left:1em;">Type à ajouter</span>
 +      </div>
 +      <div style="float: left;">
 +        <div id="nw_type_ac" style="background-color: white; border: solid 1px black; position: absolute; width: 208px; display: none">TEST</div>
 +        <input type="text" size="30" id="nw_type" name="nw_type" onkeyup="updateNetworking()">
 +        <span id="nw_add" style="display: none">
 +          <a href="javascript:addNetworking();">{icon name=add title="Ajouter cette adresse"}</a>
 +        </span>
 +      </div>
 +    </td>
 +  </tr>-->
    <tr class="pair">
      <td>
        <div>
            <label><input type="checkbox" name="freetext_pub" {if $freetext_pub eq 'public'}checked="checked"{/if} />
            {icon name="flag_green" title="site public"}</label>
          </span>&nbsp;
 -        <span class="titre">Complément libre</span><br />
 -        <span class="comm">Commentaire ? ICQ ? etc...</span>
 +        <span class="titre">Commentaire</span>
        </div>
        <div class="smaller" style="margin-top: 30px">
          <a href="wiki_help/notitle" class="popup3">
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -22,9 -22,6 +22,9 @@@
  
  {assign var=jobid value="job_`$i`"}
  {assign var=jobpref value="jobs[`$i`]"}
 +{assign var=sector_text value="sector_text_"|cat:$i}
 +{assign var=sector value="sector_"|cat:$i}
 +{assign var=entreprise value="entreprise_"|cat:$i}
  <div id="{$jobid}">
    <input type="hidden" name="{$jobpref}[removed]" value="0" />
    <input type="hidden" name="{$jobpref}[new]" value="{if $new}1{else}0{/if}" />
            {include file="include/flags.radio.tpl" name="`$jobpref`[pub]" val=$job.pub}
          </div>
          Entreprise n°{$i+1}&nbsp;:
 +        {if $job.tmp_name}{$job.tmp_name} <small>(en cours de validation)</small>{else}
          <input type="text" class="enterprise_name {if $job.name_error}error{/if}" size="35" maxlength="100"
                 name="{$jobpref}[name]" value="{$job.name}" />
 +        {/if}
          <a href="javascript:removeJob('{$jobid}', '{$jobpref}')">
            {icon name=cross title="Supprimer cet emploi"}
          </a>
        </th>
      </tr>
 -    <tr>
 -      <td class="titre">Page Web</td>
 +    {if !$job.tmp_name}
 +    <tr class="{$entreprise}">
 +      <td class="center" colspan="2">
 +        <small>Si ton entreprise ne figure pas dans la liste,
 +        <a href="javascript:addEntreprise({$i})">clique ici</a> et complète les informations la concernant.</small>
 +      </td>
 +    </tr>
 +    {/if}
 +    <tr class="{$entreprise}" style="display: none">
 +      <td class="titre">Acronyme</td>
        <td>
 -        <input type="text" size="35" maxlength="255" {if $job.web_error}class="error"{/if}
 -               name="{$jobpref}[web]" value="{$job.web}" />
 +        <input type="text" size="35" maxlength="255" {if $job.acronym_error}class="error"{/if}
 +               name="{$jobpref}[acronym]" value="{$job.acronym}" />
        </td>
      </tr>
 -    <tr>
 +    <tr class="{$entreprise}" style="display: none">
 +      <td class="titre">Page web</td>
 +      <td>
 +        <input type="text" size="35" maxlength="255" {if $job.hq_web_error}class="error"{/if}
 +               name="{$jobpref}[hq_web]" value="{$job.hq_web}" />
 +      </td>
 +    </tr>
 +    <tr class="{$entreprise}" style="display: none">
 +      <td class="titre">Email de contact</td>
 +      <td>
 +        <input type="text" maxlength="60" {if $job.hq_email_error}class="error"{/if}
 +               name="{$jobpref}[hq_email]" value="{$job.hq_email}" />
 +      </td>
 +    </tr>
 +    <!--<tr class="{$entreprise}" style="display: none">
 +      <td colspan="2">
 +        <div style="float: left">
 +          <div class="titre">Adresse du siège</div>
 +          <div style="margin-top: 20px; clear: both">
 +            {include file="geoloc/form.address.tpl" name="`$jobpref`[hq_adr]" id="`$jobid`_adr" adr=$job.hq_adr}
 +          </div>
 +        </div>
 +      </td>
 +    </tr>-->
 +    <tr class="{$entreprise}" style="display: none">
 +      <td class="titre">Téléphone</td>
 +      <td>
 +        <input type="text" maxlength="28" {if $job.hq_tel_error}class="error"{/if}
 +               name="{$jobpref}[hq_tel]" value="{$job.hq_tel}" />
 +      </td>
 +    </tr>
 +    <tr class="{$entreprise}" style="display: none">
 +      <td class="titre">Fax</td>
 +      <td>
 +        <input type="text" maxlength="28" {if $job.hq_fax_error}class="error"{/if}
 +               name="{$jobpref}[hq_fax]" value="{$job.hq_fax}" />
 +      </td>
 +    </tr>
 +
 +    <tr class="pair">
 +      <td colspan="2" class="center" style="font-style: italic">Ta place dans l'entreprise</td>
 +    </tr>
 +    <tr class="pair {$sector_text}">
        <td class="titre">Secteur d'activité</td>
        <td>
 +        <input type="text" class="sector_name {if $job.sector_error}error{/if}" size="35" maxlength="100"
 +               name="{$jobpref}[sss_secteur_name]" value="{$job.sss_secteur_name}" />
 +        <a href="javascript:displayAllSector({$i})">{icon name="table" title="Tous les secteurs"}</a>
 +      </td>
 +    </tr>
 +    <tr class="pair {$sector}" style="display: none">
 +      <td class="titre" rowspan="3">Secteur d'activité</td>
 +      <td>
          <select name="{$jobpref}[secteur]" onchange="updateJobSecteur({$i}, '{$jobid}', '{$jobpref}', ''); return true;">
            <option value="">&nbsp;</option>
            {foreach from=$secteurs item=secteur}
          </select>
        </td>
      </tr>
 -    <tr>
 -      <td class="titre">Sous-secteur d'activité</td>
 +    <tr class="pair {$sector}" style="display: none">
        <td id="{$jobid}_ss_secteur">
          <input type="hidden" name="{$jobpref}[ss_secteur]" value="{$job.ss_secteur|default:'-1'}" />
 -      </td> 
 +      </td>
      </tr>
 -    <tr>
 -      <td class="titre">Poste occupé</td>
 -      <td>
 -        <input type="text" size="35" maxlength="120" {if $job.poste_error}class="error"{/if}
 -               name="{$jobpref}[poste]" value="{$job.poste}" />
 +    <tr class="pair {$sector}" style="display: none">
 +      <td id="{$jobid}_sss_secteur">
 +        <input type="hidden" name="{$jobpref}[sss_secteur]" value="{$job.sss_secteur|default:'-1'}" />
        </td>
      </tr>
 -    <tr>
 +    <tr class="pair">
        <td class="titre">Fonction occupée</td>
        <td>
          <select name="{$jobpref}[fonction]">
          </select>
        </td>
      </tr>
 -    <tr class="titre">
 -      <td class="center" colspan="2">
 -        <small>Si des informations font défaut dans les listes ci-dessus,
 -        <a href="mailto:support@{#globals.mail.domain#}">contacte-nous</a>.</small>
 -      </td>
 -    </tr>
      <tr class="pair">
 -      <td colspan="2">
 -        <span class="titre">Email professionnel&nbsp;:</span>
 -        <input type="text" size="30" maxlength="60" {if $job.email_error}class="error"{/if}
 -               name="{$jobpref}[email]" value="{$job.email}" />
 -        <span class="flags">
 -          {include file="include/flags.radio.tpl" name="`$jobpref`[email_pub]" val=$job.mail_pub}
 -        </span>
 +      <td class="titre">Description</td>
 +      <td>
 +        <input type="text" size="35" maxlength="120" {if $job.description_error}class="error"{/if}
 +           name="{$jobpref}[description]" value="{$job.description}" /><br /><br />
        </td>
      </tr>
      <tr class="pair">
          <div style="float: left">
            <div class="titre">Adresse</div>
            <div class="flags">
 -            {include file="include/flags.radio.tpl" name="`$jobpref`[adr][pub]" val=$job.adr.pub}
 +            {include file="include/flags.radio.tpl" name="`$jobpref`[w_adr][pub]" val=$job.w_adr.pub}
            </div>
            <div style="margin-top: 20px; clear: both">
 -            {include file="geoloc/form.address.tpl" name="`$jobpref`[adr]" id="`$jobid`_adr" adr=$job.adr}
 +            {include file="geoloc/form.address.tpl" name="`$jobpref`[w_adr]" id="`$jobid`_adr" adr=$job.w_adr}
            </div>
          </div>
          <div style="float: right; width: 50%">
 -          <div class="titre">Téléphone</div>
 -          <div class="flags">
 -            {include file="include/flags.radio.tpl" name="`$jobpref`[tel_pub]" val=$job.tel_pub}
 +          {include file="include/emails.combobox.tpl" name=$jobpref|cat:'[w_email]' val=$job.w_email
 +          class="pair" i=$i error=$job.w_email_error prefix="w_" pub=$job.w_email_pub isjob="1" id=$i}
 +          <div class="titre">Page perso</div>
 +          <input type="text" size="25" maxlength="255" {if $job.w_web_error}class="error"{/if}
 +               name="{$jobpref}[w_web]" value="{$job.w_web}" />
 +        </div>
 +      </td>
 +    </tr>
 +    <tr class="pair">
 +      <td colspan="2">
 +        {foreach from=$job.w_tel key=t item=tel}
 +          <div id="{"`$jobid`_w_tel_`$t`"}" style="clear: both">
 +            {include file="profile/phone.tpl" prefname="`$jobpref`[w_tel]" prefid="`$jobid`_w_tel" telid=$t tel=$tel}
 +          </div>
 +        {/foreach}
 +        {if $job.w_tel|@count eq 0}
 +          <div id="{"`$jobid`_w_tel_0"}" style="clear: both">
 +            {include file="profile/phone.tpl" prefname="`$jobpref`[w_tel]" prefid="`$jobid`_w_tel" telid=0 tel=0}
            </div>
 -          <table style="clear: both">
 -            <tr>
 -              <td>Bureau&nbsp;:</td>
 -              <td>
 -                <input type="text" size="18" maxlength="18" {if $job.tel_error}class="error"{/if}
 -                       name="{$jobpref}[tel]" value="{$job.tel}" />
 -              </td>
 -            </tr>
 -            <tr>
 -              <td>Fax&nbsp;:</td>
 -              <td>
 -                <input type="text" size="18" maxlength="18" {if $job.fax_error}class="error"{/if}
 -                       name="{$jobpref}[fax]" value="{$job.fax}" /></td>
 -            </tr>
 -            <tr>
 -              <td>Mobile&nbsp;:</td>
 -              <td>
 -                <input type="text" size="18" maxlength="18" {if $job.mobile_error}class="error"{/if}
 -                       name="{$jobpref}[mobile]" value="{$job.mobile}" />
 -              </td>
 -            </tr>
 -          </table>
 +        {/if}
 +        <div id="{$jobid}_w_tel_add" class="center" style="clear: both; padding-top: 4px;">
 +          <a href="javascript:addTel('{$jobid}_w_tel', '{$jobpref}[w_tel]')">
 +            {icon name=add title="Ajouter un numéro de téléphone"} Ajouter un numéro de téléphone
 +          </a>
          </div>
        </td>
      </tr>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  {**************************************************************************}
  
  <?xml version="1.0" encoding="utf-8"?>
 -<select name="jobs[{$id}][ss_secteur]">
 +<select name="jobs[{$id}][ss_secteur]"
 + {if ($change)}onchange="updateJobSousSecteur({$id}, '{$jobid}', '{$jobpref}', ''); return true;"{/if}>
    <option value=""></option>
    {iterate from=$ssecteurs item=ssecteur}
 +  {if $ssecteur.optgroup}
 +  {if $gp}
 +  </optgroup>
 +  {/if}
 +  <optgroup label="{$ssecteur.label}">
 +  {assign var=1 name=gp}
 +  {else}
    <option value="{$ssecteur.id}" {if $ssecteur.id eq $sel}selected="selected"{/if}>{$ssecteur.label}</option>
 +  {/if}
 +  {if $gp}
 +  </optgroup>
 +  {/if}
    {/iterate}
  </select>
  
index a4263ac,0000000..63fd1de
mode 100644,000000..100644
--- /dev/null
@@@ -1,31 -1,0 +1,31 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +<?xml version="1.0" encoding="utf-8"?>
 +<select name="jobs[{$id}][sss_secteur]">
 +  <option value=""></option>
 +  {iterate from=$sssecteurs item=sssecteur}
 +  <option value="{$sssecteur.id}" {if $sssecteur.id eq $sel}selected="selected"{/if}>{$sssecteur.label}</option>
 +  {/iterate}
 +</select>
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
    <a href="javascript:addJob()">
      {icon name=add title="Ajouter un emploi"} Ajouter un emploi
    </a>
 +  <br/><br/>
  </div>
  
 +<table class="bicol" style="margin-bottom: 1em" summary="Corps">
 +  <tr>
 +    <th colspan="2">
 +      <div class="flags" style="float: left; text-align: left">
 +        {include file="include/flags.radio.tpl" name="corps[pub]" val=$corps.pub}
 +      </div>
 +      Corps
 +    </th>
 +  </tr>
 +  <tr>
 +    <td class="titre">Corps d'origine</td>
 +    <td>
 +      <select name="corps[original]">
 +        {foreach from=$original_corps item=o_corps}
 +        <option value="{$o_corps.id}" {if $o_corps.id eq $corps.original}selected="selected"{/if}>{$o_corps.name}</option>
 +        {/foreach}
 +      </select>
 +    </td>
 +  </tr>
 +  <tr>
 +    <td class="titre">Corps actuel</td>
 +    <td>
 +      <select name="corps[current]">
 +        {foreach from=$current_corps item=c_corps}
 +        <option value="{$c_corps.id}" {if $c_corps.id eq $corps.current}selected="selected"{/if}>{$c_corps.name}</option>
 +        {/foreach}
 +      </select>
 +    </td>
 +  </tr>
 +  <tr>
 +    <td class="titre">Grade</td>
 +    <td>
 +      <select name="corps[rank]">
 +        {foreach from=$corps_rank item=rank}
 +        <option value="{$rank.id}" {if $rank.id eq $corps.rank}selected="selected"{/if}>{$rank.name}</option>
 +        {/foreach}
 +      </select>
 +    </td>
 +  </tr>
 +</table>
 +
  <table class="bicol" summary="CV" style="margin-top: 1.5em">
    <tr>
      <th>
index 8e6244d,0000000..148f3b6
mode 100644,000000..100644
--- /dev/null
@@@ -1,57 -1,0 +1,57 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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>Les différents types de noms</h1>
 +<table class="bicol" style="margin-bottom: 1em" summary="Explications sur les différents types de noms">
 +  <tr>
 +    <th>Type</th>
 +    <th>Description</th>
 +    <th>Confidentialité&nbsp;&sup1;</th>
 +    <th>Prise en compte de la particule&nbsp;&sup2;</th>
 +  <tr>
 +  </tr>
 +  {iterate from=$types item=type}
 +  <tr>
 +    <td>{$type.name}</td>
 +    <td>{$type.explanations}</td>
 +    <td class="center">
 +      {if $type.public}
 +        {icon name="flag_green" title="site public"}
 +      {else}
 +        {icon name="flag_red" title="site privé"}
 +      {/if}
 +    </td>
 +    <td class="center">{if $type.has_particle}Oui{else}Non{/if}</td>
 +  </tr>
 +  {/iterate}
 +</table>
 +
 +<h2>Légende :</h2>
 +<ul>
 +<li>&sup1;&nbsp;{icon name="flag_green" title="site public"} signifie que les données sont visibles
 +  sur la partie publique du site alors que {icon name="flag_red" title="site privé"} indique
 +  qu'elles sont cantonnées au site privé.</li>
 +<li>&sup2;&nbsp;Pour les types concernés, il faut cocher la case en bout de ligne si le nom débute
 +  par une particule, comme cela tu seras correctement classé dans l'ordre alphabétique.</li>
 +</ul>
 +
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  {else}
  
  <p>
 -  Afin de pouvoir être considéré(e) à la fois dans ta promotion d'origine et ta
 +  Afin de pouvoir être considéré{if $sexe}e{/if} à la fois dans ta promotion d'origine et ta
    ou tes promotions d'adoption tu peux entrer ici ton année de sortie de l'école.
    Plus précisément, il s'agit de l'année d'entrée en quatrième année ou année d'application.
 -  Pour tes cocons d'origine (X{$promo}) il s'agit de l'année {math equation="a + b" a=$promo b=3}.
 +  Pour tes cocons d'origine ({$promo_display}) il s'agit de l'année {math equation="a + b" a=$promo b=3}.
  </p>
  
  <br />
index 40715be,0000000..de83b74
mode 100644,000000..100644
--- /dev/null
@@@ -1,51 -1,0 +1,51 @@@
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
 +{**************************************************************************}
 +{*                                                                        *}
++{*  Copyright (C) 2003-2009 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               *}
 +{*                                                                        *}
 +{**************************************************************************}
 +
 +{assign var=telpref value="`$prefname`[`$telid`]"}
 +{assign var=id value="`$prefid`_`$telid`"}
 +<div class="titre" style="float: left; width: 2.5em">N°{$telid+1}</div>
 +<div style="float: left;">
 +  <select name="{$telpref}[type]">
 +    <option value="fixed"{if $tel.type eq 'fixed'} selected="selected"{/if}>Fixe</option>
 +    <option value="mobile"{if $tel.type eq 'mobile'} selected="selected"{/if}>Mobile</option>
 +    <option value="fax"{if $tel.type eq 'fax'} selected="selected"{/if}>Fax</option>
 +  </select>
 +  <input type="hidden" name="{$telpref}[removed]" value="0"/>
 +  <input type="text" size="19" maxlength="28" name="{$telpref}[tel]" {if $tel.error}class="error"{/if} value="{$tel.tel}" />
 +  <a href="javascript:removeTel('{$id}')">
 +    {icon name=cross title="Supprimer ce numéro de téléphone"}
 +  </a>
 +  <a id="{$id}_addComment" href="javascript:addPhoneComment('{$id}', '{$telpref}')" {if $tel.comment neq ''}style="display:none" {/if}>
 +    {icon name=comments title="Ajouter un commentaire"}
 +  </a>
 +</div>
 +<div style="float: right" class="flags">
 +  {include file="include/flags.radio.tpl" name="`$telpref`[pub]" val=$tel.pub}
 +</div>
 +<div id="{$id}_comment" style="clear: both;{if $tel.comment eq ''} display:none{/if}">
 +  Commentaire :
 +  <input type="text" size="45" maxlength="80" name="{$telpref}[comment]" {if $tel.error}class="error"{/if} value="{$tel.comment}"/>
 +  <a href="javascript:removePhoneComment('{$id}', '{$telpref}')">
 +    {icon name=cross title="Supprimer le commentaire"}
 +  </a>
 +</div>
 +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *}
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
@@@ -50,20 -50,6 +50,20 @@@ function chgMainWinLoc(strPage
        {if $x.gpxs_join}<div><em class="intitule">Groupe{if count($x.gpxs) > 1}s{/if} et institution{if count($x.gpxs) > 1}s{/if} X&nbsp;: </em>
        <span><br/>{$x.gpxs_join|smarty:nodefaults}</span></div>{/if}
      {/if}
 +    {if $x.networking}
 +      <h2>Sur le web...</h2>
 +      {foreach from=$x.networking item=network}
 +        <img style="width: auto; padding: 0" src="profile/networking/{$network.type}" alt="{$network.name}" title="{$network.name}"/>
 +        {if $network.filter == 'web'}
 +          <a href="{$network.address}">{$network.address}</a>
 +        {elseif $network.link != ''}
 +          <a href="{$network.link}">{$network.address}</a>
 +        {else}
 +          {$network.address}
 +        {/if}
 +        <br/>
 +      {/foreach}
 +    {/if}
      {if $x.freetext}
      <h2>Commentaires&nbsp;:</h2>
      <span>{$x.freetext|miniwiki|smarty:nodefaults}</span>
    <div id="fiche_identite" class="part">
      <div class="civilite">
        {if $user->isFemale()}&bull;{/if}
 -      {$user->fullName()}{if $x.nom_usage neq ""} ({$x.nom}){/if}
 +      <span {if $x.name_tooltip neq ""}class="hinted" title="{$x.name_tooltip}"{/if}>{$x.name_display}</span>
        {if $logged}
        {if $x.nickname} (alias {$x.nickname}){/if}
        {/if}
 -      {if $x.web}&nbsp;<a href="{$x.web}">{icon name="world_go" title="Site Web"}</a>{/if}
        {if $logged}
        &nbsp;{if !$x.dcd}<a href="vcard/{$user->login()}.vcf">{*
          *}{icon name=vcard title="Afficher la carte de visite"}</a>{/if}
        le {$x.date|date_format}
      </div>
      {/if}
 -    {if $logged || $x.mobile}
 +    {if $logged || $x.tels}
      <div class="contact">
        {if $logged}
        <div class='email'>
          {/if}
        </div>
        {/if}
 -      {if $x.mobile}
 -      <div class="mob">
 -        <em class="intitule">Mobile&nbsp;: </em>{$x.mobile}
 -      </div>
 +      {if $x.tels}
 +        {display_phones tels=$x.tels}
        {/if}
        <div class='spacer'></div>
      </div>
      {/if}
      <div class='formation'>
 -      {if $x.iso3166}
 -      <img src='images/flags/{$x.iso3166}.gif' alt='{$x.nationalite}' height='11' title='{$x.nationalite}' />&nbsp;
 +      {if $x.iso3166_1}
 +      <img src='images/flags/{$x.iso3166_1}.gif' alt='{$x.nationalite}' height='11' title='{$x.nationalite}' />&nbsp;
        {/if}
 -      X {$user->promo()}
 -      {if $x.promo_sortie && ($x.promo_sortie-3 > $x.promo)}
 -        - X {math equation="a-b" a=$x.promo_sortie b=3}
 +      {if $x.iso3166_2}
 +      <img src='images/flags/{$x.iso3166_2}.gif' alt='{$x.nationalite2}' height='11' title='{$x.nationalite2}' />&nbsp;
        {/if}
 -      {if $x.applis_join}
 -        &nbsp;-&nbsp;Formation&nbsp;: {$x.applis_join|smarty:nodefaults}
 +      {if $x.iso3166_3}
 +      <img src='images/flags/{$x.iso3166_3}.gif' alt='{$x.nationalite3}' height='11' title='{$x.nationalite3}' />&nbsp;
        {/if}
 +      {$user->promo()}
        {if $logged && $x.is_referent}
 -      [<a href="referent/{$user->login()}" class='popup2'>Ma fiche référent</a>]
 +      [<a href="referent/{$x.forlife}" class='popup2'>Ma fiche référent</a>]
 +      {/if}
 +      {if $x.education}
 +        &nbsp;-&nbsp;Formation&nbsp;:
 +        <ul>
 +        {foreach from=$x.education item="edu"}
 +          <li>{$edu|smarty:nodefaults}</li>
 +        {/foreach}
 +        </ul>
 +      {/if}
 +      {if $x.corps}
 +        {$x.corps|smarty:nodefaults}
        {/if}
      </div>
    </div>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  
      if (schoolId) {
        $(".autocomplete[@name='schoolTxt']").addClass('hidden_valid');
 -
 -      $("[@name='diploma']").parent().load(baseurl + 'list/diploma/', { school:schoolId }, function() {
 -          if ($("select[@name='diploma']").children("option").size() > 1) {
 -            $("select[@name='diploma']").attr('value', '{/literal}{$smarty.request.diploma}{literal}');
 -          } else {
 -            $("select[@name='diploma']").attr('value', '');
 -          }
 -        });
      } else {
        $(".autocomplete[@name='schoolTxt']").removeClass('hidden_valid');
 -
 -      $("select[@name='diploma']").attr('value', '');
      }
 +
 +    $("[@name='diploma']").parent().load(baseurl + 'list/diploma/', { school:schoolId }, function() {
 +        $("select[@name='diploma']").attr('value', '{/literal}{$smarty.request.diploma}{literal}');
 +      });
    }
  
    // when choosing autocomplete from list, must validate
@@@ -318,8 -324,8 +318,8 @@@ checked="checked"{/if}/>Chercher unique
        </td>
      </tr>
      <tr>
 -      <td>Poste</td>
 -      <td><input type="text" class="autocomplete" name="poste" size="32" value="{$smarty.request.poste}" /></td>
 +      <td>Description</td>
 +      <td><input type="text" class="autocomplete" name="description" size="32" value="{$smarty.request.description}" /></td>
      </tr>
      <tr>
        <td>Secteur</td>
        <td>Commentaire contient</td>
        <td><input type="text" name="free" size="32" value="{$smarty.request.free}" /></td>
      </tr>
 +    <tr>
 +      <td>Numéro de téléphone</td>
 +      <td><input type="text" name="phone_number" size="32" value="{$smarty.request.phone_number}"/></td>
 +    </tr>
 +    <tr>
 +      <td style="vertical-align: middle">
 +        <span>Networking et sites webs</span>
 +      </td>
 +      <td>
 +        <table>
 +          <tr>
 +            <td style="padding-left: 0px;">
 +              <input type="text" name="networking_address" size="32" value="{$smarty.request.networking_address}" />
 +            </td>
 +            <td>
 +              <input type="text" name="networking_typeTxt" class="autocomplete" size="10" value="{$smarty.request.networking_typeTxt}" />
 +              <input name="networking_type" class="autocompleteTarget" type="hidden" value="{$smarty.request.networking_type}"/>
 +              <a href="networking_type" class="autocompleteToSelect">{icon name="table" title="Tous les types d'adresse"}</a>
 +            </td>
 +          </tr>
 +        </table>
 +      </td>
 +    </tr>
          {if $smarty.session.auth ge AUTH_COOKIE}
      <tr>
        <td colspan="2">
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
  <select name="diploma">
  <option value=""> - </option>
  {section name=diploma loop=$choix_diplomas}
 -<option value="{$choix_diplomas[diploma]}">
 -  {$choix_diplomas[diploma]}
 +{assign var=i value=$choix_diplomas[diploma]}
 +{assign var=id value=$i-1}
 +<option value="{$i}">
 +  {$name_diplomas[$id]}
  </option>
  {/section}
  </select>
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
      {assign var="has_cs" value="true"}
    {/if}
    {/iterate}
 -  <tr class="impair"> 
 +  <tr class="impair">
      <td class="half">
        {if !$has_cs}Aucun sondage en cours{/if}
        {if $smarty.session.auth}<a style="display: block; float: right;" href="survey/edit/new">{icon name=page_edit} Proposer un sondage</a>{/if}
 -    </td> 
 -  </tr> 
 +    </td>
 +  </tr>
  </table>
  
  <br />
@@@ -1,6 -1,6 +1,6 @@@
  {**************************************************************************}
  {*                                                                        *}
- {*  Copyright (C) 2003-2008 Polytechnique.org                             *}
+ {*  Copyright (C) 2003-2009 Polytechnique.org                             *}
  {*  http://opensource.polytechnique.org/                                  *}
  {*                                                                        *}
  {*  This program is free software; you can redistribute it and/or modify  *}
          <td class="titre">Type de sondage&nbsp;:</td>
          <td>{$survey_modes[$survey.mode]}</td>
        </tr>
 -      {if $survey.mode != Survey::MODE_ALL} 
 +      {if $survey.mode != Survey::MODE_ALL}
        <tr>
 -        <td class="titre">Promotions&nbsp;:</td> 
 +        <td class="titre">Promotions&nbsp;:</td>
          <td>
 -          {if $survey.promos eq "#"} 
 -          erreur 
 -          {elseif $survey.promos eq ""} 
 -          aucune restriction 
 -          {else} 
 -          {$survey.promos} 
 +          {if $survey.promos eq "#"}
 +          erreur
 +          {elseif $survey.promos eq ""}
 +          aucune restriction
 +          {else}
 +          {$survey.promos}
            {/if}
          </td>
        </tr>
@@@ -93,7 -93,7 +93,7 @@@
  <p class="center">
    {if $survey_editmode}
    <a href='survey/edit/valid'>
 -    {icon name=tick} 
 +    {icon name=tick}
      {if $survey_updatemode}Enregistrer les modifications{else}Proposer ce sondage{/if}
    </a> |
    <a href='survey/edit/cancel'>
@@@ -1,6 -1,6 +1,6 @@@
  <?php
  /***************************************************************************
-- *  Copyright (C) 2003-2007 Polytechnique.org                              *
++ *  Copyright (C) 2003-2009 Polytechnique.org                              *
   *  http://opensource.polytechnique.org/                                   *
   *                                                                         *
   *  This program is free software; you can redistribute it and/or modify   *