Merge branch 'xorg/1.0.2/master' into xorg/master
[platal.git] / classes / geocoder.php
1 <?php
2 /***************************************************************************
3 * Copyright (C) 2003-2011 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
22 // Interface for an address geocoder. It provides support for transforming a
23 // free form address into a fully structured one.
24 abstract class Geocoder {
25 // Geocodes @p the address, and returns the corresponding updated address.
26 // Unknown key-value pairs available in the input map are retained as-is.
27 abstract public function getGeocodedAddress(Address &$address);
28
29 // Cleans the address from its geocoded data
30 abstract public function stripGeocodingFromAddress(Address &$address);
31
32 // Updates geoloc_administrativeareas, geoloc_subadministrativeareas and
33 // geoloc_localities databases with new geocoded data and returns the
34 // corresponding id.
35 static public function getAreaId(Address &$address, $area)
36 {
37 static $databases = array(
38 'administrativeArea' => 'geoloc_administrativeareas',
39 'subAdministrativeArea' => 'geoloc_subadministrativeareas',
40 'locality' => 'geoloc_localities',
41 );
42 static $extras = array(
43 'subAdministrativeArea' => array(
44 'field' => 'administrativearea',
45 'name' => 'administrativeAreaName'
46 )
47 );
48
49 $areaName = $area . 'Name';
50 $areaNameLocal = $areaName . 'Local';
51 $areaId = $area . 'Id';
52 if (!is_null($address->$areaName) && isset($databases[$area])) {
53 $extra = (isset($extras[$area]) ? $extras[$area]['administrativeAreaName'] : false);
54
55 $res = XDB::query('SELECT id, nameLocal
56 FROM ' . $databases[$area] . '
57 WHERE name = {?}',
58 $address->$areaName);
59 if ($res->numRows() == 0) {
60 XDB::execute('INSERT INTO ' . $databases[$area] . ' (name, nameLocal, country' .
61 ($extra ? ', ' . $extras[$area]['field'] : '') . ')
62 VALUES ({?}, {?}, {?}' . ($extra ? ', {?}' : '') . ')',
63 $address->$areaName, $address->$areaNameLocal, $address->countryId,
64 ($extra ? $address->$extra : null));
65 $address->$areaId = XDB::insertId();
66 } else {
67 // XXX: remove this once all areas have both nameLocal and name.
68 list($id, $name) = $res->fetchOneRow();
69 if (is_null($name) && !is_null($address->$areaNameLocal)) {
70 XDB::execute('UPDATE ' . $databases[$area] . '
71 SET nameLocal = {?}
72 WHERE id = {?}',
73 $address->$areaNameLocal, $id);
74 }
75 $address->$areaId = $id;
76 }
77 } elseif (empty($address->$areaId)) {
78 $address->$areaId = null;
79 }
80 }
81
82 // Returns the part of the text preceeding the line with the postal code
83 // and the city name, within the limit of $limit number of lines.
84 static public function getFirstLines($text, $postalCode, $limit)
85 {
86 $text = str_replace("\r", '', $text);
87 $textArray = explode("\n", $text);
88 $linesNb = $limit;
89
90 for ($i = 0; $i < count($textArray); ++$i) {
91 if ($i > $limit || strpos($textArray[$i], $postalCode) !== false) {
92 $linesNb = $i;
93 break;
94 }
95 }
96 $firstLines = implode("\n", array_slice($textArray, 0, $linesNb));
97
98 // Adds empty lines to complete the $limit lines required.
99 for (; $i < $limit; ++$i) {
100 $firstLines .= "\n";
101 }
102 return $firstLines;
103 }
104
105 // Returns the number of non geocoded addresses for a user.
106 static public function countNonGeocoded($pid, $jobid = null, $type = Address::LINK_PROFILE)
107 {
108 $where = array();
109 if (!is_null($pid)) {
110 $where[] = XDB::format('pid = {?}', $pid);
111 }
112 if (!is_null($jobid)) {
113 $where[] = XDB::format('jobid = {?}', $jobid);
114 }
115 $where[] = XDB::format('FIND_IN_SET({?}, type) AND accuracy = 0', $type);
116 $res = XDB::query('SELECT COUNT(*)
117 FROM profile_addresses
118 WHERE ' . implode(' AND ', $where),
119 $pid);
120 return $res->fetchOneCell();
121 }
122 }
123
124 // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8:
125 ?>