mirror of
https://github.com/netzmacht/contao-leaflet-maps.git
synced 2025-11-28 19:13:55 +01:00
Implement custom route for data request to prevent partial rendering of the page and it's possible issues (f.e. form captcha changes) (Close #49).
This commit is contained in:
@@ -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"
|
||||
|
||||
15
js/Contao.js
15
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.
|
||||
*
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 }
|
||||
|
||||
|
||||
11
src/Bundle/Resources/config/routing.yml
Normal file
11
src/Bundle/Resources/config/routing.yml
Normal file
@@ -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+
|
||||
@@ -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'
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -90,7 +90,7 @@ class EncoderSubscriber implements EventSubscriberInterface
|
||||
$value = $event->getValue();
|
||||
$encoder = $event->getEncoder();
|
||||
$template = 'L.contao.%s(%s, %s, %s, %s, map);';
|
||||
$method = 'loadFile';
|
||||
$method = 'loadUrl';
|
||||
|
||||
if ($value instanceof OmnivoreLayer) {
|
||||
$url = $value->getUrl();
|
||||
|
||||
103
src/Frontend/Action/LayerDataAction.php
Normal file
103
src/Frontend/Action/LayerDataAction.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Leaflet maps for Contao CMS.
|
||||
*
|
||||
* @package contao-leaflet-maps
|
||||
* @author David Molineus <david.molineus@netzmacht.de>
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
47
src/Frontend/PageIdDeterminator.php
Normal file
47
src/Frontend/PageIdDeterminator.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Leaflet maps for Contao CMS.
|
||||
*
|
||||
* @package contao-leaflet-maps
|
||||
* @author David Molineus <david.molineus@netzmacht.de>
|
||||
* @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');
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user