Mapbox element

This commit is contained in:
Tony Air 2019-12-09 17:47:17 +07:00
parent 38fa5716ba
commit a63e36c6f9
8 changed files with 306 additions and 0 deletions

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "app/thirdparty/geocoding-example"]
path = app/thirdparty/geocoding-example
url = https://github.com/mapbox/geocoding-example.git

View File

@ -0,0 +1,23 @@
<?php
namespace Site\Controllers;
use DNADesign\Elemental\Controllers\ElementController;
use Site\Templates\DeferedRequirements;
class MapElementController extends ElementController
{
public function init()
{
parent::init();
DeferedRequirements::Auto();
DeferedRequirements::loadCSS('https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.css');
DeferedRequirements::loadJS('https://api.tiles.mapbox.com/mapbox-gl-js/v0.48.0/mapbox-gl.js');
DeferedRequirements::loadCSS('app_Site.Controllers.MapElementController.css');
DeferedRequirements::loadJS('app_Site.Controllers.MapElementController.js');
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* Created by PhpStorm.
* User: tony
* Date: 6/30/18
* Time: 11:54 PM
*/
namespace Site\Elements;
use A2nt\SilverStripeMapboxField\MapboxField;
use DNADesign\Elemental\Models\ElementContent;
use Site\Controllers\MapElementController;
use Site\Extensions\MapExtension;
class MapElement extends ElementContent
{
private static $icon = 'font-icon-globe-1';
private static $singular_name = 'Map Element';
private static $plural_name = 'Map Element';
private static $description = 'Displays dynamic map';
private static $table_name = 'MapElement';
private static $controller_class = MapElementController::class;
private static $extensions = [
MapExtension::class,
];
public function getType()
{
return self::$singular_name;
}
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->removeByName('Locations');
return $fields;
}
public function MapAPIKey()
{
return MapboxField::getAccessToken();
}
}

View File

@ -0,0 +1,61 @@
<?php
/**
* Created by PhpStorm.
* User: tony
* Date: 8/26/18
* Time: 12:55 PM
*/
namespace Site\Extensions;
use SilverStripe\Core\Extension;
use SilverStripe\Forms\CompositeField;
use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\GridField\GridField;
use SilverStripe\Forms\GridField\GridFieldConfig_RelationEditor;
use SilverStripe\Forms\NumericField;
use SilverStripe\ORM\DataExtension;
use Site\Models\MapPin;
class MapExtension extends DataExtension
{
private static $db = [
'MapZoom' => 'Int',
];
private static $many_many = [
'Locations' => MapPin::class,
];
private static $owns = [
'Locations',
];
public function updateCMSFields(FieldList $fields)
{
parent::updateCMSFields($fields);
$fields->addFieldsToTab('Root.Map', [
NumericField::create('MapZoom', 'Initial Map Zoom (enter a number from 0 to 24)'),
GridField::create(
'Locations',
'Locations',
$this->owner->Locations(),
GridFieldConfig_RelationEditor::create(100)
)
]);
}
public function getGeoJSON(): string
{
$pins = [];
foreach ($this->owner->Locations() as $off) {
$pins[] = $off->getGeo();
}
return json_encode([
'type' => 'MarkerCollection',
'features' => $pins
]);
}
}

117
app/src/Models/MapPin.php Normal file
View File

@ -0,0 +1,117 @@
<?php
/**
* Created by PhpStorm.
* User: tony
* Date: 9/12/18
* Time: 2:55 AM
*/
namespace Site\Models;
use A2nt\SilverStripeMapboxField\MapboxField;
use A2nt\SilverStripeMapboxField\MarkerExtension;
use Sheadawson\Linkable\Forms\LinkField;
use Sheadawson\Linkable\Models\Link;
use SilverStripe\ORM\DataObject;
use SilverStripe\Versioned\Versioned;
use Site\Elements\MapElement;
use Symbiote\Addressable\Addressable;
class MapPin extends DataObject
{
private static $table_name = 'MapPin';
private static $db = [
'Title' => 'Varchar(255)',
];
private static $has_one = [
'PhoneNumber' => Link::class,
'Fax' => Link::class,
];
private static $extensions = [
Addressable::class,
MarkerExtension::class,
Versioned::class,
];
private static $belongs_many_many = [
'MapElements' => MapElement::class,
];
private static $default_sort = 'Title ASC, ID DESC';
public function getCMSFields()
{
$fields = parent::getCMSFields();
$fields->replaceField(
'PhoneNumberID',
LinkField::create('PhoneNumberID', 'Phone Number')
->setAllowedTypes(['Phone'])
);
$fields->replaceField(
'FaxID',
LinkField::create('FaxID', 'FAX')
->setAllowedTypes(['Phone'])
);
$fields->addFieldsToTab('Root.Map', [
MapboxField::create('Map', 'Choose a location', 'Lat', 'Lng'),
]);
return $fields;
}
public function onBeforeWrite()
{
parent::onBeforeWrite();
$lng = $this->getField('Lng');
$lat = $this->getField('Lat');
// geocode
try {
// reverse geocoding get address
if (!$this->hasAddress() && $lng && $lat) {
require_once BASE_PATH . '/app/thirdparty/geocoding-example/php/Mapbox.php';
$mapbox = new \Mapbox(MapboxField::getAccessToken());
// GET Address
$res = $mapbox->reverseGeocode($lng, $lat);
if ($res->success() && $res->getCount()) {
$res = $res->getData();
if (count($res) && isset($res[0]['place_name'])) {
$details = explode(',', $res[0]['place_name']);
$fields = [
'Address',
'City',
'State',
'Country',
];
$n = count($fields);
for($i = 0; $i < $n; $i++) {
if(!isset($details[$i])){
continue;
}
$name = $fields[$i];
$val = $details[$i];
// get postal code
if ($name === 'State') {
$this->setField('PostalCode',substr($val ,strrpos($val, ' ')+1));
}
$this->setField($name, $val);
}
}
}
}
}catch (\Exception $e) {
}
}
}

View File

@ -0,0 +1,21 @@
<% if $ShowTitle %>
<h2 class="content-element__title">$Title</h2>
<% end_if %>
<% if $Content %>
<div class="typography">$Content</div>
<% end_if %>
<% include Objects\Map %>
<% if $Locations %>
<div class="locations">
<div class="row">
<% loop $Locations %>
<div class="col-sm-3">
$forTemplate
</div>
<% end_loop %>
</div>
</div>
<% end_if %>

View File

@ -0,0 +1,28 @@
<div id="MapPin{$ID}" data-id="{$ID}" class="location">
<div class="fn">{$Title}</div>
<div class="addr">{$Address}</div>
<% if $Address2 %>
<div class="addr2">{$Address2}</div>
<% end_if %>
<% if $City || $PostalCode %>
<div class="city">
{$City}, {$State} {$PostalCode}
</div>
<% end_if %>
<% if $Country %>
<div class="d-none">{$Country}</div>
<% end_if %>
<% if $PhoneNumber %>
<% with $PhoneNumber %>
T: <a href="$LinkURL" class="tel">$Title</a><br/>
<% end_with %>
<% end_if %>
<% if $Fax %>
<% with $Fax %>
F: <span class="fax">$Title</span>
<% end_with %>
<% end_if %>
<div class="dir-link">
<a href="$DirectionsURL" target="_blank">Get Directions &raquo;</a>
</div>
</div>

1
app/thirdparty/geocoding-example vendored Submodule

@ -0,0 +1 @@
Subproject commit 57f2097c063461403df25c52fd5302f3ccc96f9c