From 57fa97b3b0820a76b26a1d17c078c3663b161922 Mon Sep 17 00:00:00 2001 From: =?utf8?q?St=C3=A9phane=20Jacob?= Date: Tue, 10 May 2011 16:38:54 +0200 Subject: [PATCH] Allows users to notify erroneous geocoding. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Stéphane Jacob --- classes/address.php | 43 ++++++- htdocs/javascript/profile.js | 9 +- include/validations.inc.php | 19 +++ include/validations/address.inc.php | 174 ++++++++++++++++++++++++++ modules/profile.php | 16 +++ modules/profile/addresses.inc.php | 2 + templates/geoloc/form.address.tpl | 26 +++- templates/include/form.valid.address.tpl | 28 +++++ templates/include/form.valid.edit-address.tpl | 25 ++++ 9 files changed, 337 insertions(+), 5 deletions(-) create mode 100644 include/validations/address.inc.php create mode 100644 templates/include/form.valid.address.tpl create mode 100644 templates/include/form.valid.edit-address.tpl diff --git a/classes/address.php b/classes/address.php index 1b15158..0fab4ed 100644 --- a/classes/address.php +++ b/classes/address.php @@ -310,6 +310,7 @@ class Address public $location_type = ''; public $partial_match = false; public $componentsIds = ''; + public $request = false; // Database's field required for both 'home' and 'job' addresses. public $pub = 'ax'; @@ -352,6 +353,7 @@ class Address array('', "\n"), $this->text)), 'CEDEX')) !== false); } } + $this->request = !is_null(AddressReq::get_request($this->pid, $this->jobid, $this->groupid, $this->type, $this->text)); } public function setId($id) @@ -611,7 +613,8 @@ class Address 'northeast_longitude' => $this->northeast_longitude, 'location_type' => $this->location_type, 'partial_match' => $this->partial_match, - 'componentsIds' => $this->componentsIds + 'componentsIds' => $this->componentsIds, + 'request' => $this->request ); if ($this->type == self::LINK_PROFILE || $this->type == self::LINK_JOB) { @@ -700,6 +703,44 @@ class Address } } + public function updateGeocoding($text) + { + $id = null; + $texts = XDB::fetchAllAssoc('id', 'SELECT id, text + FROM profile_addresses + WHERE pid = {?} AND jobid = {?} AND groupid = {?} AND type = {?}', + $this->pid, $this->jobid, $this->groupid, $this->type); + $text = preg_replace('/\s+/', ' ', $text); + foreach ($texts as $key => $value) { + if (strcmp($text, preg_replace('/\s+/', ' ', $value)) == 0) { + $id = $key; + break; + } + } + if (!is_null($id)) { + XDB::execute('UPDATE profile_addresses + SET text = {?}, postalText = {?}, types = {?}, formatted_address = {?}, + location_type = {?}, partial_match = {?}, latitude = {?}, longitude = {?}, + southwest_latitude = {?}, southwest_longitude = {?}, northeast_latitude = {?}, northeast_longitude = {?} + WHERE pid = {?} AND jobid = {?} AND groupid = {?} AND type = {?} AND id = {?}', + $this->text, $this->postalText, $this->types, $this->formatted_address, + $this->location_type, $this->partial_match, $this->latitude, $this->longitude, + $this->southwest_latitude, $this->southwest_longitude, $this->northeast_latitude, $this->northeast_longitude, + $this->pid, $this->jobid, $this->groupid, $this->type, $id); + + XDB::execute('DELETE FROM profile_addresses_components + WHERE pid = {?} AND jobid = {?} AND groupid = {?} AND type = {?} AND id = {?}', + $this->pid, $this->jobid, $this->groupid, $this->type, $id); + if ($this->componentsIds) { + foreach (explode(',', $this->componentsIds) as $component_id) { + XDB::execute('INSERT IGNORE INTO profile_addresses_components (pid, jobid, groupid, type, id, component_id) + VALUES ({?}, {?}, {?}, {?}, {?}, {?})', + $this->pid, $this->jobid, $this->groupid, $this->type, $id, $component_id); + } + } + } + } + public function delete() { XDB::execute('DELETE FROM profile_addresses diff --git a/htdocs/javascript/profile.js b/htdocs/javascript/profile.js index b95aa03..3a10c17 100644 --- a/htdocs/javascript/profile.js +++ b/htdocs/javascript/profile.js @@ -333,18 +333,21 @@ function addressChanged(prefid) $('#' + prefid + '_cont').find('[name*=changed]').val("1"); } -function deleteGeocoding() +function deleteGeocoding(prefid, hrpid) { var confirmation = confirm( "La localisation de l'adresse sert à deux choses : te placer dans " + "le planisphère et te faire apparaître dans la recherche avancée par " - + "pays, région, département, ville. La supprimer t'en fera disparaître. " + + "pays, région, département, ville... La supprimer t'en fera disparaître. " + "\nIl ne faut le faire que si cette localisation " + "est réellement erronée. Avant de supprimer cette localisation, l'équipe de " + "Polytechnique.org tentera de la réparer.\n\nConfirmes-tu ta " + "demande de suppression de cette localisation ?"); + if (confirmation) { - alert('Warning: not implemented yet.'); + var address = $('#' + prefid).find("[name*='[text]']").val(); + $.xpost('profile/ajax/address/del/' + hrpid, { address:address }); + $('#' + prefid + '_geocoding_removal').html('Localisation en attente de validation.'); } } diff --git a/include/validations.inc.php b/include/validations.inc.php index eb2cd4c..35746bd 100644 --- a/include/validations.inc.php +++ b/include/validations.inc.php @@ -624,6 +624,25 @@ abstract class ProfileValidate extends Validate } // }}} + // {{{ function get_all_typed_requests() + + /** Same as get_typed_request() but return an array of objects. + */ + static public function get_all_typed_requests($type) + { + $res = XDB::iterRow('SELECT data + FROM requests + WHERE type = {?} + ORDER BY stamp', + $type); + $array = array(); + while (list($data) = $res->next()) { + $array[] = Validate::unserialize($data); + } + return $array; + } + + // }}} // {{{ function get_typed_requests_count() /** Same as get_typed_requests() but returns the count of available requests. diff --git a/include/validations/address.inc.php b/include/validations/address.inc.php new file mode 100644 index 0000000..349674a --- /dev/null +++ b/include/validations/address.inc.php @@ -0,0 +1,174 @@ +key_pid = $_pid; + $this->key_jobid = $_jobid; + $this->key_groupid = $_groupid; + $this->key_type = $_type; + $this->given_text = $_text; + $address = new Address(array('changed' => 1, 'text' => $_text)); + $address->format(); + $this->address = $address->toFormArray(); + } + + // }}} + // {{{ function formu() + + public function formu() + { + return 'include/form.valid.address.tpl'; + } + + // }}} + // {{{ function editor() + + public function editor() + { + return 'include/form.valid.edit-address.tpl'; + } + + // }}} + // {{{ function handle_editor() + + protected function handle_editor() + { + $data = Post::v('valid'); + if (isset($data['text']) && $data['text'] != $this->toy_text && $data['text'] != $this->given_text) { + $this->toy_text = $data['text']; + $address = new Address(array('changed' => 1, 'text' => $this->toy_text)); + $address->format(); + $this->address = $address->toFormArray(); + } + $this->modified = isset($data['modified']); + + return true; + } + + // }}} + // {{{ function _mail_subj + + protected function _mail_subj() + { + return '[Polytechnique.org/Adresse] Demande d\'amélioration de la localisation d\'une adresse'; + } + + // }}} + // {{{ function _mail_body + + protected function _mail_body($isok) + { + if ($isok) { + return " Nous avons réussit à mieux localiser l'adresse."; + } else { + return " L'adresse est suffisemment bien localisée pour les besoins du site (recherche avancée, planisphère), nous avons donc choisi de ne pas la modifier."; + } + } + + // }}} + // {{{ function commit() + + public function commit() + { + $this->address = array_merge($this->address, array( + 'pid' => $this->key_pid, + 'jobid' => $this->key_jobid, + 'groupid' => $this->key_groupid, + 'type' => $this->key_type + )); + $this->address['text'] = ($this->modified ? $this->toy_text : $this->given_text);; + $this->address['changed'] = 0; + $address = new Address($this->address); + $address->format(); + $address->updateGeocoding($this->given_text); + + return true; + } + + // }}} + // {{{ function get_request() + + static public function get_request($pid, $jobid, $groupid, $type, $address) + { + $reqs = parent::get_typed_requests($pid, 'address'); + foreach ($reqs as &$req) { + if ($req->key_pid == $pid && $req->key_jobid == $jobid && $req->key_groupid == $groupid + && $req->key_type == $type && $req->address['text'] == $address) { + return $req; + } + } + return null; + } + + // }}} + // {{{ function purge_requests() + + // Purges address localization requests based on deleted addresses. + static public function purge_requests($pid, $jobid, $groupid, $type) + { + $requests = parent::get_all_typed_requests('address'); + foreach ($requests as &$req) { + if ($req->key_pid == $pid && $req->key_jobid == $jobid && $req->key_groupid == $groupid && $req->key_type == $type) { + $count = XDB::fetchOneCell('SELECT COUNT(*) + FROM profile_addresses + WHERE pid = {?} AND jobid = {?} AND groupid = {?} + AND type = {?} AND text = {?}', + $pid, $jobid, $groupid, $type, $req->address['text']); + if ($count == 0) { + $req->clean(); + } + } + } + } + + // }}} +} + +// }}} + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?> diff --git a/modules/profile.php b/modules/profile.php index 9416557..bbdd8ea 100644 --- a/modules/profile.php +++ b/modules/profile.php @@ -33,6 +33,7 @@ class ProfileModule extends PLModule 'profile/ax' => $this->make_hook('ax', AUTH_COOKIE, 'admin,edit_directory'), 'profile/edit' => $this->make_hook('p_edit', AUTH_MDP), 'profile/ajax/address' => $this->make_hook('ajax_address', AUTH_COOKIE, 'user', NO_AUTH), + 'profile/ajax/address/del' => $this->make_hook('ajax_address_del', AUTH_MDP), 'profile/ajax/tel' => $this->make_hook('ajax_tel', AUTH_COOKIE, 'user', NO_AUTH), 'profile/ajax/edu' => $this->make_hook('ajax_edu', AUTH_COOKIE, 'user', NO_AUTH), 'profile/ajax/medal' => $this->make_hook('ajax_medal', AUTH_COOKIE, 'user', NO_AUTH), @@ -355,6 +356,7 @@ class ProfileModule extends PLModule } $page->setTitle('Mon Profil'); + $page->assign('hrpid', $profile->hrid()); if (isset($success) && $success) { $page->trigSuccess('Ton profil a bien été mis à jour.'); } @@ -398,6 +400,20 @@ class ProfileModule extends PLModule $page->assign('address', array()); } + function handler_ajax_address_del($page, $hrpid) + { + if ($profile = Profile::get($hrpid)) { + if (S::user()->canEdit($profile)) { + $address = Post::t('address'); + if (is_null(AddressReq::get_request($profile->id(), 0, 0, Address::LINK_PROFILE, $address))) { + $req = new AddressReq(S::user(), $profile, $address, $profile->id(), 0, 0, Address::LINK_PROFILE); + $req->submit(); + } + } + } + exit(); + } + function handler_ajax_tel($page, $prefid, $prefname, $telid, $subField, $mainField, $mainId) { pl_content_headers("text/html"); diff --git a/modules/profile/addresses.inc.php b/modules/profile/addresses.inc.php index 2961f1e..62d21ea 100644 --- a/modules/profile/addresses.inc.php +++ b/modules/profile/addresses.inc.php @@ -48,6 +48,7 @@ class ProfileSettingAddresses implements ProfileSetting Phone::deletePhones($page->pid(), Phone::LINK_ADDRESS, null, $deletePrivate); Address::deleteAddresses($page->pid(), Address::LINK_PROFILE, null, null, $deletePrivate); Address::saveFromArray($value, $page->pid(), Address::LINK_PROFILE, null, $deletePrivate); + AddressReq::purge_requests($page->pid(), 0, 0, Address::LINK_PROFILE); if (S::user()->isMe($page->owner) && count($value) > 1) { Platal::page()->trigWarning('Attention, tu as plusieurs adresses sur ton profil. Pense à supprimer celles qui sont obsolètes.'); } @@ -68,6 +69,7 @@ class ProfilePageAddresses extends ProfilePage parent::__construct($wiz); $this->settings['addresses'] = new ProfileSettingAddresses(); $this->watched['addresses'] = true; + Platal::page()->assign('geocoding_removal', true); } } diff --git a/templates/geoloc/form.address.tpl b/templates/geoloc/form.address.tpl index 033c3c0..e419512 100644 --- a/templates/geoloc/form.address.tpl +++ b/templates/geoloc/form.address.tpl @@ -20,8 +20,12 @@ {* *} {**************************************************************************} +{if t($validation)} +
+{else} +{/if} @@ -37,15 +41,35 @@ +{if t($validation)} +
+ +
+
+{else} +{/if} {if t($address.latitude)} Position de l'adresse + {if t($geocoding_removal)}
- {icon name=cross title="Adresse mal localisée"} Signaler que le repère est mal placé + + {if !t($address.request)} + {icon name=cross title="Adresse mal localisée"} Signaler que le repère est mal placé + {else} + Localisation en attente de validation. + {/if} + + {/if} {/if} +{if t($validation)} +
+
+{else} +{/if} {* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *} diff --git a/templates/include/form.valid.address.tpl b/templates/include/form.valid.address.tpl new file mode 100644 index 0000000..9b6a696 --- /dev/null +++ b/templates/include/form.valid.address.tpl @@ -0,0 +1,28 @@ +{**************************************************************************} +{* *} +{* Copyright (C) 2003-2011 Polytechnique.org *} +{* http://opensource.polytechnique.org/ *} +{* *} +{* This program is free software; you can redistribute it and/or modify *} +{* it under the terms of the GNU General Public License as published by *} +{* the Free Software Foundation; either version 2 of the License, or *} +{* (at your option) any later version. *} +{* *} +{* This program is distributed in the hope that it will be useful, *} +{* but WITHOUT ANY WARRANTY; without even the implied warranty of *} +{* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *} +{* GNU General Public License for more details. *} +{* *} +{* You should have received a copy of the GNU General Public License *} +{* along with this program; if not, write to the Free Software *} +{* Foundation, Inc., *} +{* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *} +{* *} +{**************************************************************************} + + + Adresse fournie + {$valid->given_text} + + +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *} diff --git a/templates/include/form.valid.edit-address.tpl b/templates/include/form.valid.edit-address.tpl new file mode 100644 index 0000000..0e6abcc --- /dev/null +++ b/templates/include/form.valid.edit-address.tpl @@ -0,0 +1,25 @@ +{**************************************************************************} +{* *} +{* Copyright (C) 2003-2011 Polytechnique.org *} +{* http://opensource.polytechnique.org/ *} +{* *} +{* This program is free software; you can redistribute it and/or modify *} +{* it under the terms of the GNU General Public License as published by *} +{* the Free Software Foundation; either version 2 of the License, or *} +{* (at your option) any later version. *} +{* *} +{* This program is distributed in the hope that it will be useful, *} +{* but WITHOUT ANY WARRANTY; without even the implied warranty of *} +{* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *} +{* GNU General Public License for more details. *} +{* *} +{* You should have received a copy of the GNU General Public License *} +{* along with this program; if not, write to the Free Software *} +{* Foundation, Inc., *} +{* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *} +{* *} +{**************************************************************************} + +{include file="geoloc/form.address.tpl" prefname="valid" prefid=0 address=$valid->address validation=1} + +{* vim:set et sw=2 sts=2 sws=2 enc=utf-8: *} -- 2.1.4