Merge commit 'origin/fusionax' into account
authorFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 22 Feb 2009 14:25:25 +0000 (15:25 +0100)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Sun, 22 Feb 2009 14:25:25 +0000 (15:25 +0100)
Conflicts:

include/userset.inc.php
modules/payment.php
modules/payment/money/paypal.inc.php
modules/profile.php
modules/profile/addresses.inc.php
modules/search.php
modules/xnetevents/xnetevents.inc.php
templates/profile/groupesx.tpl

Signed-off-by: Florent Bruneau <florent.bruneau@polytechnique.org>
12 files changed:
1  2 
classes/xnetpage.php
configs/platal.ini
include/userset.inc.php
modules/events.php
modules/payment/money/paypal.inc.php
modules/profile.php
modules/profile/addresses.inc.php
modules/profile/jobs.inc.php
modules/profile/mentor.inc.php
modules/profile/page.inc.php
modules/search.php
templates/profile/groupesx.tpl

diff --combined classes/xnetpage.php
@@@ -87,7 -87,6 +87,6 @@@ class XnetPage extends PlPag
              if ($perms->hasFlag('groupannu')) {
                  $sub['annuaire du groupe'] = "$dim/annuaire";
                  $sub['trombinoscope'] = "$dim/trombi";
-                 $sub['planisphère'] = "$dim/geoloc";
              }
              if ($perms->hasFlag('groupmember')) {
                  if ($globals->asso('forum')) {
@@@ -139,10 -138,11 +138,10 @@@ function list_all_my_groups($params
      if (!S::logged()) {
          return;
      }
 -    $res = XDB::iterRow(
 -            "SELECT  a.nom, a.diminutif
 -               FROM  groupex.asso    AS a
 -         INNER JOIN  groupex.membres AS m ON m.asso_id = a.id
 -              WHERE  m.uid={?}", S::v('uid'));
 +    $res = XDB::iterRow('SELECT  a.nom, a.diminutif
 +                           FROM  groupex.asso    AS a
 +                     INNER JOIN  groupex.membres AS m ON m.asso_id = a.id
 +                          WHERE  m.uid = {?}', S::i('uid'));
      $links = '<a href="exit">déconnexion</a>';
      $html = '<div>Mes groupes (' . $links . ') :</div>';
      while (list($nom, $mini) = $res->next()) {
diff --combined configs/platal.ini
@@@ -17,14 -17,17 +17,16 @@@ password = "***
  web_user = "***"
  web_pass = "***"
  
 -table_prefix = "banana_"
  spool_root   = "/var/spool/banana"
  mbox_helper  = "/usr/bin/banana-mbox-helper"
  
  event_forum = ""
  event_reply = ""
  
- [Geoloc]
- webservice_url = ""
+ [Geocoder]
+ email = ""
+ gmaps_key = ""
+ gmaps_url = "http://maps.google.com/maps/geo"
  
  [Lists]
  rpchost   = "localhost"
diff --combined include/userset.inc.php
   *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
   ***************************************************************************/
  
 -require_once('user.func.inc.php');
 -
 -global $globals;
 -
 -@$globals->search->result_where_statement = "
 -    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_countries           AS n1  ON (u.nationalite = n1.iso_3166_1_a2)
 -    LEFT JOIN  geoloc_countries           AS n2  ON (u.nationalite2 = n2.iso_3166_1_a2)
 -    LEFT JOIN  geoloc_countries           AS n3  ON (u.nationalite2 = n3.iso_3166_1_a2)
 -    LEFT JOIN  profile_addresses          AS adr ON (u.user_id = adr.pid
 -                                                     AND FIND_IN_SET('current', adr.flags))
 -    LEFT JOIN  geoloc_countries           AS gc  ON (adr.countryId = gc.iso_3166_1_a2)
 -    LEFT JOIN  geoloc_administrativeareas AS gr  ON (adr.countryId = gr.country
 -                                                     AND adr.administrativeAreaId = gr.id)
 -    LEFT JOIN  emails                     AS em  ON (em.uid = u.user_id AND em.flags = 'active')";
 -
  class UserSet extends PlSet
  {
 -    public function __construct($joins = '', $where = '')
 +    private $cond;
 +
 +    public function __construct($cond = null)
      {
 -        global $globals;
 -        parent::__construct('auth_user_md5 AS u',
 -                            (!empty($GLOBALS['IS_XNET_SITE']) ?
 -                                'INNER JOIN groupex.membres AS gxm ON (u.user_id = gxm.uid
 -                                                                       AND gxm.asso_id = ' . $globals->asso('id') . ') ' : '')
 -                           . 'LEFT JOIN auth_user_quick AS q USING (user_id)' . $joins,
 -                            $where,
 -                            'u.user_id');
 +        $this->cond = new UFC_And();
 +        if (!is_null($cond)) {
 +            $this->cond->addChild($cond);
 +        }
 +    }
 +
 +    public function &get($fields, $joins, $where, $groupby, $order, $limitcount = null, $limitfrom = null)
 +    {
 +        $uf = new UserFilter($this->cond);
 +        $users = $uf->getUsers($limitcount, $limitfrom);
 +        $this->count = $uf->getTotalCount();
 +        return $users;
      }
  }
  
@@@ -156,14 -171,93 +156,14 @@@ class MinificheView extends MultipageVi
          parent::__construct($set, $data, $params);
      }
  
 -    public function fields()
 -    {
 -        global $globals;
 -        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,
 -                je.name AS entreprise, je.url AS job_web, es.name AS secteur, ef.fonction_fr AS fonction,
 -                IF(n1.nat = '', n1.countryFR, n1.nat) AS nat1, n1.iso_3166_1_a2 AS iso3166_1,
 -                IF(n2.nat = '', n2.countryFR, n2.nat) AS nat2, n2.iso_3166_1_a2 AS iso3166_2,
 -                IF(n3.nat = '', n3.countryFR, n3.nat) AS nat3, n3.iso_3166_1_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.localityId, gr.name AS region
 -              . "gc.iso_3166_1_a2, gc.countryFR AS countrytxt
 -                (COUNT(em.email) > 0 OR FIND_IN_SET('googleapps', u.mail_storage) > 0) AS actif,
 -                d.directory_name, d.sort_name" .
 -                (S::logged() ? ", c.contact AS contact" : '');
 -    }
 -
 -    public function joins()
 +    public function bounds()
      {
 -        return  "LEFT JOIN  aliases                       AS a    ON (u.user_id = a.id AND FIND_IN_SET('bestalias', a.flags))
 -                 LEFT JOIN  search_name                   AS n    ON (u.user_id = n.uid)
 -                 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_countries              AS n1   ON (u.nationalite = n1.iso_3166_1_a2)
 -                 LEFT JOIN  geoloc_countries              AS n2   ON (u.nationalite2 = n2.iso_3166_1_a2)
 -                 LEFT JOIN  geoloc_countries              AS n3   ON (u.nationalite3 = n3.iso_3166_1_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  profile_addresses             AS adr  ON (u.user_id = adr.pid
 -                                                                      AND FIND_IN_SET('current', adr.flags)"
 -                                                                      . (S::logged() ? "" :
 -                                                                         "AND adr.pub = 'public'") . ")
 -                 LEFT JOIN  geoloc_countries              AS gc   ON (adr.countryId = gc.iso_3166_a2)
 -                 LEFT JOIN  geoloc_administrativeareas    AS gr   ON (adr.countryId = gr.country
 -                                                                      AND adr.administrativeAreaId = gr.id)
 -                 LEFT JOIN  emails                        AS em   ON (em.uid = u.user_id AND em.flags = 'active')
 -                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') . ")"
 -                 : "");
 +        return null;
      }
  
 -    public function bounds()
 +    public function fields()
      {
 -        $order = Env::v('order', $this->defaultkey);
 -        $show_bounds = 0;
 -        if (($order == "name") || ($order == "-name")) {
 -            $this->bound_field = "nom";
 -            $show_bounds = 1;
 -        } elseif (($order == "promo") || ($order == "-promo")) {
 -            $this->bound_field = "promo";
 -            $show_bounds = -1;
 -        }
 -        if ($order{0} == '-') {
 -            $show_bounds = -$show_bounds;
 -        }
 -        return $show_bounds;
 +        return null;
      }
  
      public function templateName()
@@@ -276,102 -370,6 +276,6 @@@ class TrombiView extends MultipageVie
      }
  }
  
- class GeolocView implements PlView
- {
-     private $set;
-     private $type;
-     private $params;
-     public function __construct(PlSet &$set, $data, array $params)
-     {
-         $this->params = $params;
-         $this->set   =& $set;
-         $this->type   = $data;
-     }
-     private function use_map()
-     {
-         return is_file(dirname(__FILE__) . '/../modules/geoloc/dynamap.swf') &&
-                is_file(dirname(__FILE__) . '/../modules/geoloc/icon.swf');
-     }
-     public function args()
-     {
-         $args = $this->set->args();
-         unset($args['initfile']);
-         unset($args['mapid']);
-         return $args;
-     }
-     public function apply(PlPage &$page)
-     {
-         require_once 'geoloc.inc.php';
-         require_once '../modules/search/search.inc.php';
-         switch ($this->type) {
-           case 'icon.swf':
-             header("Content-type: application/x-shockwave-flash");
-             header("Pragma:");
-             readfile(dirname(__FILE__).'/../modules/geoloc/icon.swf');
-             exit;
-           case 'dynamap.swf':
-             header("Content-type: application/x-shockwave-flash");
-             header("Pragma:");
-             readfile(dirname(__FILE__).'/../modules/geoloc/dynamap.swf');
-             exit;
-           case 'init':
-             $page->changeTpl('geoloc/init.tpl', NO_SKIN);
-             header('Content-Type: text/xml');
-             header('Pragma:');
-             if (!empty($GLOBALS['IS_XNET_SITE'])) {
-                 $page->assign('background', 0xF2E9D0);
-             }
-             break;
-           case 'city':
-             $page->changeTpl('geoloc/city.tpl', NO_SKIN);
-             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, 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;
-           case 'country':
-             if (Env::has('debug')) {
-                 $page->changeTpl('geoloc/country.tpl', SIMPLE);
-             } else {
-                 $page->changeTpl('geoloc/country.tpl', NO_SKIN);
-                 header('Content-Type: text/xml');
-                 header('Pragma:');
-             }
-             $mapid = Env::has('mapid') ? Env::i('mapid', -2) : false;
-             list($countries, $cities) = geoloc_getData_subcountries($mapid, $this->set, 10);
-             $page->assign('countries', $countries);
-             $page->assign('cities', $cities);
-             break;
-           default:
-             global $globals;
-             if (!$this->use_map()) {
-                 $page->assign('request_geodesix', true);
-             }
-             $page->assign('annu', @$this->params['with_annu']);
-             $page->assign('protocole', @$_SERVER['HTTPS'] ? 'https' : 'http');
-             $this->set->get('u.user_id', null, "u.perms != 'pending' AND u.deces = 0", "u.user_id", null);
-             return 'include/plview.geoloc.tpl';
-         }
-     }
- }
  class GadgetView implements PlView
  {
      public function __construct(PlSet &$set, $data, array $params)
                  u.perms != 'pending' AS wasinscrit,
                  u.deces != 0 AS dcd, u.deces,
                  FIND_IN_SET('femme', u.flags) AS sexe,
-                 adr.city, gp.a2, gp.pays AS countrytxt, gr.name AS region" .
+                 " // adr.city, gr.name AS region
+               . "gc.iso_3166_1_a2, gc.countryFR AS countrytxt" .
                  (S::logged() ? ", c.contact AS contact" : '');
      }
  
      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)" .
-                 (S::logged() ?
-                 "LEFT JOIN  contacts      AS c   ON (c.contact = u.user_id AND c.uid = " . S::v('uid') . ")"
-                  : "");
+         return "LEFT JOIN  profile_addresses          AS adr ON (u.user_id = adr.pid AND
+                                                                  FIND_IN_SET('current', adr.flags)"
+                                                                 . (S::logged() ? "" : "AND adr.pub = 'public'") . ")
+                 LEFT JOIN  geoloc_countries           AS gc  ON (adr.countryId = gc.iso_3166_1_a2)
+                 LEFT JOIN  geoloc_administrativeareas AS gr  ON (adr.countryId = gr.country
+                                                                  AND adr.administrativeAreaId = gr.id)
+                " . (S::logged() ?
+                "LEFT JOIN  contacts                   AS c   ON (c.contact = u.user_id
+                                                                  AND c.uid = " . S::v('uid') . ")" : "");
      }
  
      public function apply(PlPage &$page)
diff --combined modules/events.php
@@@ -41,9 -41,9 +41,9 @@@ class EventsModule extends PLModul
          global $globals;
          // Add a new special tip when changing plat/al version
          if ($globals->version != S::v('last_version') && is_null($exclude)) {
 -            XDB::execute('UPDATE auth_user_quick
 +            XDB::execute('UPDATE accounts
                               SET last_version = {?}
 -                           WHERE user_id = {?}',
 +                           WHERE uid = {?}',
                             $globals->version, S::i('uid'));
              return array('id' => 0,
                           'titre' => 'Bienvenue sur la nouvelle version du site !',
  
          // Profile update (appears when profile is > 400d old), and birthday
          // oneboxes.
 -        $res = XDB::query(
 -            "SELECT  date < DATE_SUB(NOW(), INTERVAL 400 DAY) AS is_profile_old,
 -                     MONTH(naissance) = MONTH(NOW()) AND DAYOFMONTH(naissance) = DAYOFMONTH(NOW()) AS is_birthday,
 -                     date AS profile_date, YEAR(NOW()) - YEAR(naissance) AS age
 -               FROM  auth_user_md5
 -              WHERE  user_id = {?}", S::user()->id());
 -        list($is_profile_old, $is_birthday, $profile_date, $age) = $res->fetchOneRow();
 -
 -        if ($is_profile_old) {
 -            $page->assign('fiche_incitation', $profile_date);
 -        }
 -        if ($is_birthday) {
 -            $page->assign('birthday', $age);
 +        $user = S::user();
 +        $profile = $user->profile();
 +        if (!is_null($profile)) {
 +            if (strtotime($profile->last_change) < time() - (400 * 86400)) {
 +                $page->assign('fiche_incitation', $profile->last_change);
 +            }
 +            if ($profile->next_birthday == date('Y-m-d')) {
 +                $birthyear = (int)date('Y', strtotime($profile->birthdate));
 +                $curyear   = (int)date('Y');
 +                $page->assign('birthday', $curyear - $birthyear);
 +            }
          }
  
          // No-photo onebox.
 -        $res = XDB::query("SELECT COUNT(*) FROM photo WHERE uid = {?}", S::user()->id());
 +        $res = XDB::query("SELECT  COUNT(*)
 +                             FROM  photo
 +                            WHERE  uid = {?}",
 +                          S::user()->id());
          $page->assign('photo_incitation', $res->fetchOneCell() == 0);
  
          // Geo-location onebox.
-         require_once 'geoloc.inc.php';
-         $res = localize_addresses(S::user()->id());
-         $page->assign('geoloc_incitation', count($res));
+         require_once "geocoding.inc.php";
+         $page->assign('geoloc_incitation', Geocoder::countNonGeocoded(S::user()->id()));
  
          // Direct link to the RSS feed, when available.
 -        if (S::rssActivated()) {
 +        if (S::hasAuthToken()) {
              $page->setRssLink('Polytechnique.org :: News',
 -                              '/rss/'.S::v('hruid') .'/'.S::v('core_rss_hash').'/rss.xml');
 +                              '/rss/'.S::v('hruid') .'/'.S::v('token').'/rss.xml');
          }
  
          // Hide the read event, and reload the page to get to the next event.
  
          // 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, d.promo AS promo_display ,a.hruid,
 +        $it = XDB::iterator("SELECT  e.id, e.titre, e.texte, e.post_id, e.user_id,
                                       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
 +                                     ev.user_id IS NULL AS nonlu, e.promo_min, e.promo_max
                                 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)
 -                         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 >= {?})
                             ORDER BY  important DESC, news DESC, end DESC, e.peremption, e.creation_date DESC",
 -                            S::i('uid'), S::i('promo'), S::i('promo'));
 +                            S::i('uid'));
          $cats = array('important', 'news', 'end', 'body');
 -        $body  = $it->next();
 +
 +        $this->load('feed.inc.php');
 +        $user = S::user();
 +        $body  = EventFeed::nextEvent($it, $user);
          foreach ($cats as $cat) {
              $data = array();
              if (!$body) {
                  } else {
                      break;
                  }
 -                $body = $it->next();
 +                $body = EventFeed::nextEvent($it, $user);
              } while ($body);
              if (!empty($data)) {
                  $array[$cat] = $data;
              }
          }
 +
          $page->assign_by_ref('events', $array);
      }
  
              }
  
              $pid = ($eid && $action == 'preview') ? $eid : -1;
 -            $sql = "SELECT  e.id, e.titre, e.texte,e.id = $pid AS preview,
 +            $sql = "SELECT  e.id, e.titre, e.texte,e.id = $pid AS preview, e.user_id,
                              DATE_FORMAT(e.creation_date,'%d/%m/%Y %T') AS creation_date,
                              DATE_FORMAT(e.peremption,'%d/%m/%Y') AS peremption,
                              e.promo_min, e.promo_max,
                              FIND_IN_SET('valide', e.flags) AS fvalide,
                              FIND_IN_SET('archive', e.flags) AS farch,
 -                            u.promo, u.nom, u.prenom, u.hruid,
                              FIND_IN_SET('wiki', e.flags) AS wiki
                        FROM  evenements    AS e
 -                INNER JOIN  auth_user_md5 AS u ON(e.user_id = u.user_id)
                       WHERE  ".($arch ? "" : "!")."FIND_IN_SET('archive',e.flags)
                    ORDER BY  FIND_IN_SET('valide',e.flags), e.peremption DESC";
              $page->assign('evs', XDB::iterator($sql));
@@@ -21,8 -21,6 +21,6 @@@
  
  class PayPal
  {
-     // {{{ properties
      var $val_number;
      var $urlform;
      var $nomsite = "PayPal";
  
      var $infos;
  
-     // }}}
-     // {{{ constructor
      function PayPal($val)
      {
          $this->val_number = $val;
      }
  
-     // }}}
-     // {{{ function form()
      function prepareform(&$pay)
      {
-         // toute la doc sur :
-         // https://www.paypal.com/fr_FR/pdf/integration_guide.pdf
-         // attention : le renvoi automatique ne fonctionne que si
-         // on oblige les gens à créer un compte paypal
-         // nous ne l'utilisons pas ; il faut donc que l'utilisateur
-         // revienne sur le site
+         // Documentation:
+         // https://www.paypal.com/developer
+         // Warning: the automatic return only works if we force the
+         // users to create a paypal account. We do not use it; thus
+         // the user must come back on the site.
          global $globals, $platal;
  
-         $this->urlform = 'https://'.$globals->money->paypal_site.'/cgi-bin/webscr';
+         $this->urlform = 'https://' . $globals->money->paypal_site . '/cgi-bin/webscr';
 -        $req = XDB::query("SELECT  IF(nom_usage!='', nom_usage, nom) AS nom
 -                             FROM  auth_user_md5
 -                            WHERE  user_id = {?}", S::v('uid'));
 -        $name = $req->fetchOneCell();
 +        $user = S::user();
 +        $name = $user->lastName();
  
          $roboturl = str_replace("https://","http://",$globals->baseurl)
-             . '/' . $platal->ns . "payment/paypal_return/".S::v('uid')."?comment=".urlencode(Env::v('comment'));
+                   . '/' . $platal->ns . "payment/paypal_return/" . S::v('uid')
+                   . "?comment=" . urlencode(Env::v('comment'));
  
-         $this->infos = Array();
+         $this->infos = array();
  
-         $this->infos['commercant'] = Array(
+         $this->infos['commercant'] = array(
              'business'    => $globals->money->paypal_compte,
-             'rm'        => 2,
+             'rm'          => 2,
              'return'      => $roboturl,
-             'cn'        => 'Commentaires',
+             'cn'          => 'Commentaires',
              'no_shipping' => 1,
              'cbt'         => empty($GLOBALS['IS_XNET_SITE']) ?
-             'Revenir sur polytechnique.org' :
-             'Revenir sur polytechnique.net');
+             'Revenir sur polytechnique.org.' :
+             'Revenir sur polytechnique.net.'
+         );
  
-         $info_client = Array(
+         $info_client = array(
              'first_name' => S::v('prenom'),
              'last_name'  => $name,
-             'email'      => S::user()->bestEmail());
+             'email'      => S::user()->bestEmail()
+         );
  
 +        // XXX: waiting for port of adresses.
          $res = XDB::query(
-             "SELECT a.adr1 AS address1, a.adr2 AS address2,
-                     a.city, a.postcode AS zip, a.country,
-                     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 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'));
+                 "SELECT  a.text, l.name AS city, a.postalCode AS zip, a.countryiId AS country,
+                          IF(t1.display_tel != '', t1.display_tel, t2.display_tel) AS night_phone_b
+                    FROM  auth_user_quick   AS q
+               LEFT JOIN  profile_addresses AS a  ON (q.user_id = a.pid AND FIND_IN_SET('current', a.flags))
+               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)
+               LEFT JOIN  geoloc_localities AS l  ON (l.id = a.localityId)
+                   WHERE  q.user_id = {?}
+                   LIMIT  1",
+                 S::v('uid'));
          $this->infos['client'] = array_map('replace_accent', array_merge($info_client, $res->fetchOneAssoc()));
-         // on constuit la reference de la transaction
-         $prefix = ($pay->flags->hasflag('unique')) ? str_pad("",15,"0") : rand_url_id();
-         $fullref = substr("$prefix-xorg-{$pay->id}",-15);
-         $this->infos['commande'] = Array(
-             'item_name' => replace_accent($pay->text),
-             'amount'  => $this->val_number,
+         list($this->infos['client']['address1'], $this->infos['client']['address2']) =
+             explode("\n", Geocoder::getFirstLines($this->infos['client']['text'],
+                                                   $this->infos['client']['zip'], 2));
+         unset($this->infos['client']['text']);
+         // We build the transaction's reference
+         $prefix = ($pay->flags->hasflag('unique')) ? str_pad("", 15, "0") : rand_url_id();
+         $fullref = substr("$prefix-xorg-{$pay->id}", -15);
+         $this->infos['commande'] = array(
+             'item_name'     => replace_accent($pay->text),
+             'amount'        => $this->val_number,
              'currency_code' => 'EUR',
-             'custom'  => $fullref);
+             'custom'        => $fullref
+         );
  
-         $this->infos['divers'] = Array('cmd' => '_xclick');
+         $this->infos['divers'] = array('cmd' => '_xclick');
      }
-     // }}}
  }
  
  $api = 'PayPal';
diff --combined modules/profile.php
@@@ -238,11 -238,8 +238,11 @@@ class ProfileModule extends PLModul
              return PL_NOT_FOUND;
          }
  
 -        $login = S::logged() ? User::get($x) : User::getSilent($x);
 +        $login = (!is_numeric($x) || S::has_perms()) ? Profile::get($x) : null;
          if (!$login) {
 +            if (S::logged()) {
 +                $page->trigError($x . ' inconnu dans l\'annuaire');
 +            }
              return PL_NOT_FOUND;
          }
  
  
          // Determines is the user is registered, and fetches the user infos in
          // the appropriate way.
 -        $res = XDB::query("SELECT  perms IN ('admin','user','disabled')
 -                             FROM  auth_user_md5
 -                            WHERE  user_id = {?}", $login->id());
 -        if ($res->fetchOneCell()) {
 +        $owner = $login->owner();
 +        if (!$owner || $owner->state != 'pending') {
              $new  = Env::v('modif') == 'new';
 -            $user = get_user_details($login->login(), S::v('uid'), $view);
 +            // XXX: Deprecated...
 +            $user = get_user_details($login->hrid(), S::i('uid'), $view);
          } else {
              $new  = false;
              $user = array();
              if (S::logged()) {
 -                pl_redirect('marketing/public/' . $login->login());
 +                pl_redirect('marketing/public/' . $owner->login());
              }
          }
  
          // Profile view are logged.
          if (S::logged()) {
 -            S::logger()->log('view_profile', $login->login());
 +            S::logger()->log('view_profile', $login->hrid());
          }
  
          // Sets the title of the html page.
          $page->setTitle($login->fullName());
  
          // Prepares the display of the user's mugshot.
 -        $photo = 'photo/' . $login->login() . ($new ? '/req' : '');
 +        $photo = 'photo/' . $login->hrid() . ($new ? '/req' : '');
          if (!isset($user['photo_pub']) || !has_user_right($user['photo_pub'], $view)) {
              $photo = "";
          }
  
          // Determines and displays the virtual alias.
          global $globals;
 -        $res = XDB::query(
 -                "SELECT  alias
 -                   FROM  virtual
 -             INNER JOIN  virtual_redirect USING (vid)
 -             INNER JOIN  auth_user_quick ON (user_id = {?} AND emails_alias_pub = 'public')
 -                  WHERE  (redirect={?} OR redirect={?})
 -                         AND alias LIKE '%@{$globals->mail->alias_dom}'",
 -                $login->id(),
 -                $login->forlifeEmail(),
 -                // TODO(vzanotti): get ride of all @m4x.org addresses in the
 -                // virtual redirect base, and remove this über-ugly hack.
 -                $login->login() . '@' . $globals->mail->domain2);
 -        $page->assign('virtualalias', $res->fetchOneCell());
 +        $owner = $login->owner();
 +        if ($owner) {
 +            $page->assign('virtualalias', $owner->emailAlias());
 +        }
  
          // Adds miscellaneous properties to the display.
          // Adds the global user property array to the display.
          $page->assign_by_ref('x', $user);
 -        $page->assign_by_ref('user', $login);
 +        $page->assign_by_ref('user', $owner);
          $page->assign('logged', has_user_right('private', $view));
          $page->assign('view', $view);
  
  
      function handler_ax(&$page, $user = null)
      {
 -        $user = User::get($user);
 +        $user = Profile::get($user);
          if (!$user) {
              return PL_NOT_FOUND;
          }
 -
 -        $res = XDB::query("SELECT  matricule_ax
 -                             FROM  auth_user_md5
 -                            WHERE  user_id = {?}", $user->id());
 -        $mat = $res->fetchOneCell();
 -        if (!intval($mat)) {
 -            $page->kill("Le matricule AX de {$user->login()} est inconnu");
 +        if (!$user->ax_id) {
 +            $page->kill("Le matricule AX de {$user->hrid()} est inconnu");
          }
 -        http_redirect("http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&anc_id=$mat");
 +        http_redirect("http://www.polytechniciens.com/?page=AX_FICHE_ANCIEN&anc_id=" . $user->ax_id);
      }
  
 -    function handler_p_edit(&$page, $opened_tab = null, $mode = null)
 +    function handler_p_edit(&$page, $user = null, $opened_tab = null, $mode = null)
      {
          global $globals;
  
 -        // AX Synchronization
 -        require_once 'synchro_ax.inc.php';
 -        if (is_ax_key_missing()) {
 -            $page->assign('no_private_key', true);
 -        }
 -        if (Env::v('synchro_ax') == 'confirm' && !is_ax_key_missing()) {
 -            ax_synchronize(S::user()->login(), S::v('uid'));
 -            $page->trigSuccess('Ton profil a été synchronisé avec celui du site polytechniciens.com');
 +        if (is_null($user)) {
 +            $user = S::user();
 +            if (!$user->hasProfile()) {
 +                return PL_NOT_FOUND;
 +            } else {
 +                pl_redirect('profile/edit/' . $user->profile()->hrid());
 +            }
 +        } else {
 +            $user = Profile::get($user);
 +            if (!$user) {
 +                return PL_NOT_FOUND;
 +            } else if (!S::user()->canEdit($user) && Platal::notAllowed()) {
 +                return PL_FORBIDDEN;
 +            }
          }
  
          // Build the page
          $page->addJsLink('grades.js');
          $page->addJsLink('profile.js');
          $page->addJsLink('jquery.autocomplete.js');
 -        $wiz = new PlWizard('Profil', PlPage::getCoreTpl('plwizard.tpl'), true, true);
 +        $wiz = new PlWizard('Profil', PlPage::getCoreTpl('plwizard.tpl'), true, true, false);
 +        $wiz->addUserData('profile', $user);
 +        $wiz->addUserData('owner', $user->owner());
          $this->load('page.inc.php');
          $wiz->addPage('ProfileGeneral', 'Général', 'general');
          $wiz->addPage('ProfileAddresses', 'Adresses personnelles', 'adresses');
          $wiz->addPage('ProfileJobs', 'Informations professionnelles', 'emploi');
          $wiz->addPage('ProfileSkills', 'Compétences diverses', 'skill');
          $wiz->addPage('ProfileMentor', 'Mentoring', 'mentor');
 -        $wiz->apply($page, 'profile/edit', $opened_tab, $mode);
 +        $wiz->apply($page, 'profile/edit/' . $user->hrid(), $opened_tab, $mode);
  
 -         // Misc checks
 -        $res = XDB::query("SELECT  user_id
 -                             FROM  auth_user_md5
 -                            WHERE  user_id = {?} AND naissance = '0000-00-00'", S::i('uid'));
 -        if ($res->numRows()) {
 +        if (!$user->birthdate) {
              $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.");
          }
          $page->assign('medal_list', $mlist);
      }
  
-     function handler_ajax_address(&$page, $adid)
+     function handler_ajax_address(&$page, $id)
      {
          header('Content-Type: text/html; charset=utf-8');
          $page->changeTpl('profile/adresses.address.tpl', NO_SKIN);
-         $page->assign('i', $adid);
-         $page->assign('adr', array());
+         $page->assign('i', $id);
+         $page->assign('address', array());
      }
  
      function handler_ajax_tel(&$page, $prefid, $prefname, $telid)
          $page->assign('names', build_javascript_names($data));
      }
  
 -    function handler_p_orange(&$page)
 +    function handler_p_orange(&$page, $pid = null)
      {
          $page->changeTpl('profile/orange.tpl');
  
          require_once 'validations.inc.php';
 -
 -        $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, $promo_display, $sexe) = $res->fetchOneRow();
 -        $page->assign('promo_sortie_old', $promo_sortie_old);
 -        $page->assign('promo', $promo);
 -        $page->assign('promo_display', $promo_display);
 -        $page->assign('sexe', $sexe);
 +        $profile = Profile::get($pid);
 +        if (is_null($profile)) {
 +            return PL_NOT_FOUND;
 +        }
 +        $page->assign('promo_sortie_old', $profile->grad_year);
 +        $page->assign('promo', $profile->entry_year);
 +        $page->assign('promo_display', $profile->promo());
 +        $page->assign('sexe', $profile->isFemale());
  
          if (!Env::has('promo_sortie')) {
              return;
          }
  
          $promo_sortie = Env::i('promo_sortie');
 -
 +        $promo = $profile->entry_year;
          if ($promo_sortie < 1000 || $promo_sortie > 9999) {
              $page->trigError('L\'année de sortie doit être un nombre de quatre chiffres.');
 -        }
 -        elseif ($promo_sortie < $promo + 3) {
 +        } elseif ($promo_sortie < $promo + 3) {
              $page->trigError('Trop tôt !');
 -        }
 -        elseif ($promo_sortie == $promo_sortie_old) {
 +        } 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  profile_education
 +        } elseif ($promo_sortie == $promo + 3) {
 +            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);
 -        }
 -        else {
 +                           WHERE  uid = {?} AND FIND_IN_SET(\'primary\', flags)',
 +                         $promo_sortie, $profile->id());
 +            $page->trigSuccess('Ton statut "orange" a été supprimé.');
 +            $page->assign('promo_sortie_old', $promo_sortie);
 +        else {
              $page->assign('promo_sortie', $promo_sortie);
  
              if (Env::has('submit')) {
          }
      }
  
 -    function handler_referent(&$page, $x = null)
 +    function handler_referent(&$page, $user)
      {
          require_once 'user.func.inc.php';
          $page->changeTpl('profile/fiche_referent.tpl', SIMPLE);
  
 -        $user = User::get($x);
 -        if ($user == null) {
 +        $user = Profile::get($user);
 +        if (!$user) {
              return PL_NOT_FOUND;
          }
  
 -        $res = XDB::query("SELECT cv FROM auth_user_md5 WHERE user_id = {?}", $user->id());
 -        $cv = $res->fetchOneCell();
 -
          $page->assign_by_ref('user', $user);
 -        $page->assign('cv', MiniWiki::WikiToHTML($cv, true));
 -        $page->assign('adr_pro', get_user_details_pro($user->id()));
 +        $page->assign('cv', MiniWiki::WikiToHTML($user->cv, true));
 +        //TODO: waiting for job refactoring to be done
 +        //$page->assign('adr_pro', get_user_details_pro($user->id()));
  
          /////  recuperations infos referent
  
          //expertise
 -        $res = XDB::query("SELECT expertise FROM profile_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.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());
 +        $res = XDB::iterRow('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;
              $ss_secteurs[] = $ssec;
          $page->assign_by_ref('secteurs', $secteurs);
          $page->assign_by_ref('ss_secteurs', $ss_secteurs);
  
-         //pays
-         $res = XDB::query('SELECT  gp.pays
-                              FROM  profile_mentor_country AS m
-                         LEFT JOIN  geoloc_pays            AS gp ON (m.country = gp.a2)
-                             WHERE  uid = {?}', $user->id());
+         // Countries.
+         $res = XDB::query(
+                 "SELECT  gc.countryFR
+                    FROM  profile_mentor_country AS m
+               LEFT JOIN  geoloc_countries       AS gc ON (m.country = gc.iso_3166_1_a2)
+                   WHERE  uid = {?}", $user->id());
          $page->assign('pays', $res->fetchColumn());
  
          $page->addJsLink('close_on_esc.js');
          $page->changeTpl('include/field.select.tpl', NO_SKIN);
          $page->assign('name', 'pays_sel');
          $where = ($ssect ? ' AND ms.subsectorid = {?}' : '');
-         $it = XDB::iterator("SELECT  a2 AS id, pays AS field
-                                FROM  geoloc_pays            AS g
-                          INNER JOIN  profile_mentor_country AS mp ON (mp.country = g.a2)
+         $it = XDB::iterator("SELECT  gc.iso_3166_1_a2 AS id, gc.countryFR AS field
+                                FROM  geoloc_countries       AS gc
+                          INNER JOIN  profile_mentor_country AS mp ON (mp.country = gc.iso_3166_1_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);
+                               WHERE  ms.sectorid = {?} " . $where . "
+                            GROUP BY  iso_3166_1_a2
+                            ORDER BY  countryFR", $sect, $ssect);
          $page->assign('list', $it);
      }
  
@@@ -19,7 -19,7 +19,7 @@@
   *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
   ***************************************************************************/
  
- class ProfileAddress extends ProfileGeoloc
+ class ProfileAddress extends ProfileGeocoding
  {
      private $bool;
      private $pub;
          $this->pub  = new ProfilePub();
      }
  
-     private function cleanAddress(ProfilePage &$page, $adrid, array &$address, &$success)
+     private function cleanAddress(ProfilePage &$page, $addrid, array &$address)
      {
-         if (@$address['changed']) {
-             $address['datemaj'] = time();
-         }
-         $success = true;
          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);
+         $profiletel           = new ProfilePhones('address', $addrid);
+         $address['tel']       = $profiletel->value($page, 'tel',       $address['tel'],       $s);
+         $address['current']   = $this->bool->value($page, 'current',   $address['current'],   $s);
          $address['temporary'] = $this->bool->value($page, 'temporary', $address['temporary'], $s);
-         $address['current'] = $this->bool->value($page, 'current', @$address['current'], $s);
-         $address['pub'] = $this->pub->value($page, 'pub', $address['pub'], $s);
-         unset($address['parsevalid']);
-         unset($address['changed']);
-         unset($address['removed']);
-         unset($address['display']);
+         $address['secondary'] = $this->bool->value($page, 'secondary', $address['secondary'], $s);
+         $address['mail']      = $this->bool->value($page, 'mail',      $address['mail'],      $s);
+         $address['pub']       = $this->pub->value($page,  'pub',       $address['pub'],       $s);
      }
  
      public function value(ProfilePage &$page, $field, $value, &$success)
          $init = false;
          if (is_null($value)) {
              $value = $page->values['addresses'];
-             $init = true;
+             $init  = true;
          }
-         foreach ($value as $key=>&$adr) {
-             if (@$adr['removed']) {
+         foreach ($value as $key => &$address) {
+             if (isset($address['removed']) && $address['removed']) {
                  unset($value[$key]);
              }
          }
          $current = 0;
          $success = true;
-         foreach ($value as $key=>&$adr) {
-             if (@$adr['current']) {
+         foreach ($value as $key => &$address) {
+             if (isset($address['current']) && $address['current']) {
                  $current++;
              }
          }
          if ($current == 0 && count($value) > 0) {
-             foreach ($value as $key=>&$adr) {
-                 $adr['current'] = true;
+             foreach ($value as $address) {
+                 $address['current'] = true;
                  break;
              }
-         } else if ($current > 1) {
+         } elseif ($current > 1) {
              $success = false;
          }
-         foreach ($value as $key=>&$adr) {
-             $ls = true;
-             $this->geolocAddress($adr, $s);
-             $ls = ($ls && $s);
-             $this->cleanAddress($page, $key, $adr, $s);
-             $ls = ($ls && $s);
-             if (!trim($adr['text'])) {
+         foreach ($value as $key => &$address) {
+             if (!trim($address['text'])) {
                  unset($value[$key]);
-             } else if (!$init) {
-                 $success = ($success && $ls);
+             } elseif (!$init) {
+                 $this->geocodeAddress($address, $s);
+                 $success = $success && $s;
              }
+             $this->cleanAddress($page, $key, $address);
          }
          return $value;
      }
  
 -    private function saveTel($addrid, $telid, array &$tel)
 -    {
 -        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'), $addrid, $telid, $tel['type'],
 -                     format_phone_number($tel['tel']), $tel['tel'], $tel['pub']);
 -    }
 -
 -    private function saveAddress($addrid, array &$address)
 +    private function saveAddress($pid, $adrid, array &$address)
      {
+         require_once "geocoding.inc.php";
          $flags = new PlFlagSet();
-         $flags->addFlag('res-secondaire', $address['secondaire']);
-         $flags->addFlag('courrier', $address['mail']);
-         $flags->addFlag('temporaire', $address['temporary']);
-         $flags->addFlag('active', $address['current']);
-         $flags->addFlag('coord-checked', $address['checked']);
-         XDB::execute("INSERT INTO  adresses (adr1, adr2, adr3,
-                                               postcode, city, cityid,
-                                               country, region, regiontxt,
-                                               pub, datemaj, statut,
-                                               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,
-                      $pid, $adrid, $address['precise_lat'], $address['precise_lon'], $address['comment']);
 -        if ($address['current']) {
 -            $flags->addFlag('current');
 -        }
 -        if ($address['temporary']) {
 -            $flags->addFlag('temporary');
 -        }
 -        if ($address['secondary']) {
 -            $flags->addFlag('secondary');
 -        }
 -        if ($address['mail']) {
 -            $flags->addFlag('mail');
 -        }
 -        if ($address['cedex'] =
++        $flags->addFlag('current', $address['current']);
++        $flags->addFlag('temporary', $address['temporary']);
++        $flags->addFlag('secondary', $address['secondary']);
++        $flags->addFlag('mail', $address['mail']);
++        $flags->addFlag('cedex', $address['cedex'] =
+             (strpos(strtoupper(preg_replace(array("/[0-9,\"'#~:;_\- ]/", "/\r\n/"),
 -                                            array("", "\n"), $address['text'])), 'CEDEX')) !== false) {
 -            $flags->addFlag('cedex');
 -        }
++                                            array("", "\n"), $address['text'])), 'CEDEX')) !== false);
+         Geocoder::getAreaId($address, "administrativeArea");
+         Geocoder::getAreaId($address, "subAdministrativeArea");
+         Geocoder::getAreaId($address, "locality");
+         XDB::execute("INSERT INTO  profile_addresses (pid, type, id, flags, accuracy,
+                                                       text, postalText, postalCode, localityId,
+                                                       subAdministrativeAreaId, administrativeAreaId,
+                                                       countryId, latitude, longitude, updateTime, pub, comment,
+                                                       north, south, east, west)
+                            VALUES  ({?}, 'home', {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?}, {?},
+                                     {?}, {?}, FROM_UNIXTIME({?}), {?}, {?}, {?}, {?}, {?}, {?})",
 -                     S::i('uid'), $addrid, $flags, $address['accuracy'],
++                     $pid, $addrid, $flags, $address['accuracy'],
+                      $address['text'], $address['postalText'], $address['postalCode'], $address['localityId'],
+                      $address['subAdministrativeAreaId'], $address['administrativeAreaId'],
+                      $address['countryId'], $address['latitude'], $address['longitude'],
+                      $address['updateTime'], $address['pub'], $address['comment'],
+                      $address['north'], $address['south'], $address['east'], $address['west']);
      }
  
      public function save(ProfilePage &$page, $field, $value)
      {
-         XDB::execute("DELETE FROM  adresses
-                             WHERE  uid = {?}",
+         XDB::execute("DELETE FROM  profile_addresses
+                             WHERE  pid = {?} AND type = 'home'",
 -                     S::i('uid'));
 +                     $page->pid());
          XDB::execute("DELETE FROM  profile_phones
                              WHERE  uid = {?} AND link_type = 'address'",
 -                     S::i('uid'));
 +                     $page->pid());
-         foreach ($value as $adrid=>&$address) {
-             $this->saveAddress($page->pid(), $adrid, $address);
-             $profiletel = new ProfilePhones('address', $adrid);
+         foreach ($value as $addrid => &$address) {
 -            $this->saveAddress($addrid, $address);
++            $this->saveAddress($page->pid(), $addrid, $address);
+             $profiletel = new ProfilePhones('address', $addrid);
 -            $profiletel->saveTels('tel', $address['tel']);
 +            $profiletel->saveTels($page->pid(), 'tel', $address['tel']);
          }
      }
  }
@@@ -144,44 -157,40 +137,40 @@@ class ProfileAddresses extends ProfileP
      {
          parent::__construct($wiz);
          $this->settings['addresses'] = new ProfileAddress();
-         $this->watched['addresses'] = true;
+         $this->watched['addresses']  = true;
      }
  
      protected function _fetchData()
      {
-         // Build the addresses tree
-         $res = XDB::query("SELECT  a.adrid AS id, a.adr1, a.adr2, a.adr3,
-                                    UNIX_TIMESTAMP(a.datemaj) AS datemaj,
-                                    a.postcode, a.city, a.cityid, a.region, a.regiontxt,
-                                    a.pub, a.country, gp.pays AS countrytxt, gp.display,
-                                    FIND_IN_SET('coord-checked', a.statut) AS checked,
-                                    FIND_IN_SET('res-secondaire', a.statut) AS secondaire,
-                                    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.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)
-                          ORDER BY  adrid",
+         $res = XDB::query("SELECT  type, id, accuracy, text, postalText,
+                                    postalCode, localityId, subAdministrativeAreaId, administrativeAreaId,
+                                    countryId, latitude, longitude, pub, comment, updateTime,
+                                    north, south, east, west,
+                                    FIND_IN_SET('current', flags) AS current,
+                                    FIND_IN_SET('temporary', flags) AS temporary,
+                                    FIND_IN_SET('secondary', flags) AS secondary,
+                                    FIND_IN_SET('mail', flags) AS mail,
+                                    FIND_IN_SET('cedex', flags) AS cedex
+                              FROM  profile_addresses
+                             WHERE  pid = {?} AND type = 'home'
+                          ORDER BY  id",
 -                           S::i('uid'));
 +                           $this->pid());
          if ($res->numRows() == 0) {
              $this->values['addresses'] = array();
          } else {
              $this->values['addresses'] = $res->fetchAllAssoc();
          }
  
-         $res = XDB::iterator("SELECT  link_id AS adrid, tel_type AS type, pub, display_tel AS tel, comment
+         $res = XDB::iterator("SELECT  link_id AS addrid, 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'));
 +                             $this->pid());
          $i = 0;
          $adrNb = count($this->values['addresses']);
          while ($tel = $res->next()) {
-             $adrid = $tel['adrid'];
-             unset($tel['adrid']);
+             $adrid = $tel['addrid'];
+             unset($tel['addrid']);
              while ($i < $adrNb && $this->values['addresses'][$i]['id'] < $adrid) {
                  $i++;
              }
                  $address['tel'][] = $tel;
              }
          }
-         foreach ($this->values['addresses'] as $id=>&$address) {
+         foreach ($this->values['addresses'] as $id => &$address) {
              if (!isset($address['tel'])) {
                  $address['tel'] = array();
              }
@@@ -19,7 -19,7 +19,7 @@@
   *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
   ***************************************************************************/
  
- class ProfileJob extends ProfileGeoloc
+ class ProfileJob extends ProfileGeocoding
  {
      private $pub;
      private $mail_new;
          }
          foreach ($value as $key=>&$job) {
              $ls = true;
-             $this->geolocAddress($job['w_adr'], $s);
+             $this->geocodeAddress($job['w_adr'], $s);
              $ls = ($ls && $s);
              $this->cleanJob($page, $key, $job, $s);
              $ls = ($ls && $s);
@@@ -193,9 -193,9 +193,9 @@@ class ProfileJobs extends ProfilePag
      {
          // Checkout the CV
          $res = XDB::query("SELECT  cv
 -                             FROM  auth_user_md5
 -                            WHERE  user_id = {?}",
 -                          S::i('uid'));
 +                             FROM  profiles
 +                            WHERE  pid = {?}",
 +                          $this->pid());
          $this->values['cv'] = $res->fetchOneCell();
  
          // Checkout the corps
                                     rankid AS rank, corps_pub AS pub
                               FROM  profile_corps
                              WHERE  uid = {?}",
 -                          S::i('uid'));
 +                        $this->pid());
          $this->values['corps'] = $res->fetchOneAssoc();
  
          // Build the jobs tree
          $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.country, gc.countryFR, pa.accuracy,
                                       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  geoloc_countries              AS gc ON (gc.iso_3166_1_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'));
 +                           ORDER BY  entrid", $this->pid());
          $this->values['jobs'] = array();
          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_region, $w_regiontxt, $w_country, $w_countrytxt,
                      $w_checked, $w_email, $w_web,
                      $pub, $w_adr_pub, $w_email_pub, $w_glat, $w_glng, $sss_secteur_name
                     ) = $res->next()) {
                                                                          'regiontxt'   => $w_regiontxt,
                                                                          'country'     => $w_country,
                                                                          'countrytxt'  => $w_countrytxt,
-                                                                         'display'     => $w_display,
                                                                          'pub'         => $w_adr_pub,
-                                                                         'checked'     => $w_checked,
+                                                                         'checked'     => (($w_checked == 0)? true : false),
                                                                          'precise_lat' => $w_glat,
                                                                          'precise_lon' => $w_glng),
                                              'w_email'          => $w_email,
                                  FROM  profile_phones
                                 WHERE  uid = {?} AND link_type = 'pro'
                              ORDER BY  link_id",
 -                             S::i('uid'));
 +                             $this->pid());
          $i = 0;
          $jobNb = count($this->values['jobs']);
          while ($tel = $res->next()) {
      protected function _saveData()
      {
          if ($this->changed['cv']) {
 -            XDB::execute("UPDATE  auth_user_md5
 +            XDB::execute("UPDATE  profiles
                               SET  cv = {?}
 -                           WHERE  user_id = {?}",
 -                         $this->values['cv'], S::i('uid'));
 +                           WHERE  pid = {?}",
 +                         $this->values['cv'], $this->pid());
          }
  
          if ($this->changed['corps']) {
                                    rankid = {?}, corps_pub = {?}
                             WHERE  uid = {?}",
                            $this->values['corps']['original'], $this->values['corps']['current'],
 -                          $this->values['corps']['rank'], $this->values['corps']['pub'], S::i('uid'));
 +                          $this->values['corps']['rank'], $this->values['corps']['pub'], $this->pid());
          }
      }
  
      public function _prepare(PlPage &$page, $id)
      {
          require_once "emails.combobox.inc.php";
 -        fill_email_combobox($page);
 +        fill_email_combobox($page, $this->owner, $this->profile);
  
          $res = XDB::query("SELECT  id, name AS label
                               FROM  profile_job_sector_enum");
@@@ -31,7 -31,7 +31,7 @@@ class ProfileSecteurs implements Profil
                               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'));
 +                                $page->pid());
              while (list($s, $ss, $ssname) = $res->next()) {
                  if (!isset($value[$s])) {
                      $value[$s] = array($ss => $ssname);
@@@ -57,7 -57,7 +57,7 @@@
  
          XDB::execute("DELETE FROM  profile_mentor_sector
                              WHERE  uid = {?}",
 -                     S::i('uid'));
 +                     $page->pid());
          if (!count($value)) {
              return;
          }
@@@ -65,7 -65,7 +65,7 @@@
              foreach ($sect as $sid=>&$name) {
                  XDB::execute("INSERT INTO  profile_mentor_sector (uid, sectorid, subsectorid)
                                     VALUES  ({?}, {?}, {?})",
 -                             S::i('uid'), $id, $sid);
 +                             $page->pid(), $id, $sid);
              }
          }
      }
@@@ -78,11 -78,11 +78,11 @@@ class ProfileCountry implements Profile
          $success = true;
          if (is_null($value)) {
              $value = array();
-             $res = XDB::iterRow("SELECT  m.country, p.pays
+             $res = XDB::iterRow("SELECT  m.country, gc.countryFR
                                     FROM  profile_mentor_country AS m
-                              INNER JOIN  geoloc_pays            AS p ON (m.country = p.a2)
+                              INNER JOIN  geoloc_countries       AS gc ON (m.country = gc.iso_3166_1_a2)
                                    WHERE  m.uid = {?}",
 -                                S::i('uid'));
 +                                $page->pid());
              while (list($id, $name) = $res->next()) {
                  $value[$id] = $name;
              }
      {
          XDB::execute("DELETE FROM  profile_mentor_country
                              WHERE  uid = {?}",
 -                     S::i('uid'));
 +                     $page->pid());
          foreach ($value as $id=>&$name) {
              XDB::execute("INSERT INTO  profile_mentor_country (uid, country)
                                 VALUES  ({?}, {?})",
 -                         S::i('uid'), $id);
 +                         $page->pid(), $id);
          }
      }
  }
@@@ -127,7 -127,7 +127,7 @@@ class ProfileMentor extends ProfilePag
          $res = XDB::query("SELECT  expertise
                               FROM  mentor
                              WHERE  uid = {?}",
 -                          S::i('uid'));
 +                          $this->pid());
          $this->values['expertise'] = $res->fetchOneCell();
      }
  
              if (empty($expertise)) {
                  XDB::execute("DELETE FROM  mentor
                                      WHERE  uid = {?}",
 -                             S::i('uid'));
 +                             $this->pid());
                  $this->values['expertise'] = null;
              } else {
                  XDB::execute("REPLACE INTO  mentor (uid, expertise)
                                      VALUES  ({?}, {?})",
 -                             S::i('uid'), $expertise);
 +                             $this->pid(), $expertise);
                  $this->values['expertise'] = $expertise;
              }
          }
      {
          $page->assign('secteurs_sel', XDB::iterator("SELECT  id, name AS label
                                                         FROM  profile_job_sector_enum"));
+         $page->assign('countryList', XDB::iterator("SELECT  iso_3166_1_a2, countryFR
+                                                       FROM  geoloc_countries
+                                                   ORDER BY  countryFR"));
      }
  }
  
@@@ -119,11 -119,17 +119,11 @@@ class ProfilePhones implements ProfileS
  {
      private $tel;
      private $pub;
 -    protected $id;
      protected $link_type;
      protected $link_id;
  
 -    public function __construct($type, $link_id, $id = 0)
 +    public function __construct($type, $link_id)
      {
 -        if ($id != 0) {
 -            $this->id = $id;
 -        } else {
 -            $this->id = S::i('uid');
 -        }
          $this->tel = new ProfileTel();
          $this->pub = new ProfilePub();
          $this->link_type = $type;
                                      FROM  profile_phones AS t
                                     WHERE  t.uid = {?} AND t.link_type = {?}
                                  ORDER BY  t.tel_id",
 -                                 $this->id, $this->link_type);
 +                                 $page->pid(), $this->link_type);
              $value = $res->fetchAllAssoc();
          }
          foreach ($value as $key=>&$phone) {
          return $value;
      }
  
 -    private function saveTel($telid, array &$phone)
 +    private function saveTel($pid, $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'],
 +                         $pid, $this->link_type, $this->link_id, $telid, $phone['type'],
                           format_phone_number($phone['tel']), $phone['tel'], $phone['pub'], $phone['comment']);
          }
      }
      {
          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);
 +                     $page->pid(), $this->link_type, $this->link_id);
 +        $this->saveTels($page->pid(), $field, $value);
      }
  
      //Only saves phones without a delete operation
 -    public function saveTels($field, $value)
 +    public function saveTels($pid, $field, $value)
      {
          foreach ($value as $telid=>&$phone) {
 -            $this->saveTel($telid, $phone);
 +            $this->saveTel($pid, $telid, $phone);
          }
      }
  }
@@@ -202,9 -208,9 +202,9 @@@ class ProfilePub extends ProfileNoSav
          if (is_null($value)) {
              return isset($page->values[$field]) ? $page->values[$field] : S::v($field);
          }
-         if (is_null($value) || !$value) {
+         if (!$value) {
              $value = 'private';
-         } else if ($value == 'on') { // Checkbox
+         } elseif ($value == 'on') { // Checkbox
              $value = 'public';
          }
          return $value;
@@@ -217,7 -223,7 +217,7 @@@ class ProfileBool extends ProfileNoSav
      {
          $success = true;
          if (is_null($value)) {
-             $value = @$page->values[$field];
+             $value = isset($page->values[$field]) ? $page->values[$field] : null;
          }
          return $value ? "1" : "";
      }
@@@ -248,44 -254,29 +248,29 @@@ class ProfileDate extends ProfileNoSav
      }
  }
  
- abstract class ProfileGeoloc implements ProfileSetting
+ abstract class ProfileGeocoding implements ProfileSetting
  {
-     protected function geolocAddress(array &$address, &$success)
+     protected function geocodeAddress(array &$address, &$success)
      {
-         require_once 'geoloc.inc.php';
+         require_once 'geocoding.inc.php';
          $success = true;
-         unset($address['geoloc']);
-         unset($address['geoloc_cityid']);
-         if (@$address['parsevalid']
-             || (@$address['text'] && @$address['changed'])
-             || (@$address['text'] && !@$address['cityid'])) {
-             $address = array_merge($address, empty_address());
-             $new = get_address_infos(@$address['text']);
-             if (compare_addresses_text(@$address['text'], $geotxt = get_address_text($new))
-                 || (@$address['parsevalid'] && @$address['cityid'])) {
-                 $address = array_merge($address, $new);
-                 $address['checked'] = true;
-             } else if (@$address['parsevalid']) {
-                 $address = array_merge($address, cut_address(@$address['text']));
-                 $address['checked'] = true;
+         if ($address['changed'] == 1) {
+             $gmapsGeocoder = new GMapsGeocoder();
+             $address = $gmapsGeocoder->getGeocodedAddress($address);
+             if (isset($address['geoloc'])) {
+                 $success = false;
+             }
+         }
+         if (isset($address['geoloc_choice'])) {
+             if ($address['geoloc_choice'] == 0) {
                  $mailer = new PlMailer('geoloc/geoloc.mail.tpl');
-                 $mailer->assign('text', get_address_text($address));
-                 $mailer->assign('geoloc', $geotxt);
+                 $mailer->assign('text', $address['text']);
+                 $mailer->assign('geoloc', $address['geoloc']);
                  $mailer->send();
-             } else if (@$address['changed'] || !@$address['checked']) {
-                 $success = false;
-                 $address = array_merge($address, cut_address(@$address['text']));
-                 $address['checked'] = false;
-                 $address['geoloc'] = $geotxt;
-                 $address['geoloc_cityid'] = $new['cityid'];
-             } else {
-                 $address = array_merge($address, cut_address(@$address['text']));
-                 $address['checked'] = true;
              }
+             $gmapsGeocoder = new GMapsGeocoder();
+             $address = $gmapsGeocoder->stripGeocodingFromAddress($address);
          }
-         $address['precise_lat'] = rtrim($address['precise_lat'], '.0');
-         $address['precise_lon'] = rtrim($address['precise_lon'], '.0'); 
-         $address['text'] = get_address_text($address);
      }
  }
  
@@@ -301,14 -292,10 +286,14 @@@ abstract class ProfilePage implements P
  
      public $orig     = array();
      public $values   = array();
 +    public $profile  = null;
 +    public $owner    = null;
  
      public function __construct(PlWizard &$wiz)
      {
          $this->wizard =& $wiz;
 +        $this->profile = $this->wizard->getUserData('profile');
 +        $this->owner   = $this->wizard->getUserData('owner');
      }
  
      protected function _fetchData()
                  $setting->save($this, $field, $this->values[$field]);
              }
              if ($this->changed[$field] && @$this->watched[$field]) {
 -                register_profile_update(S::i('uid'), $field);
 +                WatchProfileUpdate::register($this->profile, $field);
              }
          }
          $this->_saveData();
  
          // Update the last modification date
 -        XDB::execute('REPLACE INTO  user_changes
 -                               SET  user_id = {?}', S::v('uid'));
 -        if (!S::has('suid')) {
 -            register_watch_op(S::i('uid'), WATCH_FICHE);
 -        }
 +        XDB::execute('UPDATE  profiles
 +                         SET  last_change = NOW()
 +                       WHERE  pid = {?}', $this->pid());
          global $platal;
 -        S::logger()->log('profil', $platal->pl_self(1));
 +        S::logger()->log('profil', $platal->pl_self(2));
      }
  
      protected function checkChanges()
          return 'profile/base.tpl';
      }
  
 +    public function pid()
 +    {
 +        return $this->profile->id();
 +    }
 +
 +    public function hrpid()
 +    {
 +        return $this->profile->hrpid();
 +    }
 +
      protected function _prepare(PlPage &$page, $id)
      {
      }
              $page->assign($field, $value);
          }
          $this->_prepare($page, $id);
 +        $page->assign('profile', $this->profile);
 +        $page->assign('owner', $this->owner);
          $page->assign('profile_page', $this->pg_template);
          $page->assign('errors', $this->errors);
      }
diff --combined modules/search.php
@@@ -73,9 -73,9 +73,9 @@@ class SearchModule extends PLModul
      {
          global $globals;
  
 -        $res = XDB::query("SELECT  MIN(`diminutif`), MAX(`diminutif`)
 -                             FROM  `groupex`.`asso`
 -                            WHERE  `cat` = 'Promotions'");
 +        $res = XDB::query("SELECT  MIN(diminutif), MAX(diminutif)
 +                             FROM  groupex.asso
 +                            WHERE  cat = 'Promotions'");
          list($min, $max) = $res->fetchOneRow();
          $page->assign('promo_min', $min);
          $page->assign('promo_max', $max);
              $this->form_prepare();
          } else {
              $textFields = array(
-                 'country'         => array('field' => 'a2', 'table' => 'geoloc_pays', 'text' => 'pays', 'exact' => false),
+                 'country'         => array('field' => 'iso_3166_1_a2', 'table' => 'geoloc_countries', 'text' => 'countryFR',
+                                            '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'),
+                 'nationalite'     => array('field' => 'iso_3166_1_a2', 'table' => 'geoloc_countries', 
+                                            'text' => 'nationalityFR', '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),
                                             '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)
+                 'city'            => array('table' => 'geoloc_localities', 'text' => 'name', 'exact' => false)
              );
              if (!Env::has('page')) {
                  S::logger()->log('search', 'adv=' . var_export($_GET, true));
                             array('',
                                   '\\\\\1',
                                   '.*'),
 -                           $_REQUEST['q']);
 +                           Env::s('q'));
          if (!$q) exit();
  
          // try to look in cached results
 -        $cache = XDB::query('SELECT  `result`
 -                               FROM  `search_autocomplete`
 -                              WHERE  `name` = {?} AND
 -                                     `query` = {?} AND
 -                                     `generated` > NOW() - INTERVAL 1 DAY',
 +        $cache = XDB::query('SELECT  result
 +                               FROM  search_autocomplete
 +                              WHERE  name = {?} AND
 +                                     query = {?} AND
 +                                     generated > NOW() - INTERVAL 1 DAY',
                               $type, $q);
          if ($res = $cache->fetchOneCell()) {
              echo $res;
          }
  
          // default search
 -        $unique = '`user_id`';
 -        $db = '`auth_user_md5`';
 +        $unique = 'pid';
 +        $db = 'profiles';
          $realid = false;
          $beginwith = true;
          $field2 = false;
  
          switch ($type) {
            case 'binetTxt':
 -            $db = '`binets_def` INNER JOIN
 -                   `binets_ins` ON(`binets_def`.`id` = `binets_ins`.`binet_id`)';
 -            $field = '`binets_def`.`text`';
 +            $db = 'binets_def INNER JOIN
 +                   binets_ins ON(binets_def.id = binets_ins.binet_id)';
 +            $field = 'binets_def.text';
              if (strlen($q) > 2)
                  $beginwith = false;
 -            $realid = '`binets_def`.`id`';
 +            $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`';
 +            $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`';
 +            $realid = 'profile_networking_enum.network_type';
              break;
            case 'city':
-             $db = 'geoloc_city INNER JOIN
-                    adresses ON(geoloc_city.id = adresses.cityid)';
-             $unique='uid';
-             $field='geoloc_city.name';
+             $db     = 'geoloc_localities INNER JOIN
+                        profile_addresses ON (geoloc_localities.id = profile_addresses.localityId)';
+             $unique = 'uid';
+             $field  ='geoloc_localities.name';
              break;
            case 'countryTxt':
-             $db = 'geoloc_pays INNER JOIN
-                    adresses ON(geoloc_pays.a2 = adresses.country)';
-             $unique = 'uid';
-             $field = 'geoloc_pays.pays';
-             $field2 = 'geoloc_pays.country';
-             $realid = 'geoloc_pays.a2';
+             $db     = 'geoloc_countries INNER JOIN
+                        profile_addresses ON (geoloc_countries.iso_3166_1_a2 = profile_addresses.countryId)';
+             $unique = 'pid';
+             $field  = 'geoloc_countries.countryFR';
+             $realid = 'geoloc_countries.iso_3166_1_a2';
              break;
            case 'entreprise':
              $db     = 'profile_job_enum INNER JOIN
              $unique = 'm.uid';
              break;
            case 'nationaliteTxt':
-             $db = 'geoloc_pays AS acgp
-                   INNER JOIN profiles AS acp ON (acgp.a2 IN (acp.nationality1, acp.nationality2, acp.nationality3))';
-             $field = 'IF(acgp.nat = \'\', acgp.pays, acgp.nat)';
-             $realid = 'acgp.a2';
+             $db     = 'geoloc_countries INNER JOIN
 -                       auth_user_md5 ON (geoloc_countries.a2 = auth_user_md5.nationalite
 -                                         OR geoloc_countries.a2 = auth_user_md5.nationalite2
 -                                         OR geoloc_countries.a2 = auth_user_md5.nationalite3)';
++                       profile ON (geoloc_countries.a2 IN (profile.nationality1, profile.nationality2, profile.nationality3))';
+             $field  = 'geoloc_countries.nationalityFR';
+             $realid = 'geoloc_countries.iso_3166_1_a2';
              break;
            case 'description':
              $db     = 'profile_job';
              $distinct  = false;
              break;
            case 'sectionTxt':
 -            $db = '`sections` INNER JOIN
 -                   `auth_user_md5` ON(`auth_user_md5`.`section` = `sections`.`id`)';
 -            $field = '`sections`.`text`';
 -            $realid = '`sections`.`id`';
 +            $db = 'sections AS acs
 +                   INNER JOIN profiles AS acp ON (acp.section = acs.id)';
 +            $field = 'acs.text';
 +            $realid = 'acs.id';
              $beginwith = false;
              break;
            default: exit();
                  $res .= "\n";
              }
          }
 -        XDB::query('REPLACE INTO  `search_autocomplete`
 +        XDB::query('REPLACE INTO  search_autocomplete
                            VALUES  ({?}, {?}, {?}, NOW())',
                      $type, $q, $res);
          echo $res;
      function handler_list(&$page, $type = null, $idVal = null)
      {
          // Give the list of all values possible of type and builds a select input for it
 -        $field = '`text`';
 -        $id = '`id`';
 +        $field = 'text';
 +        $id = 'id';
          $where = '';
  
          switch ($type) {
            case 'binet':
 -            $db = '`binets_def`';
 +            $db = 'binets_def';
              break;
            case 'networking_type':
 -            $db = '`profile_networking_enum`';
 -            $field = '`name`';
 -            $id = '`network_type`';
 +            $db = 'profile_networking_enum';
 +            $field = 'name';
 +            $id = 'network_type';
              break;
            case 'country':
-             $db = 'geoloc_pays';
-             $field = 'pays';
-             $id = 'a2';
+             $db    = 'geoloc_countries';
+             $field = 'countryFR';
+             $id    = 'iso_3166_1_a2';
              $page->assign('onchange', 'changeCountry(this.value)');
              break;
            case 'fonction':
 -            $db = '`fonctions_def`';
 -            $field = '`fonction_fr`';
 +            $db = 'fonctions_def';
 +            $field = 'fonction_fr';
              break;
            case 'diploma':
              header('Content-Type: text/xml; charset="UTF-8"');
              $field = 'nom';
              break;
            case 'nationalite':
-             $db = 'geoloc_pays AS acgp INNER JOIN
+             $db    = 'geoloc_countries INNER JOIN
 -                      auth_user_md5 ON (geoloc_countries.iso_3166_1_a2 = auth_user_md5.nationalite
 -                                        OR geoloc_countries.iso_3166_1_a2 = auth_user_md5.nationalite2
 -                                        OR geoloc_countries.iso_3166_1_a2 = auth_user_md5.nationalite3)';
 +                   profiles AS acp ON (acgp.a2 IN (acp.nationality1, acp.nationality2, acp.nationality3))';
-             $field = 'IF(acgp.nat=\'\', acgp.pays, acgp.nat)';
-             $id = 'acgp.a2';
+             $field = 'nationalityFR';
+             $id    = 'iso_3166_1_a2';
              break;
            case 'region':
-             $db = 'geoloc_region';
+             $db    = 'geoloc_administrativeareas';
              $field = 'name';
-             $id = 'region';
+             $id    = 'id';
              if (isset($_REQUEST['country'])) {
-                 $where .= ' WHERE a2 = "'.$_REQUEST['country'].'"';
+                 $where .= ' WHERE country = "' . $_REQUEST['country'] . '"';
              }
              break;
            case 'school':
              $page->assign('onchange', 'changeSchool(this.value)');
              break;
            case 'section':
 -            $db = '`sections`';
 +            $db = 'sections';
              break;
            case 'secteur':
              $db    = 'profile_job_sector_enum INNER JOIN
  {foreach from=$assos item="asso"}
  <div style="width:48%;float:left" >
  <fieldset style="margin:0.6em">
 -    <legend style="padding:4px"><strong><a href="http://www.polytechnique.net/login/{$asso.diminutif}">{$asso.nom}</a></strong></legend>
 -    {if $asso.has_logo}
 -    <a href="http://www.polytechnique.net/login/{$asso.diminutif}" style="width: 30%; display: block; float: right; ">
 -      <img alt="[ LOGO ]" src="http://www.polytechnique.net/{$asso.diminutif}/logo" style="width: 100%" />
 +    <legend style="padding:4px"><strong><a href="http://www.polytechnique.net/login/{$asso->diminutif}">{$asso->nom}</a></strong></legend>
 +    {if $asso->has_logo}
 +    <a href="http://www.polytechnique.net/login/{$asso->diminutif}" style="width: 30%; display: block; float: right; ">
 +      <img alt="[ LOGO ]" src="http://www.polytechnique.net/{$asso->diminutif}/logo" style="width: 100%" />
      </a>
      {/if}
      <ul style="padding-top:0px;padding-bottom:0px">
 -        <li><a href="http://www.polytechnique.net/{$asso.diminutif}/annuaire">annuaire</a></li>
 -        <li><a href="http://www.polytechnique.net/{$asso.diminutif}/trombi">trombino</a></li>
 -        {if $asso.lists}
 -            <li><a href="http://www.polytechnique.net/{$asso.diminutif}/lists">listes de diffusion</a></li>
 +        <li><a href="http://www.polytechnique.net/{$asso->diminutif}/annuaire">annuaire</a></li>
 +        <li><a href="http://www.polytechnique.net/{$asso->diminutif}/trombi">trombino</a></li>
-         <li><a href="http://www.polytechnique.net/{$asso->diminutif}/geoloc">carte</a></li>
 +        {if $asso->lists}
 +            <li><a href="http://www.polytechnique.net/{$asso->diminutif}/lists">listes de diffusion</a></li>
          {/if}
 -        {if $asso.events}
 -            <li><a href="http://www.polytechnique.net/{$asso.diminutif}/events">{$asso.events} événement{if $asso.events > 1}s{/if}</a></li>
 +        {if $asso->events}
 +            <li><a href="http://www.polytechnique.net/{$asso->diminutif}/events">{$asso->events} événement{if $asso->events > 1}s{/if}</a></li>
          {/if}
 -        {if !$asso.lists}
 +        {if !$asso->lists}
              <li style="display:block">&nbsp;</li>
          {/if}
 -        {if !$asso.events}
 +        {if !$asso->events}
              <li style="display:block">&nbsp;</li>
          {/if}
      </ul>