Construire votre startup avec PHP Géolocalisation et Google Places

Ce que vous allez créer

Ceci est la troisième partie de la série Construire son démarrage avec PHP sur Tuts +. Dans cette série, je vous guide dans le lancement d'une startup du concept à la réalité en utilisant mon application Meeting Planner comme exemple concret. À chaque étape du processus, nous publierons le code de Meeting Planner sous forme d’exemples open source à partir desquels vous pourrez apprendre..

Dans cette partie, nous allons construire une partie de l’infrastructure sous-jacente pour le concept d’endroits où les gens peuvent planifier des réunions. Nous aborderons les bases de l'utilisation de Lieux, en nous basant sur notre schéma de base de données et en intégrant une API de géolocalisation HTML5 à Google Maps et Google Places. L'idée est d'utiliser ces fonctionnalités pour faciliter le choix du lieu de vos réunions. Nous ne pouvons pas couvrir tous les ajustements et finir dans cet épisode, mais nous en couvrirons plus dans un prochain tutoriel.

Tout le code de Meeting Planner est écrit dans le framework Yii2 pour PHP et exploite Bootstrap et JavaScript. Si vous souhaitez en savoir plus sur Yii2, consultez notre série parallèle Programmer avec Yii2 chez Tuts+.

Juste un rappel, je participe aux commentaires ci-dessous. Je suis particulièrement intéressé si vous avez des approches différentes ou des idées supplémentaires, ou si vous souhaitez suggérer des sujets pour de futurs tutoriels. Les demandes de fonctionnalités pour Meeting Planner sont également les bienvenues.

Construire la fonctionnalité des lieux

Avant de pouvoir planifier des réunions, les utilisateurs doivent pouvoir trouver et suggérer leurs lieux préférés. Dans un premier temps, pour plus de simplicité, nous allons créer la fonctionnalité de recherche et de création Place séparément de la fonctionnalité de planification..

Les utilisateurs peuvent ajouter des lieux de trois manières:

  1. À l'aide de la géolocalisation HTML5, ils peuvent rechercher leur position actuelle via WiFi et l'ajouter comme lieu..
  2. À l'aide de l'API Google Places, ils peuvent rechercher un lieu dans la base de données Places à l'aide de la fonction de saisie semi-automatique. Lorsque nous connaissons leur emplacement actuel, nous pouvons éventuellement limiter les résultats de la recherche aux lieux proches..
  3. Saisie manuelle. Les utilisateurs peuvent entrer une adresse et une description pour leur propre lieu, comme un bureau ou une maison..

Extension du schéma de lieu

Voici le schéma pour les lieux que nous avons développé dans la deuxième partie:

$ tableOptions = null; if ($ this-> db-> driverName === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> createTable ('% place', ['id' => Schema :: TYPE_PK, 'name' => Schema :: TYPE_STRING. 'NOT NULL', 'place_type' => Schema :: TYPE_SMALLINT. 'NOT NULL DEFAULT 0', 'status' => Schéma :: TYPE_SMALLINT. 'NON NULL DEFAULT 0', 'google_place_id' => Schema :: TYPE_STRING. 'NOT NULL', // par exemple, google places id 'created_by' => Schéma :: TYPE_BIGINT. 'NOT NULL', 'created_at' => Schéma :: TYPE_INTEGER. 'NOT NULL', 'updated_at' => Schéma :: TYPE_INTEGER. 'NOT NULL', $, OptionsTable table); $ this-> addForeignKey ('fk_place_created_by', '% place', 'created_by', '% user', 'id', 'CASCADE', 'CASCADE');

Notez qu'il n'y a pas de géolocalisation associée à un lieu dans cette table. En effet, le moteur MySQL InnoDB ne prend pas en charge les index spatiaux. J'ai donc créé une table secondaire à l'aide de la table MyISAM pour les coordonnées de géolocalisation de Places. C'est le Lieu_GPS table:

la classe m141025_213611_create_place_gps_table étend la migration fonction publique up () $ tableOptions = null; if ($ this-> db-> driverName === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = MyISAM';  $ this-> createTable ('% place_gps', ['id' => Schema :: TYPE_PK, 'place_id' => Schema :: TYPE_INTEGER. 'NOT NULL', 'gps' => 'POINT NOT NULL ',], $ tableOptions); $ this-> execute ('crée un index spatial place_gps_gps sur'. '' % place_gps (gps); '); $ this-> addForeignKey ('fk_place_gps', '% place_gps', 'place_id', '% place', 'id', 'CASCADE', 'CASCADE'); 

Comme je suis en mode de prototypage rapide, je vais étendre le schéma en utilisant les migrations de Yii et je pourrais éventuellement faire d'autres ajustements..

Pour étendre le schéma, nous créons une nouvelle migration dans Yii:

./ yii migrate / create extend_place_table

Et fournissez le code suivant:

db-> nomDuPort === 'mysql') $ tableOptions = 'CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB';  $ this-> addColumn ('% place', 'slug', 'chaîne NOT NULL'); $ this-> addColumn ('% place', 'site web', 'chaîne NOT NULL'); $ this-> addColumn ('% place', 'full_address', 'string NOT NULL'); $ this-> addColumn ('% place', 'environs', 'chaîne NOT NULL'); $ this-> addColumn ('% place', 'notes', 'text');  public function down () $ this-> dropColumn ('% place', 'slug'); $ this-> dropColumn ('% place', 'site web'); $ this-> dropColumn ('% place', 'full_address'); $ this-> dropColumn ('% place', 'voisinage'); $ this-> dropColumn ('% place', 'notes');  

Cela ajoutera des colonnes pour slug, website, full_address, voisinage et notes. Le slug est une adresse conviviale pour les URL permettant d'afficher la page d'affichage de la place que Yii peut générer automatiquement pour nous. Les autres champs seront parfois mis à jour par les utilisateurs et d'autres fois renseignés à partir de l'API Google Adresses..

Pour exécuter la migration, entrez ce qui suit:

./ yii migrer / up

Vous devriez voir ce qui suit:

Outil de migration Yii (basé sur Yii v2.0.0) Total 1 nouvelle migration à appliquer: m150114_202542_extend_place_table Appliquer la migration ci-dessus? (yes | no) [no]: yes *** application de m150114_202542_extend_place_table> ajouter une chaîne de slug de chaîne NON NULL à la table % place… done (heure: 0.011s)> ajouter une chaîne de site Web de colonne NOT NULL à la table % place… done (heure: 0.010s)> ajoute une chaîne adresse_chaîne chaîne NOT NULL à la table % place… fait (heure: 0.010s)> ajoute une chaîne de voisinage de colonne NON NULL à la table % place… done (heure: 0.011s)> ajouter du texte de notes de colonne au tableau % place… done (heure: 0.011s) *** appliqué m150114_202542_extend_place_table (heure: 0.055s) Migration réussie. 

Mise à jour du code CRUD

Si vous visitez la page Lieux, par exemple http: // localhost: 8888 / mp / index.php / place / create, vous verrez le formulaire Yii2 généré automatiquement par défaut avec tous nos champs de schéma:

Pour ce tutoriel, j'ai relancé le générateur de code de Yii, Gii, en utilisant les étapes de la deuxième partie pour générer le code du nouveau schéma de base de données. J'ai demandé à Gii de remplacer le code CRUD de plus tôt. 

Remarque: Il peut être plus facile pour vous de remplacer votre exemple de source de la deuxième partie par un exemple de source de cette partie. Voir le lien Github en haut à droite.

Vous devrez également mettre à jour nos bibliothèques de fournisseurs avec composer pour intégrer la prise en charge des bibliothèques Google Maps et Places de 2amigOS Yii2. Voici une partie de notre fichier composer.json:

 "minimum-stabilité": "stable", "require": "php": "> = 5.4.0", "yiisoft / yii2": "*", "yiisoft / yii2-bootstrap": "* *", " yiisoft / yii2-swiftmailer ":" * "," 2 amigos/yii2-google-maps-library ":" * "," 2 amigos/yii2-google-places-library ":" * " 

Ensuite, lancez composer update pour télécharger les fichiers:

mise à jour sudo composer

Trois façons différentes d'ajouter des lieux

En fait, nous allons créer trois actions et formulaires de contrôleur différents pour chacun de ces types d'emplacements. N'oubliez pas que nous devons également intégrer le modèle associé, LieuGPS, pour stocker les coordonnées GPS de chaque lieu, peu importe la façon dont l'utilisateur l'ajoute.

Ajouter des lieux à la barre de navigation

Pour ajouter un lien Lieux à la barre de navigation, modifiez /views/layouts/main.php. Il s'agit de la mise en page par défaut avec laquelle Yii encapsule tous nos fichiers de vue. Il comprend l'en-tête, la barre de navigation Bootstrap et le pied de page..

Ci-dessous dans $ menuItems, J'ajoute une entrée de tableau pour le menu Place:

 NavBar :: begin (['brandLabel' => 'MeetingPlanner.io', // 'brandUrl' => Yii :: $ app-> homeUrl, 'options' => ['class' => 'navbar-inverse navbar- à toit fixe ',],]); $ menuItems = [['label' => 'Accueil', 'url' => ['/ site / index']], ['label' => 'Lieux', 'url' => ['/ lieu'] ], ['label' => 'À propos', 'url' => ['/ site / sur']], ['label' => 'Contact', 'url' => ['/ site / contact'] ],]; if (Yii :: $ app-> user-> isGuest) $ menuItems [] = ['label' => 'Signup', 'url' => ['/ site / signup']]; $ menuItems [] = ['label' => 'Login', 'url' => ['/ site / login']];  else $ menuItems [] = ['label' => 'Déconnexion ('. Yii :: $ app-> utilisateur-> identité-> nom d'utilisateur. ')', 'url' => ['/ site / logout' ], 'linkOptions' => ['data-method' => 'post']];  echo Nav :: widget (['options' => ['class' => 'navbar-nav navbar-right'], 'items' => $ menuItems,]); NavBar :: end (); ?> 

La vue d'index de lieu

La vue Index des lieux ressemblera à ceci après l'ajout des boutons pour les trois façons d'ajouter des lieux:

Dans /views/place/index.php, on peut ajouter les trois ajouter un lieu boutons:

 

'btn btn-success'])?> 'btn btn-success'])?> 'btn btn-success'])?>

Nous pouvons également personnaliser les colonnes qui apparaissent dans la vue, notamment en créant une colonne personnalisée pour une méthode Place qui affiche le nom convivial du type de lieu:

 $ dataProvider, 'filterModel' => $ searchModel, 'columns' => [['class' => 'yii \ grid \ SerialColumn'], 'name', ['attribut' => 'type_emplacement', 'format' = > 'raw', 'value' => function ($ model) return '
'. $ model-> getPlaceType ($ model-> lieu_type).'
'; ,], ['class' => 'yii \ grid \ ActionColumn'],],]); ?>

Voici un sous-ensemble des méthodes de type de lieu dans /models/Place.php:

 const TYPE_OTHER = 0; const TYPE_RESTAURANT = 10; const TYPE_COFFEESHOP = 20; const TYPE_RESIDENCE = 30; const TYPE_OFFICE = 40; const TYPE_BAR = 50;… fonction publique getPlaceType ($ data) $ options = $ this-> getPlaceTypeOptions (); retourne $ options [$ data];  function publique getPlaceTypeOptions () return array (self :: TYPE_RESTAURANT => 'Restaurant', self :: TYPE_COFFEESHOP => 'Coffeeshop', self :: TYPE_RESIDENCE => 'Residence', self :: TYPE_OFFICE => 'Bureau', self :: TYPE_BAR => 'Bar', self :: TYPE_OTHER => 'Autre');  

Notez que nous n'avons pas encore abordé l'état de connexion ou la propriété des lieux par l'utilisateur. Nous y reviendrons dans le prochain tutoriel. En raison de la complexité et de la portée de cette étape, nous laisserons quelques éléments de finition pour un tutoriel ultérieur..

Ajout de lieux avec la géolocalisation HTML5

Un scénario pour ajouter des lieux consiste à créer un lieu pour votre maison ou votre bureau. Plutôt que de demander aux utilisateurs de saisir manuellement ces informations, nous pouvons souvent les générer automatiquement avec HTML5. Géolocalisation.

La géolocalisation HTML5 utilise votre adresse WiFi pour déterminer les points GPS de votre position actuelle. Cela ne fonctionne pas avec les connexions cellulaires / mobiles et ce n'est pas infaillible. 

L'utilisateur devra probablement accorder à son navigateur l'autorisation de géolocalisation pour que cette fonctionnalité fonctionne. Recherchez une fenêtre contextuelle sous la barre d'adresse, comme indiqué ci-dessous:

J'utilise le script de géosition d'estebanav pour prendre en charge la géolocalisation HTML5 avec la plus grande compatibilité de navigateur possible..

Ajout de l'action de contrôleur de lieu pour la géolocalisation

Dans frontend / controllers / PlaceController.php, nous allons créer une nouvelle méthode pour le Create_geo action:

 / ** * Crée un nouveau modèle de lieu via la géolocalisation * / fonction publique actionCreate_geo () $ model = new Place (); if ($ model-> load (Yii :: $ app-> request-> post ())) … à expliquer ci-dessous… else return $ this-> render ('create_geo', ['modèle' => $ modèle,]); 

Parce que le formulaire n’a pas encore été soumis, Yii rendra la create_geo voir pour afficher le formulaire.

Dans frontend / views / place / create_geo.php, nous allons inclure _formGeolocate.php:

title = 'Créer un lieu par géolocalisation'; $ this-> params ['breadcrumbs'] [] = ['label' => 'Lieux', 'url' => ['index']]; $ this-> params ['breadcrumbs'] [] = $ this-> title; ?> 

titre)?>

render ('_ formGeolocate', ['model' => $ model,])?>

Regardons la première partie de _formGeolocate. Nous devons inclure le code JavaScript pour Geoposition.js ainsi que notre propre code de géolocalisation personnalisé afin d’intégrer la géolocalisation à notre formulaire. La façon dont Yii fait cela est avec Asset Bundles. Vous définissez un ensemble d'actifs pour différentes pages, ce qui vous permet d'optimiser les fichiers JS et CSS chargés dans différentes zones de votre application. Nous allons créer LocaliserAsset premier:

?php utilise yii \ helpers \ Html; utilisez yii \ helpers \ BaseHtml; utilisez yii \ widgets \ ActiveForm; utilisez frontend \ assets \ LocateAsset; LocateAsset :: register ($ this); 

Dans frontend / assets / LocateAsset.php, nous allons définir le JavaScript que nous devons inclure:

LocaliserAsset précharge l'API Google Maps, le géoPosition bibliothèque et notre code personnalisé Locate.js qui est affiché ci-dessous:

function beginSearch () $ ('# preSearch'). hide (); $ ('# searchArea'). removeClass ('hidden'); // if (navigator.geolocation) // navigator. if (geoPosition.init ()) geoPosition.getCurrentPosition (success, errorHandler, timeout: 5000);  else error ('Désolé, nous ne pouvons pas utiliser la géolocalisation du navigateur pour vous trouver.');  function success (position) $ ('# actionBar'). removeClass ('hidden'); $ ('# autolocateAlert'). addClass ('hidden'); var s = document.querySelector ('# status'); // var buttons = document.querySelector ('# local_actions'); if (s.className == 'success') // ne sachant pas pourquoi nous frappons cela deux fois en FF, je pense que cela a à voir avec un résultat mis en cache qui revient, return;  s.innerHTML = "Vous êtes ici:"; s.className = 'success'; var mapcanvas = document.createElement ('div'); mapcanvas.id = 'mapcanvas'; mapcanvas.style.height = '300px'; mapcanvas.style.width = '300px'; mapcanvas.style.border = '1px noir solide'; document.querySelector ('article'). appendChild (mapcanvas); var latlng = new google.maps.LatLng (position.coords.latitude, position.coords.longitude); var myOptions = zoom: 16, center: latlng, mapTypeControl: false, navigationControlOptions: style: google.maps.NavigationControlStyle.SMALL, mapTypeId: google.maps.MapTypeId.ROADMAP; var map = new google.maps.Map (document.getElementById ("mapcanvas"), myOptions); var marker = new google.maps.Marker (position: latlng, map: map, title: "Vous êtes ici! (au moins dans un" + position.coords.accuracy + "rayon de mètre)"); $ ('# Locate_actionbar'). removeClass ('hidden'); $ ('# place-lat'). val (position.coords.latitude); $ ('# place-lng'). val (position.coords.longitude);  function errorHandler (err) var s = document.querySelector ('# status'); s.innerHTML = typeof msg == 'chaîne'? msg: "échec"; s.className = 'fail'; // if (err.code == 1)  // l'utilisateur a dit non! document.location.href = '/ place / index? errorLocate';  

Fondamentalement, la géolocalisation est initiée lorsque l'utilisateur déclenche beginSearch. Le code Geoposition appelle la fonction success quand il retourne avec la localisation de l'utilisateur. Nous personnalisons la fonction de réussite pour afficher une carte à l'emplacement et renseigner nos champs de formulaire masqués avec la latitude et la longitude renvoyées. Lorsque l'utilisateur publie le formulaire, les coordonnées de localisation seront disponibles sur notre application Web.. 

Voici le code dans Succès() qui remplit les champs de formulaire avec les coordonnées d'emplacement:

$ ('# place-lat'). val (position.coords.latitude); $ ('# place-lng'). val (position.coords.longitude);

Le reste de _formGeolocate.php est divisé en deux moitiés égales. Sur le côté gauche, nous fournissons les champs de formulaire que l'utilisateur peut entrer avec les données de géolocalisation et les champs masqués nécessaires à la prise en charge de JavaScript. Sur le côté droit, nous laissons un espace pour qu'un bouton déclenche la géolocalisation et affiche la carte. le Succès() la fonction remplit le

tag avec la carte.

champ ($ model, 'name') -> textInput (['maxlength' => 255])?> champ ($ model, 'website') -> textInput (['maxlength' => 255])?> field ($ model, 'place_type') -> dropDownList ($ model-> getPlaceTypeOptions (), ['prompt' => 'Quel type de lieu est-ce?']) -> label ('Type de lieu')?>> champ ($ modèle, 'notes') -> textArea ()?>
isNewRecord? 'Create': 'Update', ['class' => $ model-> isNewRecord? 'btn btn-success': 'btn btn-primary'])?>


'btn btn-success', 'onclick' => "javascript: beginSearch (); return false;"])?>

Recherche de votre position actuelle…

Voici à quoi ressemble le formulaire initialement:

Clique sur le Lieu de recherche bouton pour initier la géolocalisation. Encore une fois, recherchez une demande de permission dans la barre de navigation du navigateur..

Une fois votre position trouvée, nous vous indiquerons votre position sur une carte:

Remarque: j'ai réglé le délai de géolocalisation à cinq secondes, mais vous devrez parfois recharger la page pour obtenir la réponse correcte après avoir accordé l'autorisation. Certains emplacements WiFi sont moins déterminés que d'autres.

Jetons un coup d'œil au code de soumission du formulaire Meeting Controller:

 fonction publique actionCreate_geo () $ model = new Place (); if ($ model-> load (Yii :: $ app-> request-> post ())) if (Yii :: $ app-> user-> getIsGuest ()) $ model-> created_by = 1;  else $ model-> created_by = Yii :: $ app-> user-> getId ();  $ form = Yii :: $ app-> request-> post (); $ model-> save (); // ajoute une entrée GPS dans PlaceGeometry $ model-> addGeometryByPoint ($ model, $ form ['Place'] ['lat'], $ form ['Place'] ['lng']); return $ this-> redirect (['view', 'id' => $ model-> id]); 

Pour le moment, nous ne faisons que mettre un espace réservé pour l'utilisateur created_by et laisser la gestion des erreurs pour plus tard (désolés puristes, ce n'est pas le propos de ce tutoriel pour le moment).

Lorsque le formulaire est créé et qu'un lieu est créé, nous prenons le point de géolocalisation du formulaire (ces champs cachés renseignés par le script Locate.js) et ajoutons une ligne à la table des lieux associée. LieuGPS

Comme je l'ai mentionné dans la deuxième partie, nous séparons les données de géolocalisation dans une table différente car le moteur MySQL InnoDB ne prend pas en charge les index spatiaux. Cela améliorera également les performances des requêtes pour trouver les lieux de réunion les plus proches entre deux utilisateurs.. 

Ici se trouve le addGeometryByPoint méthode dans le modèle Place.php:

 fonction publique addGeometryByPoint ($ model, $ lat, $ lon) $ pg = new PlaceGPS; $ pg-> place_id = $ model-> id; $ pg-> gps = new \ yii \ db \ Expression ("GeomFromText ('Point (". $ lat. "".. lon. ")')"); $ pg-> save (); 

Voici à quoi devrait ressembler la page d'index d'emplacement après l'enregistrement de l'enregistrement:

Si vous souhaitez voir une autre implémentation de la géolocalisation HTML5 pour Yii 1.x, consultez Comment utiliser les cartes de quartier de Zillow et la géolocalisation HTML5..

Affichage de lieux sur Google Maps

Si vous cliquez sur l'icône de commande d'affichage associée à notre nouvel emplacement dans la vue d'index ci-dessus, vous verrez ceci:

Nous avons personnalisé la page d'affichage générée par Gii et ajouté du code pour dessiner Google Map à l'aide de l'extension Yii2 Google Maps..

Ici se trouve le Vue action dans PlaceController.php:

 / ** * Affiche un modèle de lieu unique. * @param entier $ id * @retour mixte * / fonction publique actionView ($ id) $ model = $ this-> findModel ($ id); $ gps = $ model-> getLocation ($ id); return $ this-> render ('view', ['model' => $ model, 'gps' => $ gps,]);  

Ici se trouve le getLocation méthode dans le modèle Place.php. Il récupère les coordonnées de localisation de la LieuGPS table:

fonction publique getLocation ($ place_id) $ sql = 'Sélectionnez AsText (gps) en tant que gps à partir de % place_gps où place_id ='. $ place_id; $ model = PlaceGPS :: findBySql ($ sql) -> one (); $ gps = new \ stdClass; if (is_null ($ model)) return false;  else list ($ gps-> lat, $ gps-> lng) = $ this-> string_to_lat_lon ($ model-> gps);  return $ gps; 

Voici une partie du fichier view qui rend la page. Le côté gauche consiste en un Yii2 standard Vue détaillée widget pour l'instant. Le côté droit génère le code qui dessine la carte:

$ modèle, 'attributs' => ['nom', 'type_emplacement', 'site web', 'adresse complète',],])?>
$ gps-> lat, 'lng' => $ gps-> lng]); $ map = new Map (['center' => $ coord, 'zoom' => 14, 'width' => 300, 'height' => 300,]); $ marker = new Marker (['position' => $ coord, 'title' => $ model-> nom,]); // Ajouter un marqueur à la carte $ map-> addOverlay ($ marker); echo $ map-> display (); else echo 'Aucune coordonnée de localisation pour cet endroit n'a été trouvée.'; ?>

Ajout à partir de l'API Google Adresses

La fonctionnalité de saisie semi-automatique de Google Adresses est un moyen extrêmement rapide et simple pour les utilisateurs d'ajouter des lieux de réunion. J'utilise l'extension Yii2 Google Places de 2amigOS.

Dans PlaceController.php, nous ajouterons une action pour Create_place_google:

/ ** * Crée un nouveau modèle de lieu à partir de Google Place * Si la création est réussie, le navigateur sera redirigé vers la page "Afficher". * @return mixed * / public function actionCreate_place_google () $ model = new Place (); if ($ model-> load (Yii :: $ app-> request-> post ())) … à expliquer plus en détail ci-dessous… else return $ this-> render ('create_place_google', ['model' = > $ model,]);  

le /frontend/views/place/create_place_google.php Le fichier affichera le formulaire et initialisera le JavaScript nécessaire pour prendre en charge la saisie semi-automatique:

titre)?>

render ('_ formPlaceGoogle', ['model' => $ model,])?>
'lieux', 'sensor' => 'false',)); echo $ this-> registerJsFile ($ gpJsLink); $ options = '"types": ["établissement"], "composantRestrictions": "pays": "us"'; echo $ this-> registerJs ("(function () var input = document.getElementById ('lieu-searchbox'); var options = $ options; searchbox = new google.maps.places.Autocomplete (entrée, options); setupListeners ();) (); ", \ yii \ web \ View :: POS_END); // 'setupBounds ('. $ bound_bl. ','. $ bound_tr. '); ?>

La développeur Petra Barus a fourni une extension Google Places pour Yii1.x. Pour ce tutoriel, j'ai codé à la main le support de base pour Yii2. Cependant, Barus a eu la gentillesse de publier une extension Yii2 quelques jours après. Je n'ai pas encore intégré son code. Voici sa dernière extension Yii2 Google Places Autocomplete.

Ici se trouve le MapAsset bundle que je crée pour le JavaScript associé qui sera nécessaire:

Ici se trouve le _formPlaceGoogle.php code de formulaire:

 

Saisissez un lieu ou une entreprise connu de Google Adresses:

champ ($ model, 'searchbox') -> textInput (['maxlength' => 255]) -> label ('Place')?> field ($ model, 'place_type') -> dropDownList ($ model-> getPlaceTypeOptions (), ['prompt' => 'Quel type de lieu est-ce?']) -> label ('Type de lieu')?>>
isNewRecord? 'Create': 'Update', ['class' => $ model-> isNewRecord? 'btn btn-success': 'btn btn-primary'])?>

Il y a un Barre de recherche champ qui acceptera l'entrée d'auto-complétion de l'utilisateur. Il existe également une variété de champs cachés que notre JavaScript chargera avec les résultats du service Google Adresses..

Voici le create_place.js qui accomplit toute la "magie":

function setupListeners () // google.maps.event.addDomListener (fenêtre, 'charger', initialiser); // searchbox est la var de l'objet google places créé sur la page google.maps.event.addListener (searchbox, 'lieu_changed', function () var place = searchbox.getPlace (); if (! place.geometry)  // Informe l'utilisateur qu'un lieu n'a pas été trouvé et renvoie. Return; else // migre les données JSON de Google vers les champs de formulaire masqués populateResult (place););  function populateResult (place) // déplace les données JSON extraites de Google vers des champs de formulaire masqués // afin que Yii2 puisse publier les données $ ('# place-location'). val (JSON.stringify (place ['geometry'] [ 'emplacement'])); $ ('# place-google_place_id'). val (place ['place_id']); $ ('# place-full_address'). val (place ['formatted_address']); $ ('# place-website'). val (place ['site web']); $ ('# lieu-voisinage'). val (lieu ['voisinage']); $ ('# lieu-nom'). val (lieu ['nom']); loadMap (lieu ['géométrie'] ['emplacement'], lieu ['nom']);  function loadMap (gps, name) var mapcanvas = document.createElement ('div'); mapcanvas.id = 'mapcanvas'; mapcanvas.style.height = '300px'; mapcanvas.style.width = '300px'; mapcanvas.style.border = '1px noir solide'; document.querySelector ('article'). appendChild (mapcanvas); var latlng = new google.maps.LatLng (gps ['k'], gps ['D']); var myOptions = zoom: 16, center: latlng, mapTypeControl: false, navigationControlOptions: style: google.maps.NavigationControlStyle.SMALL, mapTypeId: google.maps.MapTypeId.ROADMAP; var map = new google.maps.Map (document.getElementById ("mapcanvas"), myOptions); var marker = new google.maps.Marker (position: latlng, map: map, title: name); 

le setupListeners () la méthode lie notre Barre de recherche champ au service de saisie semi-automatique de Google Adresses. Lorsqu'un lieu_changé événement se produit, populateResult () est appelé pour remplir les champs cachés du formulaire avec les données de Google et charger la carte qui s'affiche dans la moitié droite du formulaire.

Vous pouvez utiliser le débogueur de navigateur pour inspecter les champs masqués une fois qu’ils ont été renseignés avec des données de formulaire via JavaScript. Ces données seront affichées avec le formulaire lors de la soumission afin que nous puissions les ajouter à la base de données Lieu..

Voici le dernier élément de PlaceController Create_place_google enregistrer l'action:

 fonction publique actionCreate_place_google () $ model = new Place (); if ($ model-> load (Yii :: $ app-> request-> post ())) if (Yii :: $ app-> user-> getIsGuest ()) $ model-> created_by = 1;  else $ model-> created_by = Yii :: $ app-> user-> getId ();  $ form = Yii :: $ app-> request-> post (); $ model-> save (); // ajouter une entrée GPS dans PlaceGeometry $ model-> addGeometry ($ model, $ form ['Place'] ['location']); return $ this-> redirect (['view', 'id' => $ model-> id]); 

C'est assez semblable au Create_geo action. Nous avons une méthode de modèle Place.php distincte pour simplifier la collecte de données de localisation. Voici addGeometry ():

fonction publique addGeometry ($ model, $ location) $ x = json_decode ($ location, true); réinitialiser ($ x); $ lat = actuel ($ x); $ lon = next ($ x); $ pg = new Pla