Non geocoded addresses could not be saved.
[platal.git] / include / geoloc.inc.php
index 8511a4e..0a6bfac 100644 (file)
@@ -1,6 +1,6 @@
 <?php
 /***************************************************************************
- *  Copyright (C) 2003-2008 Polytechnique.org                              *
+ *  Copyright (C) 2003-2009 Polytechnique.org                              *
  *  http://opensource.polytechnique.org/                                   *
  *                                                                         *
  *  This program is free software; you can redistribute it and/or modify   *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
  ***************************************************************************/
 
-// {{{ liste les pays ou les régions d'un pays
-/** donne la liste déroulante des pays
- * @param $current pays actuellement selectionné
- */
-function geoloc_country($current, $avail_only = false)
-{
-    if ($avail_only) {
-        $res = XDB::iterRow('SELECT  g.a2, g.pays
-                               FROM  geoloc_pays AS g
-                         INNER JOIN  adresses    AS a ON(a.country = g.a2)
-                           GROUP BY  g.a2
-                           ORDER BY  g.pays');
-    } else {
-        $res = XDB::iterRow('SELECT a2,pays FROM geoloc_pays ORDER BY pays');
-    }
-    $html = "";
-    while (list($my_id, $my_pays) = $res->next()) {
-        $html .= sprintf("<option value=\"%s\" %s>%s</option>\n",
-                         $my_id, ($current==$my_id?"selected='selected'":""), $my_pays);
-    }
-    return $html;
-}
-
-/** donne la liste deroulante des regions pour un pays
- * @param $pays le pays dont on veut afficher les regions
- * @param $current la region actuellement selectionnee
- */
-function geoloc_region($country, $current, $avail_only = false)
-{
-    if ($avail_only) {
-        $res = XDB::iterRow('SELECT  r.region, r.name
-                               FROM  geoloc_region AS r
-                         INNER JOIN  adresses      AS a ON (a.country = r.a2 AND a.region = r.region)
-                              WHERE  r.a2 = {?}
-                           GROUP BY  r.region
-                           ORDER BY  r.name', $country);
-    } else {
-        $res = XDB::iterRow('SELECT  region,name
-                               FROM  geoloc_region
-                              WHERE  a2 = {?}
-                           ORDER BY  name', $country);
-    }
-    $html = "<option value=\"\"></option>";
-    while (list($regid, $regname) = $res->next()) {
-        $html .= sprintf("<option value=\"%s\" %s>%s</option>\n",
-                 $regid, ($current==$regid?"selected='selected'":""), $regname);
-    }
-    return $html;
-}
-// }}}
-
-// {{{ get_address_infos($txt)
-/** retrieve the infos on a text address
- * store on the fly the info of the city concerned
- * @param $txt the raw text of an address
- */
-function get_address_infos($txt)
-{
-    global $globals;
-    $url = $globals->geoloc->webservice_url."address.php?precise=1&txt=" . urlencode($txt);
-    if (!($f = @fopen($url, 'r'))) return false;
-    $keys = explode('|',fgets($f));
-    $vals = explode('|',fgets($f));
-    $infos = array();
-    foreach ($keys as $i=>$key) {
-        if($vals[$i]) {
-            if ($key == 'sql') {
-                $infos[$key] = $vals[$i];
-            } else {
-                $val = strtr($vals[$i], array(chr(197).chr(147) => "&oelig;"));
-                $infos[$key] = $val;
-            }
-        }
-    }
-    if (isset($infos['sql']) && $infos['sql'])
-       XDB::execute("REPLACE INTO  geoloc_city
-                           VALUES  ".$infos['sql']);
-    if (isset($infos['display']) && $infos['display'])
-        XDB::execute("UPDATE  geoloc_pays
-                         SET  display = {?}
-                       WHERE  a2 = {?}", $infos['display'], $infos['country']);
-    if (isset($infos['cityid'])) {
-        fix_cities_not_on_map(1, $infos['cityid']);
-        if (floatval($infos['precise_lat']) && floatval($infos['precise_lon'])) {
-            $res = XDB::query("SELECT  c.lat / 100000, c.lon / 100000
-                                 FROM  geoloc_city AS c
-                                WHERE  c.id = {?}", $infos['cityid']);
-            if ($res->numRows()) {
-                list($glat, $glng) = $res->fetchOneRow();
-                $infos['precise_lat'] = $glat;
-                $infos['precise_lon'] = $glng;
-            }
-        }
-    }
-    return $infos;
-}
-// }}}
-
-// {{{ get_cities_maps($array)
-/* get all the maps id of the cities contained in an array */
-function get_cities_maps($array)
-{
-    global $globals;
-    implode("\n",$array);
-    $url = $globals->geoloc->webservice_url."findMaps.php?datatext=".urlencode(implode("\n", $array));
-    if (!($f = @fopen($url, 'r'))) return false;
-    $maps = array();
-    while (!feof($f))
-    {
-        $l = trim(fgets($f));
-        $tab = explode(';', $l);
-        $i = $tab[0];
-        unset($tab[0]);
-        $maps[$i] = $tab;
-    }
-    return $maps;
-}
-// }}}
-
-// {{{ get_new_maps($url)
-/** set new maps from url **/
-function get_new_maps($url)
-{
-    if (!($f = @fopen($url, 'r'))) {
-        return false;
-    }
-    XDB::query('TRUNCATE TABLE geoloc_maps');
-    $s = '';
-    while (!feof($f)) {
-        $l = fgetcsv($f, 1024, ';', '"');
-        foreach ($l as $i => $val) {
-            if ($val != 'NULL') {
-                $l[$i] = '\''.addslashes($val).'\'';
-            }
-        }
-        $s .= ',('.implode(',',$l).')';
-    }
-    XDB::execute('INSERT INTO geoloc_maps VALUES '.substr($s, 1));
-    return true;
-}
-// }}}
-
 // {{{ get_address_text($adr)
 /** make the text of an address that can be read by a mailman
  * @param $adr an array with all the usual fields
@@ -201,7 +59,6 @@ function get_address_text($adr)
     return trim($t);
 }
 // }}}
-
 // {{{ compare_addresses_text($a, $b)
 /** compares if two address matches
  * @param $a the raw text of an address
@@ -218,7 +75,7 @@ function compare_addresses_text($a, $b)
     if (count($lb) > count($la) + 1) {
         return false;
     }
-    foreach ($la as $i=>$l) {
+    foreach ($la as $i => $l) {
         if (levenshtein(trim($l), trim($lb[$i])) > 3) {
             return false;
         }
@@ -227,31 +84,6 @@ function compare_addresses_text($a, $b)
 }
 
 // }}}
-
-function empty_address() {
-    return Array(
-        "adr1" => "",
-        "adr2" => "",
-        "adr3" => "",
-        "cityid" => NULL,
-        "city" => "",
-        "postcode" => "",
-        "region" => "",
-        "regiontxt" => "",
-        "country" => "00",
-        "countrytxt" => "",
-        "precise_lat" => "",
-        "precise_lon" => "");
-}
-
-// create a simple address from a text without geoloc
-function cut_address($txt)
-{
-    $txt = str_replace("\r\n", "\n", $txt);
-    ereg("^([^\n]*)(\n([^\n]*)(\n(.*))?)?$", trim($txt), $a);
-    return array("adr1" => trim($a[1]), "adr2" => trim($a[3]), "adr3" => trim(str_replace("\n", " ", $a[5])));
-}
-
 // {{{ localize_addresses($uid)
 /* localize all the address of a user and modify the database
  * if the new address match with the old one
@@ -290,7 +122,89 @@ function localize_addresses($uid)
     return $erreur;
 }
 // }}}
+// {{{ get_address_infos($txt)
+/** retrieve the infos on a text address
+ * store on the fly the info of the city concerned
+ * @param $txt the raw text of an address
+ */
+
+function get_address_infos($txt)
+{
+    global $globals;
 
+    $url = $globals->geoloc->webservice_url."address.php?precise=1&txt=" . urlencode($txt);
+    if ($globals->debug & DEBUG_BT) {
+        if (!isset(PlBacktrace::$bt['Geoloc'])) {
+            new PlBacktrace('Geoloc');
+        }
+        PlBacktrace::$bt['Geoloc']->start($url);
+    }
+    $f = @fopen($url, 'r');
+    if ($f === false) {
+        if ($globals->debug & DEBUG_BT) {
+            PlBacktrace::$bt['Geoloc']->stop(0, 'Can\'t fetch result');
+        }
+        return false;
+    }
+    $keys = explode('|',fgets($f));
+    $vals = explode('|',fgets($f));
+    if ($globals->debug & DEBUG_BT) {
+        $data = array();
+        for ($i = 0 ; $i < count($keys) ; ++$i) {
+            $data[] = array($keys[$i], $vals[$i]);
+        }
+        PlBacktrace::$bt['Geoloc']->stop(count($keys), null, $data);
+    }
+    $infos = empty_address();
+    foreach ($keys as $i=>$key) {
+        if($vals[$i]) {
+            if ($key == 'sql') {
+                $infos[$key] = $vals[$i];
+            } else {
+                $val = strtr($vals[$i], array(chr(197).chr(147) => "&oelig;"));
+                $infos[$key] = $val;
+            }
+        }
+    }
+    if (empty($infos['country'])) {
+        $infos['country'] = '00';
+    }
+    if (isset($infos['sql']) && $infos['sql']) {
+        $sql = explode(', ', trim($infos['sql'], '()'));
+        if (count($sql) == 16) {
+            for ($i = 0 ; $i < 16 ; ++$i) {
+                $sql[$i] = stripslashes(trim($sql[$i], ' \''));
+            }
+            XDB::execute("REPLACE INTO  geoloc_city
+                                VALUES  ({?}, {?}, {?}, {?}, {?}, {?},
+                                         {?}, {?}, {?}, {?}, {?}, {?},
+                                         {?}, {?}, {?}, {?})",
+                         $sql[0], $sql[1], $sql[2], $sql[3], $sql[4], $sql[5],
+                         $sql[6], $sql[7], $sql[8], $sql[9], $sql[10], $sql[11],
+                         $sql[12], $sql[13], $sql[14], $sql[15]);
+        }
+    }
+    if (isset($infos['display']) && $infos['display'])
+        XDB::execute("UPDATE  geoloc_pays
+                         SET  display = {?}
+                       WHERE  a2 = {?}", $infos['display'], $infos['country']);
+    if (isset($infos['cityid'])) {
+        fix_cities_not_on_map(1, $infos['cityid']);
+        if (floatval($infos['precise_lat']) && floatval($infos['precise_lon'])) {
+            $res = XDB::query("SELECT  c.lat / 100000, c.lon / 100000
+                                 FROM  geoloc_city AS c
+                                WHERE  c.id = {?}", $infos['cityid']);
+            if ($res->numRows()) {
+                list($glat, $glng) = $res->fetchOneRow();
+                $infos['precise_lat'] = $glat;
+                $infos['precise_lon'] = $glng;
+            }
+        }
+    }
+    return $infos;
+}
+
+// }}}
 // {{{ synchro_city($id)
 /** synchronise the local geoloc_city base to geoloc.org
  * @param $id the id of the city to synchronize
@@ -308,7 +222,6 @@ function synchro_city($id)
     }
 }
  // }}}
-
 // {{{ function fix_cities_not_on_map($limit)
 function fix_cities_not_on_map($limit=false, $cityid=false)
 {
@@ -326,8 +239,10 @@ function fix_cities_not_on_map($limit=false, $cityid=false)
                 $values .= ",($cityid, $map_id, '')";
             }
         }
-        XDB::execute("REPLACE INTO  geoloc_city_in_maps
-                            VALUES  ".substr($values, 1));
+        if (strlen($values) > 1) {
+            XDB::execute("REPLACE INTO  geoloc_city_in_maps
+                                VALUES  ".substr($values, 1));
+        }
     } else {
         return false;
     }
@@ -349,7 +264,100 @@ function set_smallest_levels()
     return true;
 }
 // }}}
+// {{{ geoloc_country($current, $avail_only = false)
+/** donne la liste déroulante des pays
+ * @param $current pays actuellement selectionné
+ */
+function geoloc_country($current, $avail_only = false)
+{
+    if ($avail_only) {
+        $res = XDB::iterRow('SELECT  g.a2, g.pays
+                               FROM  geoloc_pays AS g
+                         INNER JOIN  adresses    AS a ON(a.country = g.a2)
+                           GROUP BY  g.a2
+                           ORDER BY  g.pays');
+    } else {
+        $res = XDB::iterRow('SELECT a2,pays FROM geoloc_pays ORDER BY pays');
+    }
+    $html = "";
+    while (list($my_id, $my_pays) = $res->next()) {
+        $html .= sprintf("<option value=\"%s\" %s>%s</option>\n",
+                         $my_id, ($current==$my_id?"selected='selected'":""), $my_pays);
+    }
+    return $html;
+}
 
+// }}}
+// {{{ geoloc_region($country, $current, $avail_only = false)
+/** donne la liste deroulante des regions pour un pays
+ * @param $pays le pays dont on veut afficher les regions
+ * @param $current la region actuellement selectionnee
+ */
+function geoloc_region($country, $current, $avail_only = false)
+{
+    if ($avail_only) {
+        $res = XDB::iterRow('SELECT  r.region, r.name
+                               FROM  geoloc_region AS r
+                         INNER JOIN  adresses      AS a ON (a.country = r.a2 AND a.region = r.region)
+                              WHERE  r.a2 = {?}
+                           GROUP BY  r.region
+                           ORDER BY  r.name', $country);
+    } else {
+        $res = XDB::iterRow('SELECT  region,name
+                               FROM  geoloc_region
+                              WHERE  a2 = {?}
+                           ORDER BY  name', $country);
+    }
+    $html = "<option value=\"\"></option>";
+    while (list($regid, $regname) = $res->next()) {
+        $html .= sprintf("<option value=\"%s\" %s>%s</option>\n",
+                 $regid, ($current==$regid?"selected='selected'":""), $regname);
+    }
+    return $html;
+}
+// }}}
+// {{{ get_cities_maps($array)
+/* get all the maps id of the cities contained in an array */
+function get_cities_maps($array)
+{
+    global $globals;
+    implode("\n",$array);
+    $url = $globals->geoloc->webservice_url."findMaps.php?datatext=".urlencode(implode("\n", $array));
+    if (!($f = @fopen($url, 'r'))) return false;
+    $maps = array();
+    while (!feof($f))
+    {
+        $l = trim(fgets($f));
+        $tab = explode(';', $l);
+        $i = $tab[0];
+        unset($tab[0]);
+        $maps[$i] = $tab;
+    }
+    return $maps;
+}
+// }}}
+// {{{ get_new_maps($url)
+/** set new maps from url **/
+function get_new_maps($url)
+{
+    if (!($f = @fopen($url, 'r'))) {
+        return false;
+    }
+    XDB::query('TRUNCATE TABLE geoloc_maps');
+    $s = '';
+    while (!feof($f)) {
+        $l = fgetcsv($f, 1024, ';', '"');
+        foreach ($l as $i => $val) {
+            if ($val != 'NULL') {
+                $l[$i] = '\''.addslashes($val).'\'';
+            }
+        }
+        $s .= ',('.implode(',',$l).')';
+    }
+    XDB::execute('INSERT INTO geoloc_maps VALUES '.substr($s, 1));
+    return true;
+}
+// }}}
 
 function geoloc_to_x($lon, $lat)
 {
@@ -525,7 +533,6 @@ function geoloc_getData_subcountries($mapid, $sin, $minentities)
 
     return array($countries, $cities);
 }
-// }}}
 
 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
 ?>