huge Laravel 10 upgrade

This commit is contained in:
HolgerHatGarKeineNode
2023-02-19 20:13:20 +01:00
parent 5c74f77beb
commit 12847f95f6
440 changed files with 46336 additions and 682 deletions

View File

@@ -0,0 +1,18 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.yml]
indent_size = 2
[*.js]
indent_size = 2

15
support/laravel-maps/.gitattributes vendored Normal file
View File

@@ -0,0 +1,15 @@
* text=auto
/tests export-ignore
.editorconfig export-ignore
.gitattributes export-ignore
.gitignore export-ignore
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
*.jpg binary
*.png binary
*.gif binary
*.ico binary

53
support/laravel-maps/.gitignore vendored Normal file
View File

@@ -0,0 +1,53 @@
/.idea
/.vscode
.phpunit.result.cache
### Composer
/vendor
composer.phar
### Node
/node_modules
/package-lock.json
npm-debug.log*
.npm/
.eslintcache
.node_repl_history
*.js.LICENSE
### Windows
Thumbs.db
ehthumbs.db
Desktop.ini
$RECYCLE.BIN/
*.cab
*.msi
*.msm
*.msp
*.lnk
### macOS
*.DS_Store
.AppleDouble
.LSOverride
._*
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Linux
*~
.fuse_hidden*
.directory
.Trash-*
.nfs*

View File

@@ -0,0 +1,44 @@
# Changelog
All notable changes will be documented in this file.
### 1.2.2 - 2020-02-06
- Change the marker options iconSize and iconAnchor to snake case
### 1.2.1 - 2020-01-06
- Prevent double initialization
### 1.2.0 - 2020-01-06
- Add support for marker popups
- Events
### 1.1.0 - 2020-01-06
- Add support for custom marker icon images
### 1.0.4 - 2020-01-06
- Add Laravel 6 compatibility
### 1.0.3 - 2019-04-18
- Update service provider
### 1.0.2 - 2018-10-25
- Code cleanup
### 1.0.1 - 2018-08-30
- Code cleanup
## 1.0.0 - 2018-08-30
- Improvements, first stable release
## 0.0.1 - 2018-08-30
- Initial beta release

View File

@@ -0,0 +1,77 @@
# Contributing
Contributions are **welcome** and will be fully **credited**.
Please read and understand the contribution guide before creating an issue or
pull request.
## Etiquette
This project is open source, and as such, the maintainers give their free time
to build and maintain the source code held within. They make the code freely
available in the hope that it will be of use to other developers. It would be
extremely unfair for them to suffer abuse or anger for their hard work.
Please be considerate towards maintainers when raising issues or presenting
pull requests. Let's show the world that developers are civilized and selfless
people.
It's the duty of the maintainer to ensure that all submissions to the project
are of sufficient quality to benefit the project. Many developers have
different skillsets, strengths, and weaknesses. Respect the maintainer's
decision, and do not be upset or abusive if your submission is not used.
## Viability
When requesting or submitting new features, first consider whether it might be
useful to others. Open source projects are used by many developers, who may
have entirely different needs to your own. Think about whether or not your
feature is likely to be used by other users of the project.
## Procedure
Before filing an issue:
- Attempt to replicate the problem, to ensure that it wasn't a coincidental
incident.
- Check to make sure your feature suggestion isn't already present within the
project.
- Check the pull requests tab to ensure that the bug doesn't have a fix in
progress.
- Check the pull requests tab to ensure that the feature isn't already in
progress.
Before submitting a pull request:
- Check the codebase to ensure that your feature doesn't already exist.
- Check the pull requests to ensure that another person hasn't already
submitted the feature or fix.
## Requirements
If the project maintainer has any additional requirements, you will find them
listed here.
- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](https://pear.php.net/package/PHP_CodeSniffer).
- **Add tests!** - Your patch won't be accepted if it doesn't have tests.
- **Document any change in behaviour** - Make sure the `README.md` and any
other relevant documentation are kept up-to-date.
- **Consider our release cycle** - We try to follow [SemVer v2.0.0](https://semver.org/).
Randomly breaking public APIs is not an option.
- **One pull request per feature** - If you want to do more than one thing,
send multiple pull requests.
- **Send coherent history** - Make sure each individual commit in your pull
request is meaningful. If you had to make multiple intermediate commits while
developing, please [squash them](https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages)
before submitting.
**Happy coding**!

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2018-present Go NoWare
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,266 @@
# Maps for your Laravel application
[![GitLab Repository](https://img.shields.io/badge/GitLab-gonoware/laravel--maps-blue.svg?logo=gitlab&style=flat-square&longCache=true)](https://gitlab.com/gonoware/laravel-maps)
[![Laravel Version](https://img.shields.io/badge/Laravel-9-blue.svg?logo=laravel&style=flat-square&longCache=true)]()
[![Latest Stable Version](https://poser.pugx.org/gonoware/laravel-maps/v/stable?format=flat-square)](https://packagist.org/packages/gonoware/laravel-maps)
[![StyleCI](https://gitlab.styleci.io/repos/8146646/shield)](https://gitlab.styleci.io/repos/8146646)
[![License](https://poser.pugx.org/gonoware/laravel-maps/license?format=flat-square)](https://packagist.org/packages/gonoware/laravel-maps)
[![Total Downloads](https://poser.pugx.org/gonoware/laravel-maps/downloads?format=flat-square)](https://packagist.org/packages/gonoware/laravel-maps)
Using this package you can easily display maps on your website.
Supported map services:
* Google Maps
* OpenStreetMap
* Bing Maps
* MapQuest
* Yandex Maps
* MapKit (beta)
> Note: Yandex Maps API does not work in Chrome.
## Features
| | Google Maps | OpenStreetMap | Bing Maps | MapQuest | Yandex Maps | MapKit |
|---|:---:|:---:|:---:|:---:|:---:|:---:|
| [Map](#basic-map) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| [Markers](#map-with-markers) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| [Marker Links](#marker-links) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| [Marker Popups](#marker-popups) | ✔ | ✔ | ✔ | ✔ | ✔ | ❌ |
| [Custom Marker Icons](#custom-marker-icons) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
| [Marker Click Event](#marker-clicked) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
## Installation
This package can be installed through Composer.
```bash
composer require gonoware/laravel-maps
```
Publish the compiled assets to `public/vendor/maps` with one of these
commands:
```bash
php artisan vendor:publish --tag=maps
```
```bash
php artisan vendor:publish --provider="GoNoWare\Maps\MapsServiceProvider" --tag=public
```
> When updating, use the `--force` switch to overwrite existing assets:
```bash
php artisan vendor:publish --tag=maps --force
```
Optionally, you can also publish the config file of this package with this
command to `config/vendor/maps.php`:
```bash
php artisan vendor:publish --provider="GoNoWare\Maps\MapsServiceProvider" --tag=config
```
## Usage
Load the map styles by adding the following directive to your
Blade template before the `</head>` closing tag.
```php
@mapstyles
```
Then add the following directive to your Blade template
before the `</body>` closing tag, to load the map scripts.
```php
@mapscripts
```
### Basic Map
Display a map by adding the `@map` directive to your Blade template.
```php
@map([
'lat' => 48.134664,
'lng' => 11.555220,
'zoom' => 6,
])
```
### Map With Markers
You can also show markers / pins / annotations:
```php
@map([
'lat' => 48.134664,
'lng' => 11.555220,
'zoom' => 6,
'markers' => [
[
'title' => 'Go NoWare',
'lat' => 48.134664,
'lng' => 11.555220,
],
],
])
```
### Marker Links
Open a url when a marker is clicked.
```php
@map([
'lat' => 48.134664,
'lng' => 11.555220,
'zoom' => 6,
'markers' => [
[
'title' => 'Go NoWare',
'lat' => 48.134664,
'lng' => 11.555220,
'url' => 'https://gonoware.com',
],
],
])
```
### Marker Popups
Show a popup when a marker is clicked. The `popup` attribute may contain HTML markup.
```php
@map([
'lat' => 48.134664,
'lng' => 11.555220,
'zoom' => 6,
'markers' => [
[
'title' => 'Go NoWare',
'lat' => 48.134664,
'lng' => 11.555220,
'popup' => '<h3>Details</h3><p>Click <a href="https://gonoware.com">here</a>.</p>',
],
],
])
```
### Custom Marker Icons
Show a custom marker icon. Absolute and relative URLs are supported.
```php
@map([
'lat' => 48.134664,
'lng' => 11.555220,
'zoom' => 6,
'markers' => [
[
'title' => 'Go NoWare',
'lat' => 48.134664,
'lng' => 11.555220,
'url' => 'https://gonoware.com',
'icon' => 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',
],
],
])
```
Additionally you may also specify the icon image size and anchor in pixels. The image will be aligned so that the tip of the icon is at the marker's geographical location.
```php
@map([
'lat' => 48.134664,
'lng' => 11.555220,
'zoom' => 6,
'markers' => [
[
'title' => 'Go NoWare',
'lat' => 48.134664,
'lng' => 11.555220,
'url' => 'https://gonoware.com',
'icon' => 'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png',
'icon_size' => [20, 32],
'icon_anchor' => [0, 32],
],
],
])
```
## Styling
To adjust the height of the map use CSS:
```css
.gnw-map-service {
height: 750px;
}
```
Change the background of the map container:
```css
.gnw-map-service__osm {
background: rgb(221, 221, 221);
}
```
Fade in by default when using Bootstrap 3.3.7 or 4+. To replicate or modify the animation use following CSS:
```css
.gnw-map.fade {
transition: opacity .15s linear;
}
.gnw-map.fade:not(.show) {
opacity: 0;
}
```
## Events
### Map Initialized
The event `LaravelMaps:MapInitialized` will be dispatched when a map and its markers were initialized. The DOM element, map,
markers and service name can be accessed via the event details.
```js
window.addEventListener('LaravelMaps:MapInitialized', function (event) {
var element = event.detail.element;
var map = event.detail.map;
var markers = event.detail.markers;
var service = event.detail.service;
console.log('map initialized', element, map, markers, service);
});
```
Please refer to the respective documentation for advanced customization:
* [Google Maps](https://developers.google.com/maps/documentation/javascript/tutorial)
* [OpenStreetMap](https://leafletjs.com/reference-1.6.0.html)
* [Bing Maps](https://leafletjs.com/reference-1.6.0.html)
* [MapQuest](https://leafletjs.com/reference-1.6.0.html)
* [Yandex Maps](https://tech.yandex.com/maps/jsapi/)
* [MapKit (beta)](https://developer.apple.com/documentation/mapkitjs)
### Marker Clicked
The event `LaravelMaps:MarkerClicked` will be dispatched when a marker was clicked. The DOM element, map, marker and
service name can be accessed via the event details.
```js
window.addEventListener('LaravelMaps:MarkerClicked', function (event) {
var element = event.detail.element;
var map = event.detail.map;
var marker = event.detail.marker;
var service = event.detail.service;
console.log('marker clicked', element, map, marker, service);
});
```
## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently.
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
## Security
If you discover any security related issues, please email [em@gonoware.com](mailto:em@gonoware.com)
instead of using the issue tracker.
## Credits
- [Emanuel Mutschlechner](https://gitlab.com/emanuel)
- [Benedikt Tuschter](https://gitlab.com/benedikttuschter)
- [All Contributors](https://gitlab.com/gonoware/laravel-maps/graphs/master)
## License
[MIT](LICENSE.md)
Copyright (c) 2018-present Go NoWare
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgitlab.com%2Fgonoware%2Flaravel-maps.svg?type=large)](https://app.fossa.io/projects/git%2Bgitlab.com%2Fgonoware%2Flaravel-maps?ref=badge_large)

View File

@@ -0,0 +1,82 @@
{
"name": "gonoware/laravel-maps",
"description": "Maps for your Laravel application",
"keywords": [
"maps",
"laravel",
"gonoware",
"osm",
"google",
"bing",
"yandex",
"mapquest",
"googlemaps",
"openstreetmap",
"bingmaps",
"yandexmaps",
"mapkit",
"mapkitjs"
],
"homepage": "https://gitlab.com/gonoware/laravel-maps",
"support": {
"issues": "https://gitlab.com/gonoware/laravel-maps/issues",
"source": "https://gitlab.com/gonoware/laravel-maps"
},
"license": "MIT",
"authors": [
{
"name": "Emanuel Mutschlechner",
"email": "em@gonoware.com"
},
{
"name": "Benedikt Tuschter",
"email": "bt@gonoware.com"
}
],
"type": "library",
"require": {
"php": "^8.1",
"illuminate/support": "^9.0|^10.0"
},
"require-dev": {
"mockery/mockery": "^1.4.4",
"phpunit/phpunit": "^9.5.10"
},
"autoload": {
"psr-4": {
"GoNoWare\\Maps\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
},
"laravel": {
"providers": [
"GoNoWare\\Maps\\MapsServiceProvider"
]
}
},
"scripts": {
"build-script": [
"yarn install",
"yarn run prod"
],
"post-install-cmd": [
"@build-script"
],
"post-update-cmd": [
"@build-script"
]
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}

2854
support/laravel-maps/composer.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,93 @@
<?php
return [
/*
|----------------------------------------------------------------------
| Default Map Service Name
|----------------------------------------------------------------------
|
| Here you may specify which of the map services below you wish to use
| as your default service for all displayed maps. Of course you may use many services at once using the Maps library.
| Available maps: 'google', 'osm', 'bing', 'mapquest', 'yandex', 'mapkit'
|
*/
'default' => env('MAPS_SERVICE', 'osm'),
/*
|--------------------------------------------------------------------------
| Map Services
|--------------------------------------------------------------------------
|
| Here are each of the map services setup for your application.
| Of course, examples of configuring each map api that is supported by
| Maps is shown below to make development simple.
|
|
| All proprietary map services require an API Key, so make sure you have
| the key for your particular service of choice defined in your .env
| before you begin development.
|
*/
'services' => [
'google' => [
// https://developers.google.com/maps/documentation/javascript/get-api-key
// https://developers.google.com/maps/documentation/embed/get-api-key
'key' => env('MAPS_GOOGLE_KEY', ''),
// https://developers.google.com/maps/documentation/javascript/maptypes
'type' => 'roadmap', // 'roadmap', 'satellite', 'hybrid', 'terrain',
],
'bing' => [
// https://msdn.microsoft.com/en-us/library/ff428642.aspx
// https://www.bingmapsportal.com
'key' => env('MAPS_BING_KEY', ''),
],
'osm' => [
'type' => 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
],
'yandex' => [
// https://developer.tech.yandex.com/keys
// limited free quota
'key' => env('MAPS_YANDEX_KEY', ''),
],
'mapquest' => [
// https://developer.mapquest.com/plan_purchase/steps/business_edition/business_edition_free/register
// https://developer.mapquest.com/user/me/apps
'key' => env('MAPS_MAPQUEST_KEY', ''),
// https://developer.mapquest.com/documentation/mapquest-js/v1.3/l-mapquest-tile-layer/
'type' => 'map', // 'map', 'hybrid', 'satellite', 'light', 'dark'
],
'mapkit' => [
// https://developer.apple.com/videos/play/wwdc2018/508
// https://developer.apple.com/documentation/mapkitjs/setting_up_mapkit_js?changes=latest_minor
'key' => env('MAPS_MAPKIT_KEY', ''),
// https://developer.apple.com/documentation/mapkitjs/mapkit/map/maptypes
'type' => 'standard', // 'standard', 'hybrid', 'satellite'
],
],
/*
|--------------------------------------------------------------------------
| Maps Enabled
|--------------------------------------------------------------------------
|
| By default, Maps is enabled. You can set the value to false to disable
| rendering of all maps.
|
*/
'enabled' => env('MAPS_ENABLED', true),
];

View File

@@ -0,0 +1,32 @@
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"laravel-mix": "^6.0.6",
"leaflet-bing-layer": "^3.3.1",
"resolve-url-loader": "^3.1.0",
"sass": "^1.24.2",
"sass-loader": "^8.0.0",
"vue-template-compiler": "^2.6.11"
},
"browserslist": [
"last 1 version",
"> 1%",
"Chrome >= 45",
"Firefox >= 38",
"Edge >= 12",
"Explorer >= 10",
"iOS >= 9",
"Safari >= 9",
"Android >= 4.4",
"Opera >= 30"
]
}

View File

@@ -0,0 +1 @@
.gnw-map-service{height:400px;position:relative}.gnw-map-service__google{background:#e5e3df}.gnw-map-service__bing,.gnw-map-service__mapquest,.gnw-map-service__osm{background:#ddd}.gnw-map-service__yandex{background:#f3f1ed}.gnw-map-service__mapkit{background:#f8f4ec}.gnw-map{height:inherit}.gnw-map .mk-map-view>.syrup-canvas{margin-left:-50%}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,4 @@
/* @preserve
* Leaflet 1.9.2, a JS library for interactive maps. https://leafletjs.com
* (c) 2010-2022 Vladimir Agafonkin, (c) 2010-2011 CloudMade
*/

View File

@@ -0,0 +1,4 @@
{
"/js/index.js": "/js/index.js?id=6508504506f20e7f033c7de36683001a",
"/css/index.css": "/css/index.css?id=56062e68c820fdf21c3c4ec98fbe553b"
}

View File

@@ -0,0 +1,69 @@
import google from './services/google';
import osm from './services/osm';
import bing from './services/bing';
import mapquest from './services/mapquest';
import yandex from './services/yandex';
import mapkit from './services/mapkit';
import parser from './utils/parser';
import {isDefined, logError} from './utils/helper';
import './utils/customEventPolyfill';
import {dispatchEventMapInitialized} from './utils/dispatchEvent';
const createMap = (element, createMap, createMarker) => {
if (!isDefined(element)) {
logError('element is undefined');
return;
}
const mapData = parser.map(element);
if (!isDefined(mapData)) {
logError('map data is undefined');
return;
}
const map = createMap(element, mapData);
if (!isDefined(map)) {
logError('map is undefined');
return;
}
const markers = mapData.markers.map(markerData => createMarker(element, map, markerData));
return {
map,
markers,
};
};
const createMapService = service => {
const createMapService = element => createMap(
element,
service.createMap,
service.createMarker,
);
const selector = `[data-map-${service.name}]`;
const elements = Array.prototype.slice.call(document.querySelectorAll(selector) || []);
elements.forEach(element => {
if (element.getAttribute('data-map-initialized') === true) {
return;
}
const data = createMapService(element);
dispatchEventMapInitialized(service.name, element, data);
element.setAttribute('data-map-initialized', true);
});
};
window.onGoogleMapsReady = () => createMapService(google);
window.onYandexMapsReady = () => createMapService(yandex);
window.addEventListener('DOMContentLoaded', () => {
(() => createMapService(osm))();
(() => createMapService(bing))();
(() => createMapService(mapquest))();
(() => createMapService(mapkit))();
});

View File

@@ -0,0 +1,33 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import 'leaflet-bing-layer';
import {createMarker} from '../utils/leaflet';
const name = 'bing';
export default {
name,
createMap(element, mapData) {
if (!isDefined(window.L)) {
logError('leaflet is undefined');
return;
}
const {lat, lng, zoom, service} = mapData;
const map = window.L
.map(element, {})
.on('load', () => {
fadeElementIn(element);
})
.setView([lat, lng], zoom);
window.L.tileLayer
.bing({
bingMapsKey: service.key,
imagerySet: 'CanvasLight',
})
.addTo(map);
return map;
},
createMarker: createMarker.bind(null, name),
}

View File

@@ -0,0 +1,70 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import {dispatchEventMarkerClicked} from '../utils/dispatchEvent';
const name = 'google';
export default {
name,
createMap(element, mapData) {
if (!isDefined(window.google)) {
logError('google is undefined');
return;
}
if (!isDefined(window.google.maps)) {
logError('google maps is undefined');
return;
}
const {lat, lng, zoom, service} = mapData;
const map = new window.google.maps.Map(element, {
center: new window.google.maps.LatLng(lat, lng),
zoom,
mapTypeId: service.type || window.google.maps.MapTypeId.ROADMAP,
});
window.google.maps.event.addListenerOnce(map, 'idle', () => {
fadeElementIn(element);
});
return map;
},
createMarker(element, map, markerData) {
const {title, lat, lng, url, popup, icon, iconSize, iconAnchor} = markerData;
const markerOptions = {
position: new window.google.maps.LatLng(lat, lng),
map,
title,
draggable: false,
};
if (icon) {
markerOptions.icon = {
url: icon,
};
if (iconSize) {
markerOptions.icon.size = new window.google.maps.Size(...iconSize);
}
if (iconAnchor) {
markerOptions.icon.anchor = new window.google.maps.Point(...iconAnchor);
}
}
const marker = new window.google.maps.Marker(markerOptions);
marker.addListener('click', () => {
dispatchEventMarkerClicked(name, element, map, marker);
if (popup) {
const infoWindow = new window.google.maps.InfoWindow({
content: popup
});
infoWindow.open(map, marker);
} else if (url) {
openUrl(url);
}
});
return marker;
},
};

View File

@@ -0,0 +1,66 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import {dispatchEventMarkerClicked} from "../utils/dispatchEvent";
const name = 'mapkit';
export default {
name,
createMap(element, mapData) {
if (!isDefined(window.mapkit)) {
logError('mapkit is undefined');
return;
}
const {lat, lng, zoom, service} = mapData;
window.mapkit.init({
authorizationCallback(done) {
done(service.key);
},
});
window.mapkit.addEventListener('configuration-change', event => {
if (event.status === 'Initialized') {
fadeElementIn(element);
}
});
const map = new window.mapkit.Map(element, {
mapType: service.type || window.mapkit.Map.MapTypes.Standard,
});
const delta = Math.exp(Math.log(360) - (zoom * Math.LN2)); // TODO: zoom to delta not working
map.region = new window.mapkit.CoordinateRegion(
new window.mapkit.Coordinate(lat, lng),
new window.mapkit.CoordinateSpan(delta, delta),
);
return map;
},
createMarker(element, map, markerData) {
const {title, lat, lng, url, popup, icon} = markerData;
const coordinate = new window.mapkit.Coordinate(lat, lng);
const markerAnnotationOptions = {title};
if (icon) {
markerAnnotationOptions.glyphImage = {
1: icon,
};
}
const marker = new window.mapkit.MarkerAnnotation(coordinate, markerAnnotationOptions);
marker.addEventListener('select', event => {
dispatchEventMarkerClicked(name, element, map, marker);
if (popup) {
// TODO
} else if (url) {
openUrl(url);
}
});
map.showItems([marker]); // TODO: map auto resize bugging if multiple markers
return marker;
},
};

View File

@@ -0,0 +1,40 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import {createMarker} from '../utils/leaflet';
// TODO maybe add this https://github.com/elmarquis/Leaflet.GestureHandling/
// TODO add config for different styles like database connections: https://wiki.openstreetmap.org/wiki/Tile_servers
// http://leaflet-extras.github.io/leaflet-providers/preview/
// TODO custom icons: https://leafletjs.com/examples/custom-icons/
const name = 'mapquest';
export default {
name,
createMap(element, mapData) {
if (!isDefined(window.L)) {
logError('leaflet is undefined');
return;
}
if (!isDefined(window.L.mapquest)) {
logError('mapquest is undefined');
return
}
const {lat, lng, zoom, service} = mapData;
window.L.mapquest.key = service.key;
const map = window.L.mapquest
.map(element, {
center: [lat, lng],
zoom,
layers: window.L.mapquest.tileLayer(service.type || 'map'),
})
.on('load', () => {
fadeElementIn(element);
})
.setView([lat, lng], zoom);
return map;
},
createMarker: createMarker.bind(null, name),
}

View File

@@ -0,0 +1,38 @@
import {fadeElementIn, isDefined, logError, openUrl} from '../utils/helper';
import {createMarker} from '../utils/leaflet';
// TODO maybe add this https://github.com/elmarquis/Leaflet.GestureHandling/
// TODO add config for different styles like database connections: https://wiki.openstreetmap.org/wiki/Tile_servers
// http://leaflet-extras.github.io/leaflet-providers/preview/
// TODO custom icons: https://leafletjs.com/examples/custom-icons/
const name = 'osm';
export default {
name,
createMap(element, mapData) {
if (!isDefined(window.L)) {
logError('leaflet is undefined');
return;
}
const {lat, lng, zoom, service} = mapData;
const map = window.L
.map(element, {})
.on('load', () => {
fadeElementIn(element);
})
.setView([lat, lng], zoom);
window.L
.tileLayer(service.type || 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
})
.addTo(map);
return map;
},
createMarker: createMarker.bind(null, name),
}

View File

@@ -0,0 +1,65 @@
import {isDefined, logError, openUrl} from '../utils/helper';
import {dispatchEventMarkerClicked} from '../utils/dispatchEvent';
const name = 'yandex';
export default {
name,
createMap(element, mapData) {
if (!isDefined(window.ymaps)) {
logError('ymaps is undefined');
return;
}
const {lat, lng, zoom} = mapData;
const map = new window.ymaps.Map(element, {
center: [lat, lng],
zoom,
});
// window.google.maps.event.addListenerOnce(map, 'idle', () => {
// fadeElementIn(element);
// });
return map;
},
createMarker(element, map, markerData) {
const {title, lat, lng, url, popup, icon, iconSize, iconAnchor} = markerData;
const placemarkProperties = {
hintContent: title,
};
const placemarkOptions = {};
if (icon) {
placemarkOptions.iconLayout = 'default#imageWithContent';
placemarkOptions.iconImageHref = icon;
if (iconSize) {
placemarkOptions.iconImageSize = iconSize;
}
if (iconAnchor) {
placemarkOptions.iconImageOffset = iconAnchor;
}
}
if (popup) {
placemarkProperties.balloonContentBody = popup;
}
const marker = new window.ymaps.Placemark([lat, lng], placemarkProperties, placemarkOptions);
marker.events.add('click', e => {
dispatchEventMarkerClicked(name, element, map, marker);
if (popup) {
// Handled with ballonContentBody
} else if (url) {
openUrl(url);
}
});
map.geoObjects.add(marker);
return marker;
},
};

View File

@@ -0,0 +1,15 @@
(function () {
if (window.CustomEvent) return false;
function CustomEvent(event, params) {
params = params || {
bubbles: false, cancelable: false, detail: undefined
};
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent(
event, params.bubbles, params.cancelable, params.detail
);
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();

View File

@@ -0,0 +1,23 @@
export function dispatchEventMapInitialized (serviceName, element, data) {
const event = new CustomEvent('LaravelMaps:MapInitialized', {
detail: {
element: element,
map: data.map,
markers: data.markers || [],
service: serviceName,
},
});
window.dispatchEvent(event);
}
export function dispatchEventMarkerClicked (serviceName, element, map, marker) {
const event = new CustomEvent('LaravelMaps:MarkerClicked', {
detail: {
element: element,
map: map,
marker: marker,
service: serviceName,
},
});
window.dispatchEvent(event);
}

View File

@@ -0,0 +1,11 @@
export const isDefined = object => typeof object !== 'undefined';
export const fadeElementIn = element => {
const target = element.closest('.fade');
target.classList.add('show'); // Bootstrap 4
target.classList.add('in'); // Backwards compatibility Bootstrap 3.3.7
};
export const openUrl = url => window.open(url, '_blank');
export const logError = error => isDefined(console) && console.error('[laravel-maps] error:', error);

View File

@@ -0,0 +1,44 @@
import {openUrl} from './helper';
import {dispatchEventMarkerClicked} from './dispatchEvent';
export function createMarker(service, element, map, markerData) {
const {title, lat, lng, url, popup, icon, iconSize, iconAnchor} = markerData;
const markerOptions = {
title,
keyboard: false,
draggable: false,
};
if (icon) {
const iconOptions = {
iconUrl: icon,
};
if (iconSize) {
iconOptions.iconSize = iconSize;
}
if (iconAnchor) {
iconOptions.iconAnchor = iconAnchor;
}
markerOptions.icon = window.L.icon(iconOptions);
}
const marker = window.L.marker([lat, lng], markerOptions);
marker.on('click', event => {
event.originalEvent.preventDefault();
dispatchEventMarkerClicked(service, element, map, marker);
if (popup) {
window.L.popup()
.setLatLng([lat, lng])
.setContent(popup)
.openOn(map);
} else if (url) {
openUrl(url);
}
});
marker.addTo(map);
return marker;
}

View File

@@ -0,0 +1,74 @@
import {logError} from './helper';
const parseMap = element => JSON.parse(
element.dataset.mapGoogle
|| element.dataset.mapOsm
|| element.dataset.mapBing
|| element.dataset.mapMapquest
|| element.dataset.mapYandex
|| element.dataset.mapMapkit
);
const parseService = element => {
const {key, type} = JSON.parse(element.dataset.mapService);
return {
key,
type,
}
};
const parseMarkers = element => {
const markers = JSON.parse(element.dataset.mapMarkers) || [];
return markers.map(marker => {
const lat = parseNumberFloat(marker.lat);
const lng = parseNumberFloat(marker.lng);
const {title, url, popup, icon, icon_size, icon_anchor} = marker;
return {
title,
lat,
lng,
url,
popup,
icon,
iconSize: icon_size || marker.iconSize,
iconAnchor: icon_anchor || marker.iconAnchor,
};
});
};
const parseNumberFloat = number => {
return typeof number === 'string'
? parseFloat(number)
: number;
};
const parseNumberInt = number => {
return typeof number === 'string'
? parseFloat(number)
: number;
};
export default {
map(element) {
try {
const map = parseMap(element);
const lat = parseNumberFloat(map.lat);
const lng = parseNumberFloat(map.lng);
const zoom = parseNumberInt(map.zoom);
const service = parseService(element);
const markers = parseMarkers(element);
return {
lat,
lng,
zoom,
service,
markers,
};
} catch (e) {
logError(e);
}
},
}

View File

@@ -0,0 +1,30 @@
.gnw-map-service {
position: relative;
height: 400px;
&__google {
background: rgb(229, 227, 223);
}
&__osm,
&__bing,
&__mapquest {
background: rgb(221, 221, 221);
}
&__yandex {
background: rgb(243, 241, 237);
}
&__mapkit {
background: rgb(248, 244, 236);
}
}
.gnw-map {
height: inherit;
// Fix Mapkit canvas
.mk-map-view {
> .syrup-canvas {
margin-left: -50%;
}
}
}

View File

@@ -0,0 +1,23 @@
@if ($enabled)
<div class="gnw-map-service gnw-map-service__{{ $service }}">
<div class="gnw-map fade" data-map-{{ $service }}="{{ json_encode(compact('lat', 'lng', 'zoom')) }}" data-map-service="{{ json_encode(config('vendor.maps.services.'.$service)) }}" data-map-markers="{{ json_encode($markers ?? []) }}"></div>
</div>
{{--
<div class="col-lg-12"></div>
<div class="clear-fix"></div>
<div class="col-lg-12"></div>
<div class="clear-fix"></div>
<iframe class="map" width="800" height="450" frameborder="0" style="border:0" src="https://www.google.com/maps/embed/v1/place?key={{ $key ?? '' }}&q={{ $lat }},{{ $lng }}&center={{ $lat }},{{ $lng }}&zoom={{ $zoom }}" scrolling="no">
</iframe>
<div class="col-lg-12"></div>
<div class="clear-fix"></div>
<div class="map-container fade in">
<iframe class="map" width="800" height="800" frameborder="0" style="border:0" src="https://www.bing.com/maps/embed?h=800&w=800&cp={{ $lat }}~{{ $lng }}&lvl={{ $zoom }}&typ=d&sty=r&src=SHELL&FORM=MBEDV8" scrolling="no">
</iframe>
</div>
--}}
@endif

View File

@@ -0,0 +1,24 @@
@if ($enabled)
{{--TODO: If overriding service via @map() then service is not working--}}
@if ($service == 'osm' || $service == 'bing' || $service == 'mapquest')
<script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin="" type="text/javascript"></script>
{{-- TODO check if bing needs polyfill: https://github.com/digidem/leaflet-bing-layer--}}
@endif
<script src="{{ asset(mix('js/index.js', 'vendor/maps')) }}" type="text/javascript"></script>
@if ($service == 'mapkit')
<script src="https://cdn.apple-mapkit.com/mk/5.x.x/mapkit.js" type="text/javascript"></script>
@endif
@if ($service == 'mapquest')
<script src="https://api.mqcdn.com/sdk/mapquest-js/v1.3.2/mapquest-core.js" type="text/javascript"></script>
@endif
@if ($service == 'yandex')
@if (!empty($key = config('vendor.maps.services.yandex.key')))
<script src="https://enterprise.api-maps.yandex.ru/2.1/?lang=en_US&apikey={{ $key }}&onload=onYandexMapsReady" type="text/javascript" async defer></script>
@else
<script src="https://api-maps.yandex.ru/2.1/?lang=en_US&onload=onYandexMapsReady" type="text/javascript" async defer></script>
@endif
@endif
@if ($service == 'google')
<script src="https://maps-api-ssl.google.com/maps/api/js?v=3&ie=UTF8&oe=UTF8&key={{ config('vendor.maps.services.google.key') }}&language={{ app()->getLocale() }}&callback=onGoogleMapsReady" type="text/javascript" async defer></script>
@endif
@endif

View File

@@ -0,0 +1,9 @@
@if ($enabled)
@if ($service == 'osm' || $service == 'bing' || $service == 'mapquest')
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" type="text/css">
@endif
@if ($service == 'mapquest')
<link rel="stylesheet" href="https://api.mqcdn.com/sdk/mapquest-js/v1.3.2/mapquest-core.css" type="text/css">
@endif
<link rel="stylesheet" href="{{ asset(mix('css/index.css', 'vendor/maps')) }}" type="text/css">
@endif

View File

@@ -0,0 +1,83 @@
<?php
namespace GoNoWare\Maps;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
/*
TODO:
https://www.bing.com/maps/embed-a-map
https://developers.google.com/maps/documentation/maps-static/intro
https://wiki.openstreetmap.org/wiki/OpenLinkMap#Embed_map_in_another_website
embed via iframe:
- bing
- osm?
javascript api:
- all
Add custom marker
Add custom popup
*/
class MapsServiceProvider extends BaseServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
$this->publishFiles();
Blade::include('maps::styles', 'mapstyles');
Blade::include('maps::scripts', 'mapscripts');
Blade::include('maps::index', 'map');
$this->loadViewsFrom(__DIR__.'/../resources/views', 'maps');
view()->composer('maps::*', function ($view) {
if (!isset($view->service)) {
$view->with('service', config('vendor.maps.default'));
}
if (!isset($view->enabled)) {
$view->with('enabled', config('vendor.maps.enabled'));
}
return $view;
});
}
/**
* Register services.
*
* @return void
*/
public function register()
{
$this->mergeConfigFrom(__DIR__.'/../config/maps.php', 'vendor.maps');
}
/**
* Publish files.
*
* @return void
*/
private function publishFiles()
{
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/../config/maps.php' => config_path('vendor/maps.php'),
], 'config');
$this->publishes([
__DIR__.'/../public' => public_path('vendor/maps'),
], 'public');
$this->publishes([
__DIR__.'/../public' => public_path('vendor/maps'),
], 'maps');
}
}
}

View File

@@ -0,0 +1,16 @@
preset: laravel
linting: true
enabled:
- alpha_ordered_imports
disabled:
- length_ordered_imports
finder:
exclude:
- "node_modules"
- "public"
- "tests"
- "vendor"

View File

7
support/laravel-maps/webpack.mix.js vendored Normal file
View File

@@ -0,0 +1,7 @@
const mix = require('laravel-mix');
mix.setPublicPath('public')
.js('resources/js/index.js', 'js')
.sass('resources/sass/index.scss', 'css')
.copy('resources/img/*.png', 'img')
.version('img');

File diff suppressed because it is too large Load Diff