array('label'=>'Identifiant','type'=>'key'), 'uid' => array('label'=>'Identifiant de l\'Entité liée','type'=>'integer'), 'scope' => array('label'=>'Périmetre de l\'entité liée','type'=>'text'), 'label' => array('label'=>'Libellé','type'=>'text'), 'type' => array('label'=>'Type','type'=>'text'), 'street' => array('label'=>'Rue','type'=>'text'), 'complement' => array('label'=>'Complément d\'adresse','type'=>'text'), 'city' => array('label'=>'Ville','type'=>'text'), 'zip' => array('label'=>'Code postal','type'=>'text'), 'country' => array('label'=>'Pays','type'=>'text'), 'state' => array('label'=>'Etat','type'=>'text') ); public $indexes = array('uid','scope'); public function mapUrl(){ $encoded = urlencode($this->street).', '.urlencode($this->zip).' '.urlencode($this->city); return 'https://www.google.com/maps/place/'.$encoded; } //Surchage de toArray pour prendre en compte le fullName régulierement utilisé en toArray public function toArray($decoded=false) { $fields = parent::toArray($decoded); $fields['fullName'] = $this->fullName(); if($decoded){ $fields['fullName'] = html_entity_decode($fields['fullName']); } return $fields; } /** * Permet de récupérer un tableau de * données liées à l'adresse via l'API Here * * Détail des paramètres possibles : https://developer.here.com/documentation/geocoder/dev_guide/topics/resource-geocode.html * Types de réponses : https://developer.here.com/documentation/geocoder/dev_guide/topics/resource-type-response-geocode.html * Voir utilisation live ici : https://developer.here.com/documentation/examples/rest/geocoder/latitude-longitude-no-attributes * * @param $responseAttributes : Définit les attributs de réponse à récupérer, séparés par virgule (ps,mq,mt,mc,pr par défaut) * Listes des possibilités: * - ps = performedSearch * - mq = matchQuality * - mt = matchType * - mc = matchCode * - pr = parsedRequest * - none = aucun attribut * * @param $locationAttributes : Définit les attributs de réponse à récupérer, séparés par virgule * Listes des possibilités: * - ar = address * - mr = mapReference * - mv = mapView * - dt = addresseDetails * - sd = streetDetails * - ad = additionalData * - ai = adminIds * - li = linkInfo * - in = adminInfo * - none = aucun attribut */ public function infos($responseAttributes='ps,mq,mt,mc,pr', $locationAttributes='ar,mr,mv,dt,sd,ad,ai,li,in', $maxResults=null){ global $myUser, $conf; if(!$myUser->connected()) throw new Exception("Vous devez être connecté",401); $results = array(); $appUrl = $conf->get('maps_api_geocode_url'); $appId = $conf->get('maps_api_id'); $appKey = $conf->get('maps_api_key'); //On ne throw pas d'exception pour ne pas bloquer l'utilisation if(empty($appUrl) || empty($appId) || empty($appKey)) { Log::put('Erreur de paramétrage des configurations de l\'API. URL Geocode: '.$appUrl.', API ID: '.$appId.', Taille clé privée API: '.strlen($appKey) ,'Location API'); return $results; } //Attributs response $responseAttr = explode(',', $responseAttributes); foreach($responseAttr as $i => $attr) { if(!in_array($attr, array('ps','mq','mt','mc','pr','none'))) { unset($responseAttr[$i]); continue; } } $responseAttributes = implode(',', $responseAttr); if(empty($responseAttributes)) $responseAttributes = 'ps,mq,mt,mc,pr'; //Attributs location $locationAttr = explode(',', $responseAttributes); foreach($locationAttr as $i => $attr) { if(!in_array($attr, array('ar','mr','mv','dt','sd','ad','ai','li','in','none'))) { unset($locationAttr[$i]); continue; } } $locationAttributes = implode(',', $locationAttr); if(empty($locationAttributes)) $locationAttributes = 'ar,mr,mv,dt,sd,ad,ai,li,in'; $params = array( 'searchtext' => $this->street.(!empty($this->complement)?$this->complement:'').', '.$this->zip.' '.$this->city, 'app_id' => $appId, 'app_code' => $appKey, 'responseattributes' => $responseAttributes, 'locationattributes' => $locationAttributes, ); if(isset($maxResults) && is_numeric($maxResults)) $params['maxresults'] = $maxResults; $curlOpt = array( CURLOPT_URL => sprintf("%s?%s", $appUrl, http_build_query($params)), CURLOPT_HTTPHEADER => array( 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:55.0) Gecko/20100101 Firefox/55.0', 'Content-Type: application/json', ), CURLOPT_RETURNTRANSFER => 1, CURLOPT_HTTPAUTH => CURLAUTH_ANY, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, ); $ch = curl_init(); curl_setopt_array($ch, $curlOpt); $response = curl_exec($ch); if($response === false){ Log::put("Erreur de récupération cURL : ".curl_error($ch),'Location API'); return $results; } $results = json_decode($response); //Check si le retour n'est pas une erreur if(!isset($results->Response)){ Log::put(mb_strtoupper('['.$results->type.']').' '.$results->subtype.': '.$results->Details,'Location API'); return array(); } //Contrôle sur la structure de l'objet de retour if(!isset($results->Response->View)){ Log::put("La structure de retour de l'API Here a été modifiée. Se référer à la documentation pour modifier la structure en conséquence",'Location API'); return array(); } if(empty($results->Response->View)){ Log::put("Aucun résultat trouvé pour la récupération des infos de l'adresse : ".$this->toText(),'Location API'); $results = $results->Response->View; return $results; } if(!isset($results->Response->View[0]->Result)){ Log::put("La structure de retour de l'API Here a été modifiée. Se référer à la documentation pour modifier la structure en conséquence",'Location API'); return array(); } Log::put("Récupération des informations de l'adresse : ".$this->toText(),'Location API'); return $results->Response->View[0]->Result; // $infos = curl_getinfo($ch); // curl_close($ch); } //Permet de récupérer les coordonnées géographiques //d'une adresse en fonction de son libellé public function locationCoordinates(){ //Récupération des informations en scopant sur Lat. + Long. $infos = $this->infos('none', 'none', 1); $coordinates = array( 'latitude' => 0, 'longitude' => 0, ); if(empty($infos) || !isset($infos[0]->Location->DisplayPosition)) return $coordinates; $coordinates['latitude'] = $infos[0]->Location->DisplayPosition->Latitude; $coordinates['longitude'] = $infos[0]->Location->DisplayPosition->Longitude; return $coordinates; } //Retourne l'adresse sur une seule ligne //au format : street, complement, zip city country public function fullName(){ $fullname = ''; if(!empty($this->street)) $fullname .= $this->street; if(!empty($this->complement)) $fullname .= ', '.$this->complement; if($fullname!='') $fullname .= ', '; if(!empty($this->zip)) $fullname .= $this->zip; if(!empty($this->city)) $fullname .= ' '.$this->city; if(!empty($this->country)) $fullname .= ', '.$this->country; return $fullname; } //remplis un composant location à partir des infos de la classe courante public function toDataAttributes($plainText=true){ $array = array(); $plain = ''; foreach (array('street','complement','city','zip','country') as $key) { $array[$key] = $this->$key; $plain .= ' data-'.$key.' = "'.(empty($this->$key) ? '' : $this->$key).'"'; } return !$plainText ? $array : $plain; } public function getCoordinates(){ return self::coordinates($this->fullName()); } //Récupere des latitudes/ longitudes à partir d'une adresse public static function coordinates($address){ $response = file_get_contents('https://api-adresse.data.gouv.fr/search/?q='.urlencode($address)); $response = json_decode($response,true); if(!$response) $response = array(); if(isset($response['features']) && isset($response['features'][0]) && isset($response['features'][0]['geometry']) && isset($response['features'][0]['geometry']['coordinates'])) return array('latitude'=>$response['features'][0]['geometry']['coordinates'][0],'longitude'=>$response['features'][0]['geometry']['coordinates'][1]); } public static function types($key=null){ $types = array( self::MAIN => array( 'label' => "Adresse générale", 'icon' => "fas fa-map-marker-alt", 'color' => "#4dabf7", ), self::INVOICE => array( 'label' => "Adresse de facturation", 'icon' => "fas fa-receipt", 'color' => "#4dabf7", ), self::SHIPPING => array( 'label' => "Adresse de livraison", 'icon' => "fas fa-shipping-fast", 'color' => "#4dabf7", ) ); Plugin::callHook('address_types', array(&$types)); if(!isset($key)) return $types; return isset($types[$key]) ? $types[$key] : array('label'=>'non définit','icon'=>'','color'=>''); } } ?>