diff --git a/composer.json b/composer.json
index 775cb90..b4d493a 100644
--- a/composer.json
+++ b/composer.json
@@ -22,7 +22,7 @@
"source": "https://github.com/netzmacht/contao-leaflet-maps"
},
"require": {
- "php": ">=7.0",
+ "php": ">=7.1",
"ext-json": "*",
"ext-pdo": "*",
"contao/core-bundle": "~4.4",
@@ -39,6 +39,7 @@
"netzmacht/php-javascript-builder": "^1.0",
"netzmacht/php-leaflet": "^1.0.2",
"netzmacht/contao-toolkit": "~3.0",
+ "netzmacht/contao-page-context": "~1.0",
"contao-community-alliance/meta-palettes": "^2.0 || ^1.5",
"menatwork/contao-multicolumnwizard": "^3.2",
"doctrine/cache": "^1.0"
diff --git a/js/Contao.js b/js/Contao.js
index 004d65e..69ce015 100644
--- a/js/Contao.js
+++ b/js/Contao.js
@@ -138,7 +138,7 @@ L.Contao = L.Evented.extend({
* @param customLayer optional custom layer.
* @param map Pass a map object so that the data loading events are passed to the map.
*/
- loadFile: function (url, type, options, customLayer, map) {
+ loadUrl: function (url, type, options, customLayer, map) {
var layer = omnivore[type](url, options, customLayer);
if (map) {
@@ -172,6 +172,19 @@ L.Contao = L.Evented.extend({
return layer;
},
+ /**
+ * Load data from an url into a layer using omnivore.
+ *
+ * @param url A file url.
+ * @param type The response content format.
+ * @param options Parser options
+ * @param customLayer optional custom layer.
+ * @param map Pass a map object so that the data loading events are passed to the map.
+ */
+ loadFile: function (url, type, options, customLayer, map) {
+ return this.loadUrl(url, type, options, customLayer, map);
+ },
+
/**
* Point to layer callback. Adds a geo json point to the layer.
*
diff --git a/src/Bundle/ContaoManager/Plugin.php b/src/Bundle/ContaoManager/Plugin.php
index 8033179..f9f6d52 100644
--- a/src/Bundle/ContaoManager/Plugin.php
+++ b/src/Bundle/ContaoManager/Plugin.php
@@ -18,15 +18,20 @@ use Contao\CoreBundle\ContaoCoreBundle;
use Contao\ManagerPlugin\Bundle\BundlePluginInterface;
use Contao\ManagerPlugin\Bundle\Config\BundleConfig;
use Contao\ManagerPlugin\Bundle\Parser\ParserInterface;
+use Contao\ManagerPlugin\Routing\RoutingPluginInterface;
use Netzmacht\Contao\Leaflet\Bundle\NetzmachtContaoLeafletBundle;
+use Netzmacht\Contao\PageContext\NetzmachtContaoPageContextBundle;
use Netzmacht\Contao\Toolkit\Bundle\NetzmachtContaoToolkitBundle;
+use Symfony\Component\Config\Loader\LoaderResolverInterface;
+use Symfony\Component\HttpKernel\KernelInterface;
+use Symfony\Component\Routing\RouteCollection;
/**
* Contao manager plugin.
*
* @package Netzmacht\Contao\Leaflet\ContaoManager
*/
-class Plugin implements BundlePluginInterface
+class Plugin implements BundlePluginInterface, RoutingPluginInterface
{
/**
* {@inheritdoc}
@@ -35,8 +40,32 @@ class Plugin implements BundlePluginInterface
{
return [
BundleConfig::create(NetzmachtContaoLeafletBundle::class)
- ->setLoadAfter([ContaoCoreBundle::class, NetzmachtContaoToolkitBundle::class])
+ ->setLoadAfter(
+ [
+ ContaoCoreBundle::class,
+ NetzmachtContaoToolkitBundle::class,
+ NetzmachtContaoPageContextBundle::class
+ ]
+ )
->setReplace(['leaflet']),
];
}
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getRouteCollection(LoaderResolverInterface $resolver, KernelInterface $kernel): ?RouteCollection
+ {
+ $loader = $resolver->resolve(__DIR__ . '/../Resources/config/routing.yml');
+ if (!$loader) {
+ return null;
+ }
+
+ $collection = $loader->load(__DIR__ . '/../Resources/config/routing.yml');
+ if ($collection instanceof RouteCollection) {
+ $collection->addPrefix('leaflet/api');
+ }
+
+ return $collection;
+ }
}
diff --git a/src/Bundle/Resources/config/mappers.yml b/src/Bundle/Resources/config/mappers.yml
index 39644e6..e45987c 100644
--- a/src/Bundle/Resources/config/mappers.yml
+++ b/src/Bundle/Resources/config/mappers.yml
@@ -32,6 +32,7 @@ services:
class: Netzmacht\Contao\Leaflet\Mapper\Layer\MarkersLayerMapper
arguments:
- '@netzmacht.contao_toolkit.repository_manager'
+ - '@router'
tags:
- { name: netzmacht.contao_leaflet.mapper }
@@ -46,6 +47,7 @@ services:
class: Netzmacht\Contao\Leaflet\Mapper\Layer\VectorsLayerMapper
arguments:
- '@netzmacht.contao_toolkit.repository_manager'
+ - '@router'
tags:
- { name: netzmacht.contao_leaflet.mapper }
diff --git a/src/Bundle/Resources/config/routing.yml b/src/Bundle/Resources/config/routing.yml
new file mode 100644
index 0000000..371ec1a
--- /dev/null
+++ b/src/Bundle/Resources/config/routing.yml
@@ -0,0 +1,11 @@
+leaflet_layer:
+ path: /layer/{layerId}
+ controller: Netzmacht\Contao\Leaflet\Frontend\Action\LayerDataAction
+ defaults:
+ _leaflet_scope: page
+ _format: geojson
+ _scope: frontend
+ requirements:
+ _format: geojson
+ context: \w+
+ contextId: \d+
diff --git a/src/Bundle/Resources/config/services.yml b/src/Bundle/Resources/config/services.yml
index 2eae139..454f01c 100644
--- a/src/Bundle/Resources/config/services.yml
+++ b/src/Bundle/Resources/config/services.yml
@@ -122,3 +122,12 @@ services:
arguments:
- '@netzmacht.contao_leaflet.filter_factory'
- '%kernel.debug%'
+
+ Netzmacht\Contao\Leaflet\Frontend\PageIdDeterminator:
+ tags:
+ - { name: Netzmacht\Contao\PageContext\Request\PageIdDeterminator }
+
+ Netzmacht\Contao\Leaflet\Frontend\Action\LayerDataAction:
+ arguments:
+ - '@netzmacht.contao_leaflet.map.provider'
+ - '@netzmacht.contao_leaflet.filter_factory'
diff --git a/src/Bundle/Resources/public/js/contao-leaflet.js b/src/Bundle/Resources/public/js/contao-leaflet.js
index e26d02d..80ce810 100644
--- a/src/Bundle/Resources/public/js/contao-leaflet.js
+++ b/src/Bundle/Resources/public/js/contao-leaflet.js
@@ -1 +1 @@
-L.Contao=L.Evented.extend({statics:{ATTRIBUTION:' | netzmacht'},maps:{},icons:{},initialize:function(){L.Icon.Default.imagePath="assets/leaflet/libs/leaflet/images/",this.setGeoJsonListeners(L.GeoJSON)},addMap:function(t,o){return this.maps[t]=o,this.fire("map:added",{id:t,map:o}),this},getMap:function(t){return void 0===this.maps[t]?null:this.maps[t]},addIcon:function(t,o){return this.icons[t]=o,this.fire("icon:added",{id:t,icon:o}),this},loadIcons:function(t){for(var o=0;o=200&&t<300||304===t}function i(){void 0===a.status||n(a.status)?o.call(a,null,a):o.call(a,a,null)}var s=!1;if(void 0===window.XMLHttpRequest)return o(Error("Browser not supported"));if(void 0===e){var r=t.match(/^\s*https?:\/\/[^\/]*/);e=r&&r[0]!==location.protocol+"//"+location.hostname+(location.port?":"+location.port:"")}var a=new window.XMLHttpRequest;if(e&&!("withCredentials"in a)){a=new window.XDomainRequest;var p=o;o=function(){if(s)p.apply(this,arguments);else{var t=this,o=arguments;setTimeout(function(){p.apply(t,o)},0)}}}return"onload"in a?a.onload=i:a.onreadystatechange=function(){4===a.readyState&&i()},a.onerror=function(t){o.call(this,t||!0,null),o=function(){}},a.onprogress=function(){},a.ontimeout=function(t){o.call(this,t,null),o=function(){}},a.onabort=function(t){o.call(this,t,null),o=function(){}},a.open("GET",t,!0),a.send(null),s=!0,a}});
\ No newline at end of file
+L.Contao=L.Evented.extend({statics:{ATTRIBUTION:' | netzmacht'},maps:{},icons:{},initialize:function(){L.Icon.Default.imagePath="assets/leaflet/libs/leaflet/images/",this.setGeoJsonListeners(L.GeoJSON)},addMap:function(t,o){return this.maps[t]=o,this.fire("map:added",{id:t,map:o}),this},getMap:function(t){return void 0===this.maps[t]?null:this.maps[t]},addIcon:function(t,o){return this.icons[t]=o,this.fire("icon:added",{id:t,icon:o}),this},loadIcons:function(t){for(var o=0;ogetValue();
$encoder = $event->getEncoder();
$template = 'L.contao.%s(%s, %s, %s, %s, map);';
- $method = 'loadFile';
+ $method = 'loadUrl';
if ($value instanceof OmnivoreLayer) {
$url = $value->getUrl();
diff --git a/src/Frontend/Action/LayerDataAction.php b/src/Frontend/Action/LayerDataAction.php
new file mode 100644
index 0000000..da8f94c
--- /dev/null
+++ b/src/Frontend/Action/LayerDataAction.php
@@ -0,0 +1,103 @@
+
+ * @copyright 2014-2018 netzmacht David Molineus. All rights reserved.
+ * @license LGPL-3.0 https://github.com/netzmacht/contao-leaflet-maps/blob/master/LICENSE
+ * @filesource
+ */
+
+declare(strict_types=1);
+
+namespace Netzmacht\Contao\Leaflet\Frontend\Action;
+
+use Netzmacht\Contao\Leaflet\Filter\Filter;
+use Netzmacht\Contao\Leaflet\Filter\FilterFactory;
+use Netzmacht\Contao\Leaflet\MapProvider;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+
+/**
+ * Request action which handles request for layer data
+ */
+final class LayerDataAction
+{
+ /**
+ * Map provider.
+ *
+ * @var MapProvider
+ */
+ private $mapProvider;
+
+ /**
+ * Filter factory.
+ *
+ * @var FilterFactory
+ */
+ private $filterFactory;
+
+ /**
+ * LayerDataAction constructor.
+ *
+ * @param MapProvider $mapProvider Map provider.
+ * @param FilterFactory $filterFactory Filter factory.
+ */
+ public function __construct(MapProvider $mapProvider, FilterFactory $filterFactory)
+ {
+ $this->mapProvider = $mapProvider;
+ $this->filterFactory = $filterFactory;
+ }
+
+ /**
+ * Handle the request.
+ *
+ * @param int $layerId The layer id.
+ * @param string $_format The requested output format.
+ * @param Request $request The request.
+ *
+ * @return Response
+ *
+ * @throws BadRequestHttpException When unsupported format is given.
+ *
+ * @SuppressWarnings(PHPMD.CamelCaseParameterName)
+ * @SuppressWarnings(PHPMD.CamelCaseVariableName)
+ */
+ public function __invoke(int $layerId, string $_format, Request $request): Response
+ {
+ $filter = $this->createFilter($request);
+ $data = $this->mapProvider->getFeatureCollection($layerId, $filter);
+
+ if ($_format === 'geojson') {
+ $response = new JsonResponse($data);
+ $response->setEncodingOptions(JSON_UNESCAPED_SLASHES);
+
+ return $response;
+ }
+
+ throw new BadRequestHttpException(sprintf('Unsupported format "%s"', $_format));
+ }
+
+ /**
+ * Create the filter if defined in the request.
+ *
+ * @param Request $request The request.
+ *
+ * @return Filter|null
+ */
+ private function createFilter(Request $request): ?Filter
+ {
+ if (!$request->query->has('filter')) {
+ return null;
+ }
+
+ $filter = (string) $request->query->get('filter');
+ $values = (string) $request->query->get('values');
+
+ return $this->filterFactory->create($filter, $values);
+ }
+}
diff --git a/src/Frontend/DataController.php b/src/Frontend/DataController.php
index c5dd4cc..563b5e6 100644
--- a/src/Frontend/DataController.php
+++ b/src/Frontend/DataController.php
@@ -12,14 +12,18 @@
namespace Netzmacht\Contao\Leaflet\Frontend;
+use const E_USER_DEPRECATED;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Filter\FilterFactory;
use Netzmacht\Contao\Leaflet\MapProvider;
+use function trigger_error;
/**
* The data controller handles ajax request for sub data.
*
* @package Netzmacht\Contao\Leaflet\Frontend
+ *
+ * @deprecated
*/
class DataController
{
@@ -60,6 +64,13 @@ class DataController
{
$this->debugMode = $debugMode;
$this->filterFactory = $filterFactory;
+
+ // @codingStandardsIgnoreStart
+ @trigger_error(
+ 'Deprecated since 3.1.0 and will be removed in 4.0.0 - Use properly route instead.',
+ E_USER_DEPRECATED
+ );
+ // @codingStandardsIgnoreEnd
}
/**
diff --git a/src/Frontend/PageIdDeterminator.php b/src/Frontend/PageIdDeterminator.php
new file mode 100644
index 0000000..ad8807a
--- /dev/null
+++ b/src/Frontend/PageIdDeterminator.php
@@ -0,0 +1,47 @@
+
+ * @copyright 2014-2018 netzmacht David Molineus. All rights reserved.
+ * @license LGPL-3.0 https://github.com/netzmacht/contao-leaflet-maps/blob/master/LICENSE
+ * @filesource
+ */
+
+declare(strict_types=1);
+
+namespace Netzmacht\Contao\Leaflet\Frontend;
+
+use Netzmacht\Contao\PageContext\Exception\DeterminePageIdFailed;
+use Netzmacht\Contao\PageContext\Request\PageIdDeterminator as PageContextPageIdDeterminator;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Class ApiPageIdDeterminator
+ */
+final class PageIdDeterminator implements PageContextPageIdDeterminator
+{
+ /**
+ * {@inheritDoc}
+ */
+ public function match(Request $request): bool
+ {
+ return ($request->attributes->get('_leaflet_scope') === 'page' && $request->query->get('context') === 'page');
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @throws DeterminePageIdFailed When no context id is given.
+ */
+ public function determinate(Request $request): int
+ {
+ if (!$request->query->has('contextId')) {
+ throw new DeterminePageIdFailed('Could not determine page id for from request.');
+ }
+
+ return $request->query->getInt('contextId');
+ }
+}
diff --git a/src/Frontend/RequestUrl.php b/src/Frontend/RequestUrl.php
index df7de63..25c393a 100644
--- a/src/Frontend/RequestUrl.php
+++ b/src/Frontend/RequestUrl.php
@@ -21,6 +21,8 @@ use Netzmacht\Contao\Leaflet\Mapper\Request;
* Class RequestUrl creates the request url.
*
* @package Netzmacht\Contao\Leaflet\Request
+ *
+ * @deprecated
*/
class RequestUrl implements \JsonSerializable
{
@@ -89,6 +91,13 @@ class RequestUrl implements \JsonSerializable
{
$this->url = $url;
$this->hash = $hash;
+
+ // @codingStandardsIgnoreStart
+ @trigger_error(
+ 'Deprecated since 3.1.0 and will be removed in 4.0.0. Use The router instead.',
+ E_USER_DEPRECATED
+ );
+ // @codingStandardsIgnoreEnd
}
/**
diff --git a/src/Mapper/Layer/MarkersLayerMapper.php b/src/Mapper/Layer/MarkersLayerMapper.php
index 017e7e8..dc78d7e 100644
--- a/src/Mapper/Layer/MarkersLayerMapper.php
+++ b/src/Mapper/Layer/MarkersLayerMapper.php
@@ -13,7 +13,6 @@
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Contao\Model;
-use Netzmacht\Contao\Leaflet\Frontend\RequestUrl;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Mapper\GeoJsonMapper;
use Netzmacht\Contao\Leaflet\Mapper\Request;
@@ -24,6 +23,7 @@ use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Group\GeoJson;
use Netzmacht\LeafletPHP\Plugins\Omnivore\GeoJson as OmnivoreGeoJson;
use Netzmacht\LeafletPHP\Value\GeoJson\FeatureCollection;
+use Symfony\Component\Routing\RouterInterface;
/**
* Class MarkersLayerMapper maps the layer model to the markers definition.
@@ -46,14 +46,23 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
*/
private $repositoryManager;
+ /**
+ * Router.
+ *
+ * @var RouterInterface
+ */
+ private $router;
+
/**
* Construct.
*
* @param RepositoryManager $repositoryManager Repository manager.
+ * @param RouterInterface $router Router.
*/
- public function __construct(RepositoryManager $repositoryManager)
+ public function __construct(RepositoryManager $repositoryManager, RouterInterface $router)
{
$this->repositoryManager = $repositoryManager;
+ $this->router = $router;
parent::__construct();
}
@@ -93,7 +102,7 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
return [
$this->getElementId($model, $elementId),
- RequestUrl::create($model->id, null, null, $request),
+ $this->generateUrl((int) $model->id, $request),
[],
$layer,
];
@@ -101,7 +110,7 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
return [
$this->getElementId($model, $elementId),
- RequestUrl::create($model->id, null, null, $request),
+ $this->generateUrl((int) $model->id, $request),
];
}
@@ -182,4 +191,31 @@ class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
return $repository->findByFilter($model->id);
}
+
+ /**
+ * Generate the data url for a layer.
+ *
+ * @param int $layerId The layer id.
+ * @param Request|null $request The request.
+ *
+ * @return string
+ *
+ * @SuppressWarnings(PHPMD.Superglobals)
+ */
+ private function generateUrl(int $layerId, ?Request $request = null): string
+ {
+ $params = ['layerId' => $layerId];
+
+ if ($request && ($filter = $request->getFilter())) {
+ $params['filter'] = $filter::getName();
+ $params['values'] = $filter->toRequest();
+ }
+
+ if (isset($GLOBALS['objPage'])) {
+ $params['context'] = 'page';
+ $params['contextId'] = $GLOBALS['objPage']->id;
+ }
+
+ return $this->router->generate('leaflet_layer', $params, RouterInterface::ABSOLUTE_URL);
+ }
}
diff --git a/src/Mapper/Layer/VectorsLayerMapper.php b/src/Mapper/Layer/VectorsLayerMapper.php
index e5c7c97..2c692a3 100644
--- a/src/Mapper/Layer/VectorsLayerMapper.php
+++ b/src/Mapper/Layer/VectorsLayerMapper.php
@@ -14,7 +14,6 @@ namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Contao\Model;
use Contao\Model\Collection;
-use Netzmacht\Contao\Leaflet\Frontend\RequestUrl;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Mapper\GeoJsonMapper;
use Netzmacht\Contao\Leaflet\Mapper\Request;
@@ -25,6 +24,7 @@ use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Group\GeoJson;
use Netzmacht\LeafletPHP\Plugins\Omnivore\GeoJson as OmnivoreGeoJson;
use Netzmacht\LeafletPHP\Value\GeoJson\FeatureCollection;
+use Symfony\Component\Routing\RouterInterface;
/**
* Class VectorsLayerMapper maps the layer model for the Vectors layer definition.
@@ -47,14 +47,23 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
*/
private $repositoryManager;
+ /**
+ * Router.
+ *
+ * @var RouterInterface
+ */
+ private $router;
+
/**
* Construct.
*
* @param RepositoryManager $repositoryManager Repository manager.
+ * @param RouterInterface $router Router
*/
- public function __construct(RepositoryManager $repositoryManager)
+ public function __construct(RepositoryManager $repositoryManager, RouterInterface $router)
{
$this->repositoryManager = $repositoryManager;
+ $this->router = $router;
parent::__construct();
}
@@ -101,7 +110,7 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
return [
$this->getElementId($model, $elementId),
- RequestUrl::create($model->id, null, null, $request),
+ $this->generateUrl((int) $model->id, $request),
[],
$layer,
];
@@ -109,7 +118,7 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
return [
$this->getElementId($model, $elementId),
- RequestUrl::create($model->id, null, null, $request),
+ $this->generateUrl((int) $model->id, $request),
];
}
@@ -202,4 +211,31 @@ class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
$definition->setOnEachFeature(new Expression($model->onEachFeature));
}
}
+
+ /**
+ * Generate the data url for a layer.
+ *
+ * @param int $layerId The layer id.
+ * @param Request|null $request The request.
+ *
+ * @return string
+ *
+ * @SuppressWarnings(PHPMD.Superglobals)
+ */
+ private function generateUrl(int $layerId, ?Request $request = null): string
+ {
+ $params = ['layerId' => $layerId];
+
+ if ($request && ($filter = $request->getFilter())) {
+ $params['filter'] = $filter::getName();
+ $params['values'] = $filter->toRequest();
+ }
+
+ if (isset($GLOBALS['objPage'])) {
+ $params['context'] = 'page';
+ $params['contextId'] = $GLOBALS['objPage']->id;
+ }
+
+ return $this->router->generate('leaflet_layer', $params, RouterInterface::ABSOLUTE_URL);
+ }
}