Merge commit 'origin/master' into fusionax
authorStéphane Jacob <jacou@melix.net>
Mon, 1 Sep 2008 18:33:45 +0000 (20:33 +0200)
committerStéphane Jacob <jacou@melix.net>
Mon, 1 Sep 2008 18:33:45 +0000 (20:33 +0200)
1  2 
htdocs/css/default.css
htdocs/javascript/profile.js
include/user.func.inc.php
include/userset.inc.php
modules/profile.php
modules/search.php
plugins/function.select_nat.php
templates/include/minifiche.tpl

diff --combined htdocs/css/default.css
@@@ -107,10 -107,6 +107,10 @@@ p 
      background: inherit;
  }
  
 +.hinted {
 +    border-bottom: 1px dashed black;
 +}
 +
  input.error, textarea.error {
      background-color: #faa;
  }
@@@ -290,7 -286,7 +290,7 @@@ div.contact-list div.grayed 
  
  div.contact div.identity {
      float: left;
-     width: 89%;
+     width: 85%;
  }
  
  div.contact div.nom {
  div.contact div.bits {
      text-align: right;
      float: right;
-     width: 10%;
+     width: 14%;
  }
  
  div.contact div.long {
@@@ -24,14 -24,10 +24,14 @@@ 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++;
 +        }
 +        for (var j = 0; j < i; j++) {
 +            prepareType(j);
 +        }
          break;
        case 'poly':
          updateGroupSubLink(document.forms.prof_annu.groupesx_sub);
              updateJobSecteur(i, 'job_' + i, 'jobs[' + i + ']',
                               document.forms.prof_annu["jobs[" + i + "][ss_secteur]"].value);
          }
-         registerEnterpriseAutocomplete(-1);
+         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 addSearchName()
 +{
 +  var i = 0;
 +  while (document.getElementById('search_name_' + i) != null) {
 +      i++;
 +  }
 +  $('#add_search_name').before('<div id="search_name_' + i + '" style="padding:2px" class="center"></div>');
 +  Ajax.update_html('search_name_' + i, 'profile/ajax/searchname/' + i,function(){
 +    $('#search_name_'+i+' input')[1].focus();
 +  });
 +}
 +
 +function removeSearchName(i)
 +{
 +  if (document.getElementById('search_name_'+i+'_new') != null) {
 +    $('#search_name_'+i).remove();
 +  } else {
 +    removeObject('search_name_'+i, 'search_name['+i+']');
 +  }
 +}
 +
 +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
  
@@@ -270,74 -166,18 +270,74 @@@ function addAddress(
      Ajax.update_html('addresses_' + i + '_cont', 'profile/ajax/address/' + i, checkCurrentAddress);
  }
  
 -function addTel(id)
 +function addEdu()
  {
      var i = 0;
 -    var adid = 'addresses_' + id;
 -    var tel  = adid + '_tel_';
 -    while (document.getElementById(tel + i) != null) {
 +    var j = 0;
 +    var prefix  = 'edu_';
 +    var class_parity;
 +
 +    while (!$('#edu_add').hasClass(prefix + i)) {
 +        if ($('.' + prefix + i).length != 0) {
 +            j++;
 +        }
          i++;
      }
 -    $('#' + adid + '_add_tel').before('<div id="' + tel + i + '" style="clear: both"></div>');
 -    Ajax.update_html(tel + i, 'profile/ajax/tel/' + id + '/' + 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 prefix  = prefid + '_';
 +    while (document.getElementById(prefix + i) != null) {
 +        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
  
@@@ -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_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);
@@@ -276,8 -275,8 +276,8 @@@ function get_user_details_pro($uid, $vi
  {
      $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
 +                     gp.pays AS countrytxt, gr.name AS region, e.entrid,
 +                     e.pub, e.adr_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)
                      $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]);
          }
@@@ -359,7 -358,8 +359,8 @@@ function get_user_details_adr($uid, $vi
                       gp.pays AS countrytxt,a.region, a.regiontxt,
                       FIND_IN_SET('active', a.statut) AS active, a.adrid,
                       FIND_IN_SET('res-secondaire', a.statut) AS secondaire,
 -                     a.pub, gp.display
+                      FIND_IN_SET('courrier', a.statut) AS courier,
 +                     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)) {
@@@ -401,32 -402,26 +402,32 @@@ function &get_user_details($login, $fro
  {
      $reqsql = "SELECT  u.user_id, u.promo, u.promo_sortie, 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_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,
 -                       IF(gp.nat='',gp.pays,gp.nat) AS nationalite, gp.a2 AS iso3166,
 +                       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
 +                       (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  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')
 +           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 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  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)
                  WHERE  a.alias = {?}
               GROUP BY  u.user_id";
      $res  = XDB::query($reqsql, $from_uid, $login);
          $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
 +    $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
 +                     INNER JOIN  profile_education_enum        AS en ON (en.id = ed.eduid)
 +                     INNER JOIN  profile_education_degree_enum AS d  ON (d.id  = ed.degreeid)
 +                     INNER JOIN  profile_education_field_enum  AS f  ON (f.id  = ed.fieldid)
                            WHERE  uid={?}
 -                       ORDER BY  ordre", $uid);
 +                       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);
 +    $user['education'] = "";
 +    require_once('education.func.inc.php');
 +    if (list($name, $url, $degree, $grad_year, $field, $program) = $res->next()) {
 +        $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);
      }
 -    $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;
  }
  // }}}
@@@ -551,7 -528,7 +552,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 ++;
          }
      }
@@@ -569,17 -546,17 +570,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()
@@@ -684,6 -647,13 +685,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) {
      $res = XDB::query("SELECT adrid FROM adresses WHERE uid = {?} AND adrid >= 1 ORDER BY adrid", $uid);
      $adrids = $res->fetchColumn();
@@@ -763,6 -715,9 +764,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
@@@ -24,18 -24,18 +24,18 @@@ 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  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 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
  {
@@@ -63,8 -63,7 +63,7 @@@ class SearchSet extends UserSe
  
      public function __construct($quick = false, $no_search = false, $join = '', $where = '')
      {
-         require_once dirname(__FILE__).'/../modules/search/search.inc.php';
+         Platal::load('search', 'search.inc.php');
          if ($no_search) {
              return;
          }
@@@ -79,7 -78,7 +78,7 @@@
  
      private function getQuick($join, $where)
      {
-         require_once dirname(__FILE__).'/../modules/search/search.inc.php';
+         Platal::load('search', 'search.inc.php');
          global $globals;
          if (!S::logged()) {
              Env::kill('with_soundex');
@@@ -159,15 -158,15 +158,15 @@@ 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);
      }
  
                  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, es.label AS secteur, ef.fonction_fr AS fonction,
+                 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,
 +                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,
 +                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, edu2gram AS eduprogram2,
 +                ede3.name AS eduname3, ede3.url AS eduurl3, edd3.degree AS edudegree3,
 +                edu3.grad_year AS edugrad_year3, f3.field AS edufield3, edu3gram 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  emails         AS em  ON (em.uid = u.user_id AND em.flags = 'active')" .
 +        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 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)" .
                  (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') . ")"
                   : "");
      }
  
@@@ -262,23 -237,17 +261,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,
 -                a.alias AS forlife, m.expertise, mp.pid,
 -                ms.secteur, ms.ss_secteur";
 +        return "m.uid, u.promo,
 +                a.alias AS bestalias, m.expertise, mp.pid,
 +                ms.secteur, ms.ss_secteur,
 +                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)";
      }
  
      public function bounds()
@@@ -309,24 -278,23 +308,24 @@@ 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, a.alias AS forlife ";
 +        return "u.user_id, nd.display AS name_display, nd.tooltip AS name_tooltip, nd.sort AS name_sort, u.promo, a.alias AS forlife ";
      }
  
      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_names_display AS nd ON (nd.user_id = u.user_id)";
      }
  
      public function bounds()
@@@ -467,6 -435,7 +466,6 @@@ class GadgetView implements PlVie
      {
          return "u.user_id AS id,
                  u.*, a.alias AS forlife," .
 -                (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') . ")"
                   : "");
      }
  
diff --combined modules/profile.php
@@@ -24,50 -24,43 +24,50 @@@ 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/skill'         => $this->make_hook('ajax_skill',                 AUTH_COOKIE, 'user', NO_AUTH),
 +            'profile/ajax/searchname'    => $this->make_hook('ajax_searchname',            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/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'),
  
          );
      }
          exit;
      }
  
 +    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');
         $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/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');
          }
      }
  
 +    function handler_ajax_searchname(&$page, $snid)
 +    {
 +        header('Content-Type: text/html; charset=utf-8');
 +        $page->changeTpl('profile/general.searchname.tpl', NO_SKIN);
 +        $page->assign('i', $snid);
 +        $page->assign('sn', array());
 +        $page->assign('newsn', true);
 +    }
 +    
      function handler_p_orange(&$page)
      {
          $page->changeTpl('profile/orange.tpl');
              $x = substr($x, 0, strlen($x) - 4);
          }
  
-         $vcard = new VCard($x);
-         $vcard->do_page($page);
+         $vcard = new VCard();
+         $vcard->addUser($x);
+         $vcard->show();
      }
  
      function handler_admin_trombino(&$page, $uid = null, $action = null) {
          $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_medals(&$page, $action = 'list', $id = null) {
          $page->setTitle('Administration - Distinctions');
          $page->assign('title', 'Gestion des Distinctions');
diff --combined modules/search.php
@@@ -38,13 -38,6 +38,6 @@@ class SearchModule extends PLModul
          exit;
      }
  
-     function on_subscribe($forlife, $uid, $promo, $pass)
-     {
-         require_once 'user.func.inc.php';
-         user_reindex($uid);
-     }
      function form_prepare()
      {
          Platal::page()->assign('formulaire',1);
              $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' => "(a.cat = 'GroupesX' OR a.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' => '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),
 +                'networking_type' => array('field' => 'network_type', 'table' => 'profile_networking_enum',
 +                                           'text' => 'name', 'exact' => false),
 +                'groupex'         => array('field' => 'id', 'table' => 'groupex.asso',
 +                                           'text' => "(a.cat = 'GroupesX' OR a.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));
            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`';
 +            $unique = '`uid`';
              break;
            case 'firstname':
              $field = '`prenom`';
              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`)';
            case 'poste':
              $db = '`entreprises`';
              $field = '`poste`';
 -            $unique='`uid`';
 +            $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;
                                  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()) {
            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':
   ***************************************************************************/
  
  
 -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 ORDER BY text";
++    $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);
  }
  
      {if $smarty.session.auth ge AUTH_COOKIE}
      <div class="photo">
        <img src="photo/{if $c.inscrit}{$c.forlife}{else}{make_forlife nom=$c.nom prenom=$c.prenom promo=$c.promo}{/if}"
 -           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/{if $c.inscrit}{$c.forlife}{else}{make_forlife nom=$c.nom prenom=$c.prenom promo=$c.promo}{/if}" 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}
 +      X {$c.promo}{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>
  
@@@ -76,6 -64,8 +76,8 @@@
          {if !$c.dcd}
      <a href="vcard/{$c.forlife}.vcf">{*
      *}{icon name=vcard title="Afficher la carte de visite"}</a>
+     <a href="mailto:{$c.forlife}@{#globals.mail.domain#}">{*
+     *}{icon name=email title="Envoyer un email"}</a>
            {if $show_action eq ajouter}
      <a href="carnet/contacts?action={$show_action}&amp;user={$c.forlife}&amp;token={xsrf_token}">{*
      *}{icon name=add title="Ajouter à mes contacts"}</a>
        <tr>
          <td class="lt">Profession&nbsp;:</td>
          <td class="rt">
-           {$c.entreprise} {if $c.secteur}({$c.secteur}){/if}
-           {if $c.fonction}<br />{$c.fonction}{/if}
+           {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}
          </td>
        </tr>
        {/if}