Switch to PSR-4.

This commit is contained in:
David Molineus
2017-10-05 14:16:56 +02:00
parent e3344ffd4f
commit 827c746b0d
87 changed files with 4 additions and 6 deletions

View File

@@ -0,0 +1,195 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\LeafletPHP\Definition;
/**
* Class AbstractMapper is made for mapping Contao models to the definition.
*
* For custom sources besides Contao models use your own implementation of the mapper interface.
*
* @package Netzmacht\Contao\Leaflet\Mapper
*/
abstract class AbstractMapper implements Mapper
{
const VALUE_NOT_EMPTY = '__value_not_empty__';
const VALUE_EMPTY = '__value_empty__';
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = null;
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = null;
/**
* Options builder.
*
* @var OptionsBuilder
*/
protected $optionsBuilder;
/**
* Construct.
*/
public function __construct()
{
$this->optionsBuilder = new OptionsBuilder();
$this->initialize();
}
/**
* {@inheritdoc}
*/
public function handle(
$model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null,
Definition $parent = null
) {
$definition = $this->createInstance($model, $mapper, $filter, $elementId);
$this->optionsBuilder->build($definition, $model);
$this->build($definition, $model, $mapper, $filter, $parent);
return $definition;
}
/**
* {@inheritdoc}
*/
public function match($model, Filter $filter = null)
{
$modelClass = static::$modelClass;
return ($model instanceof $modelClass);
}
/**
* Initialize the mapper.
*
* @return void
*/
protected function initialize()
{
}
/**
* Use for specific build methods.
*
* @param Definition $definition The definition being built.
* @param \Model $model The model.
* @param DefinitionMapper $mapper The definition mapper.
* @param Filter|null $filter Optional request filter.
* @param Definition|null $parent The parent object.
*
* @return void
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
}
/**
* Create a new definition instance.
*
* @param \Model $model The model.
* @param DefinitionMapper $mapper The definition mapper.
* @param Filter $filter Optional request filter.
* @param string|null $elementId Optional element id.
*
* @return Definition
*/
protected function createInstance(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
$reflector = new \ReflectionClass($this->getClassName($model, $mapper, $filter));
$instance = $reflector->newInstanceArgs($this->buildConstructArguments($model, $mapper, $filter, $elementId));
return $instance;
}
/**
* Get construct arguments.
*
* @param \Model $model The model.
* @param DefinitionMapper $mapper The definition mapper.
* @param Filter $filter Optional request filter.
* @param string|null $elementId Optional element id.
*
* @return array
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
return array(
$this->getElementId($model, $elementId)
);
}
/**
* Get definition class name.
*
* @param \Model $model The model.
* @param DefinitionMapper $mapper The definition mapper.
* @param Filter $filter Optional request filter.
*
* @return string
*
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
protected function getClassName(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
return static::$definitionClass;
}
/**
* Create element id for the model.
*
* @param \Model $model The model being passed.
* @param string|null $elementId Optional forced id.
*
* @return string
*/
protected function getElementId(\Model $model, $elementId = null)
{
if ($elementId) {
return $elementId;
}
return $model->alias ?: (str_replace('tl_leaflet_', '', $model->getTable()) . '_' . $model->id);
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper;
use Netzmacht\Contao\Leaflet\Filter\Filter;
/**
* Class AbstractTypeMapper is the base mapper for tables containing different types of definitins.
*
* @package Netzmacht\Contao\Leaflet\Mapper
*/
abstract class AbstractTypeMapper extends AbstractMapper
{
/**
* The definition type.
*
* @var string
*/
protected static $type;
/**
* {@inheritdoc}
*/
public function match($model, Filter $filter = null)
{
return parent::match($model) && $model->type === static::$type;
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
use Netzmacht\Contao\Leaflet\Mapper\AbstractTypeMapper;
/**
* Class AbstractControlMapper is the base mapper for the control model.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Control
*/
class AbstractControlMapper extends AbstractTypeMapper
{
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\ControlModel';
/**
* {@inheritdoc}
*/
protected function initialize()
{
$this->optionsBuilder->addOption('position');
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Control\Attribution;
use Netzmacht\LeafletPHP\Definition\Map;
/**
* AttributionControlMapper maps the the attribution database definition to the definition class.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Control
*/
class AttributionControlMapper extends AbstractControlMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Control\Attribution';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'attribution';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder->addConditionalOption('prefix');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if (!$definition instanceof Attribution) {
return;
}
if ($model->disableDefault && $parent instanceof Map) {
$parent->setAttributionControl(false);
}
$attributions = deserialize($model->attributions, true);
foreach ($attributions as $attribution) {
$definition->addAttribution($attribution);
}
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
use Netzmacht\LeafletPHP\Definition;
/**
* Class FullscreenControlMapper.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Control
*/
class FullscreenControlMapper extends AbstractControlMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Plugins\FullScreen\FullScreenControl';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'fullscreen';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder
->addOption('forceSeparateButton', 'separate')
->addConditionalOption('title', 'title', 'buttonTitle')
->addOption('forcePseudoFullScreen', 'simulateFullScreen');
}
}

View File

@@ -0,0 +1,65 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\ControlModel;
/**
* Class LayersControlMapper maps the control model to the layers control definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Control
*/
class LayersControlMapper extends AbstractControlMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Control\Layers';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'layers';
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
$arguments = parent::buildConstructArguments($model, $mapper, $filter, $elementId);
$arguments[1] = array();
$arguments[2] = array();
/** @var ControlModel $model */
$collection = $model->findActiveLayers();
if ($collection) {
foreach ($collection as $layer) {
$argument = ($layer->controlMode === 'overlay') ? 2 : 1;
$arguments[$argument][] = $mapper->handle($layer, $filter);
}
}
return $arguments;
}
}

View File

@@ -0,0 +1,97 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\ControlModel;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Control\Zoom;
use Netzmacht\LeafletPHP\Plugins\Loading\LoadingControl;
use Netzmacht\LeafletPHP\Plugins\Loading\SpinJsLoadingControl;
/**
* Class LoadingControlMapper maps the control model to the loading control definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Control
*/
class LoadingControlMapper extends AbstractControlMapper
{
/**
* Layer type.
*
* @var string
*/
protected static $type = 'loading';
/**
* {@inheritdoc}
*/
protected function getClassName(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
if ($model->spinjs) {
return 'Netzmacht\LeafletPHP\Plugins\Loading\SpinJsLoadingControl';
}
return 'Netzmacht\LeafletPHP\Plugins\Loading\LoadingControl';
}
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder->addOption('separate');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof SpinJsLoadingControl && $model->spin) {
$config = json_decode($model->spin, true);
if (is_array($config)) {
$definition->setSpin($config);
}
}
if ($definition instanceof LoadingControl && !$definition->isSeparate() && $model->zoomControl) {
// Only assign if zoom control is activated and part of the map.
$control = ControlModel::findOneBy(
array('active=1', 'type=?', 'pid=?', 'id=?'),
array('zoom', $model->pid, $model->zoomControl)
);
if ($control) {
$control = $mapper->handle($control);
if ($control instanceof Zoom) {
// By default the loading control overrides the position of the zoom control. Deactivate it by
// overriding the position.
$definition->setPosition($control->getPosition());
$definition->setZoomControl($control);
}
}
}
}
}

View File

@@ -0,0 +1,44 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
/**
* Class ScaleControlMapper maps the database item of the type "scale" to the scale control.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Control
*/
class ScaleControlMapper extends AbstractControlMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Control\Scale';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'scale';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder->addOptions('maxWidth', 'metric', 'imperial', 'updateWhenIdle');
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Control;
/**
* Class ZoomControlMapper maps the zoom database definition to the zoom control.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Control
*/
class ZoomControlMapper extends AbstractControlMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Control\Zoom';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'zoom';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder
->addConditionalOption('zoomInText')
->addConditionalOption('zoomOutText')
->addConditionalOption('zoomInTitle')
->addConditionalOption('zoomOutTitle');
}
}

View File

@@ -0,0 +1,232 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper;
use Netzmacht\Contao\Leaflet\Event\BuildDefinitionEvent;
use Netzmacht\Contao\Leaflet\Event\ConvertToGeoJsonEvent;
use Netzmacht\Contao\Leaflet\Event\GetHashEvent;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Value\GeoJson\ConvertsToGeoJsonFeature;
use Netzmacht\LeafletPHP\Value\GeoJson\Feature;
use Netzmacht\LeafletPHP\Value\GeoJson\FeatureCollection;
use Netzmacht\LeafletPHP\Value\GeoJson\GeoJsonFeature;
use Symfony\Component\EventDispatcher\EventDispatcherInterface as EventDispatcher;
/**
* Class DefinitionMapper is the main mapper instance which contains all other mappers as children.
*
* @package Netzmacht\Contao\Leaflet\Mapper
*/
class DefinitionMapper
{
/**
* Lit of all registered mappers.
*
* @var Mapper[][]
*/
private $mappers = array();
/**
* The event dispatcher.
*
* @var EventDispatcher
*/
private $eventDispatcher;
/**
* Cache of mapped definitions.
*
* @var array
*/
private $mapped = array();
/**
* Construct.
*
* @param EventDispatcher $eventDispatcher The event dispatcher.
*/
public function __construct($eventDispatcher)
{
$this->eventDispatcher = $eventDispatcher;
}
/**
* Add a mapper.
*
* @param Mapper $mapper The mapper.
* @param int $priority The priority. The higher priorities get called first.
*
* @return $this
*/
public function register(Mapper $mapper, $priority = 0)
{
$this->mappers[$priority][] = $mapper;
krsort($this->mappers);
return $this;
}
/**
* Reset the internal cache.
*
* @return $this
*/
public function reset()
{
$this->mapped = array();
return $this;
}
/**
* Build a model.
*
* @param mixed $model The definition model.
* @param Filter $filter Optional request filter.
* @param string $elementId Optional element id. If none given the mapId or alias is used.
* @param Definition|null $parent Optional pass the parent object.
*
* @return Definition|null
*
* @throws \RuntimeException If model could not be mapped to a definition.
*/
public function handle($model, Filter $filter = null, $elementId = null, $parent = null)
{
$hash = $this->hash($model, $elementId);
if (!isset($this->mapped[$hash])) {
$mapper = $this->getMapper($model);
$definition = $mapper->handle($model, $this, $filter, $elementId, $parent);
if ($definition) {
$event = new BuildDefinitionEvent($definition, $model, $filter);
$this->eventDispatcher->dispatch($event::NAME, $event);
}
$this->mapped[$hash] = $definition;
}
return $this->mapped[$hash];
}
/**
* Build a model.
*
* @param mixed $model The definition model.
* @param Filter $filter Optional request filter.
*
* @return FeatureCollection|Feature|null
*
* @throws \RuntimeException If a model could not be mapped to the GeoJSON representation.
*/
public function handleGeoJson($model, Filter $filter = null)
{
$mapper = $this->getMapper($model);
if ($mapper instanceof GeoJsonMapper) {
return $mapper->handleGeoJson($model, $this, $filter);
}
throw new \RuntimeException(
sprintf(
'Mapper for model "%s::%s" is not a GeoJsonMapper',
$model->getTable(),
$model->{$model->getPk()}
)
);
}
/**
* Convert a definition to a geo json feature.
*
* @param Definition $definition The leaflet definition object.
* @param mixed $model The corresponding definition model.
*
* @return GeoJsonFeature
* @throws \RuntimeException If a definition type is not supported.
*/
public function convertToGeoJsonFeature(Definition $definition, $model)
{
if ($definition instanceof GeoJsonFeature) {
$feature = $definition;
} elseif ($definition instanceof ConvertsToGeoJsonFeature) {
$feature = $definition->toGeoJsonFeature();
} else {
throw new \RuntimeException(
sprintf(
'Definition of class "%s" could not be converted to a geo json feature.',
get_class($definition)
)
);
}
$event = new ConvertToGeoJsonEvent($definition, $feature, $model);
$this->eventDispatcher->dispatch($event::NAME, $event);
return $feature;
}
/**
* Get the hash of a model.
*
* @param mixed $model The definition model.
* @param string|null $elementId Optional defined extra element id.
*
* @return string
*
* @throws \RuntimeException If no hash was created.
*/
private function hash($model, $elementId = null)
{
$event = new GetHashEvent($model);
$this->eventDispatcher->dispatch($event::NAME, $event);
$hash = $event->getHash();
if (!$hash) {
throw new \RuntimeException('Could not create a hash');
}
if ($elementId) {
$hash .= '.' . $elementId;
}
return $hash;
}
/**
* Get the mapper for a definition model.
*
* @param mixed $model The data model.
*
* @return Mapper
* @throws \RuntimeException If the mapper could not be found.
*/
private function getMapper($model)
{
foreach ($this->mappers as $mappers) {
foreach ($mappers as $mapper) {
if ($mapper->match($model)) {
return $mapper;
}
}
}
throw new \RuntimeException(
sprintf(
'Could not build model "%s". No matching mappers found.',
$this->hash($model)
)
);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\LeafletPHP\Value\GeoJson\GeoJsonFeature;
/**
* Interface GeoJsonMapper describes mappers which can convert their definition to a GeoJSON representation.
*
* @package Netzmacht\Contao\Leaflet\Mapper
*/
interface GeoJsonMapper
{
/**
* Hanle the GeoJSON creation.
*
* @param \Model $model The model being mapped.
* @param DefinitionMapper $mapper The definition mapper.
* @param Filter $filter Optional request filter.
*
* @return GeoJsonFeature|null
*/
public function handleGeoJson(\Model $model, DefinitionMapper $mapper, Filter $filter = null);
}

View File

@@ -0,0 +1,39 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\Mapper\AbstractTypeMapper;
/**
* Class AbstractLayerMapper is the base mapper for the layer model.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class AbstractLayerMapper extends AbstractTypeMapper
{
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\LayerModel';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder->addOption('label', 'title');
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\LayerModel;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Group\LayerGroup;
use Netzmacht\LeafletPHP\Definition\Layer;
/**
* Class GroupLayerMapper maps the layer model to the group layer definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class GroupLayerMapper extends AbstractLayerMapper
{
/**
* Layer type.
*
* @var string
*/
protected static $type = 'group';
/**
* {@inheritdoc}
*/
protected function getClassName(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
if ($model->groupType === 'feature') {
return 'Netzmacht\LeafletPHP\Definition\Group\FeatureGroup';
}
return 'Netzmacht\LeafletPHP\Definition\Group\LayerGroup';
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if (!$definition instanceof LayerGroup) {
return;
}
$collection = LayerModel::findBy(
array('pid=?', 'active=1'),
array($model->id),
array('order' => 'sorting')
);
if ($collection) {
foreach ($collection as $layerModel) {
$layer = $mapper->handle($layerModel);
if ($layer instanceof Layer) {
$definition->addLayer($layer);
}
}
}
}
}

View File

@@ -0,0 +1,132 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\ContaoAssets;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\LayerModel;
use Netzmacht\Contao\Toolkit\View\Assets\AssetsManager;
use Netzmacht\JavascriptBuilder\Type\AnonymousFunction;
use Netzmacht\JavascriptBuilder\Type\Expression;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Layer;
use Netzmacht\LeafletPHP\Plugins\MarkerCluster\MarkerClusterGroup;
use Netzmacht\LeafletPHP\Plugins\Omnivore\OmnivoreLayer;
/**
* Class MarkerClusterLayerMapper maps the layer database model to the marker cluster definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class MarkerClusterLayerMapper extends AbstractLayerMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Plugins\MarkerCluster\MarkerClusterGroup';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'markercluster';
/**
* Assets manager.
*
* @var ContaoAssets
*/
private $assets;
/**
* MarkerClusterLayerMapper constructor.
*
* @param ContaoAssets $assets Assets manager.
*/
public function __construct(ContaoAssets $assets)
{
parent::__construct();
$this->assets = $assets;
}
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder
->addOptions('showCoverageOnHover', 'zoomToBoundsOnClick', 'spiderfyOnMaxZoom')
->addOption('removeOutsideVisibleBounds')
->addConditionalOption('maxClusterRadius')
->addConditionalOption('singleMarkerMode')
->addConditionalOption('animateAddingMarkers')
->addConditionalOption('disableClusteringAtZoom')
->addConditionalOption('spiderfyDistanceMultiplier');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter, $parent);
/** @var MarkerClusterGroup $definition */
if ($model->iconCreateFunction) {
$definition->setIconCreateFunction(new Expression($model->iconCreateFunction));
}
if ($model->polygonOptions) {
$definition->setPolygonOptions((array) json_decode($model->polygonOptions, true));
}
if (!$model->disableDefaultStyle) {
$this->assets->addStylesheet('assets/leaflet/libs/leaflet-markercluster/MarkerCluster.Default.css');
}
$collection = LayerModel::findBy(
array('pid=?', 'active=1'),
array($model->id),
array('order' => 'sorting')
);
if ($collection) {
foreach ($collection as $layerModel) {
$layer = $mapper->handle($layerModel);
if ($layer instanceof Layer) {
$definition->addLayer($layer);
if ($layer instanceof OmnivoreLayer) {
$callback = new AnonymousFunction();
$callback->addLine('layers.' . $definition->getId() . '.addLayers(this.getLayers())');
$layer->on('ready', $callback);
}
}
}
}
}
}

View File

@@ -0,0 +1,160 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Mapper\GeoJsonMapper;
use Netzmacht\Contao\Leaflet\Model\MarkerModel;
use Netzmacht\Contao\Leaflet\Frontend\RequestUrl;
use Netzmacht\JavascriptBuilder\Type\Expression;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Value\GeoJson\FeatureCollection;
use Netzmacht\LeafletPHP\Definition\Group\GeoJson;
/**
* Class MarkersLayerMapper maps the layer model to the markers definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class MarkersLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
{
/**
* Layer type.
*
* @var string
*/
protected static $type = 'markers';
/**
* {@inheritdoc}
*/
protected function getClassName(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
if ($model->deferred) {
return 'Netzmacht\LeafletPHP\Plugins\Omnivore\GeoJson';
}
return 'Netzmacht\LeafletPHP\Definition\Group\GeoJson';
}
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
if ($model->deferred) {
if ($model->pointToLayer || $model->boundsMode) {
$layer = new GeoJson($this->getElementId($model, $elementId));
if ($model->pointToLayer) {
$layer->setPointToLayer(new Expression($model->pointToLayer));
}
if ($model->boundsMode) {
$layer->setOption('boundsMode', $model->boundsMode);
}
return array(
$this->getElementId($model, $elementId),
RequestUrl::create($model->id, null, null, $filter),
array(),
$layer
);
}
return array(
$this->getElementId($model, $elementId),
RequestUrl::create($model->id, null, null, $filter)
);
}
return parent::buildConstructArguments($model, $mapper, $filter, $elementId);
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if ($definition instanceof GeoJson) {
if ($model->boundsMode) {
$definition->setOption('boundsMode', $model->boundsMode);
}
$collection = $this->loadMarkerModels($model);
if ($collection) {
foreach ($collection as $item) {
$marker = $mapper->handle($item);
$point = $mapper->convertToGeoJsonFeature($marker, $item);
if ($point) {
$definition->addData($point, true);
}
}
}
if ($model->pointToLayer) {
$definition->setPointToLayer(new Expression($model->pointToLayer));
}
}
}
/**
* {@inheritdoc}
*/
public function handleGeoJson(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
$feature = new FeatureCollection();
$collection = $this->loadMarkerModels($model, $filter);
if ($collection) {
foreach ($collection as $item) {
$marker = $mapper->handle($item);
$point = $mapper->convertToGeoJsonFeature($marker, $item);
if ($point) {
$feature->addFeature($point);
}
}
}
return $feature;
}
/**
* Load all layer markers.
*
* @param \Model $model The layer model.
* @param Filter $filter The request filter.
*
* @return \Model\Collection|null
*/
protected function loadMarkerModels(\Model $model, Filter $filter = null)
{
if ($model->boundsMode == 'fit') {
return MarkerModel::findByFilter($model->id, $filter);
}
return MarkerModel::findByFilter($model->id);
}
}

View File

@@ -0,0 +1,139 @@
<?php
/**
* @package netzmacht
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2016 netzmacht David Molineus. All rights reserved.
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Model;
use Netzmacht\Contao\Leaflet\Definition\Layer\OverpassLayer;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\IconModel;
use Netzmacht\JavascriptBuilder\Type\Expression;
use Netzmacht\LeafletPHP\Definition;
/**
* Class OverpassLayerMapper.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class OverpassLayerMapper extends AbstractLayerMapper
{
/**
* The definition type.
*
* @var string
*/
protected static $type = 'overpass';
/**
* The definition class.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\Contao\Leaflet\Definition\Layer\OverpassLayer';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder
->addOption('query', 'overpassQuery')
->addOption('minZoom')
->addOption('boundsMode')
->addOption('overpassEndpoint', 'endpoint');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if (!$definition instanceof OverpassLayer) {
return;
}
$amenityIconsMap = $this->buildAmenityIconsMap($model);
$definition->setOption('amenityIcons', $amenityIconsMap);
if ($model->pointToLayer) {
$definition->setPointToLayer(new Expression($model->pointToLayer));
}
if ($model->onEachFeature) {
$definition->setOnEachFeature(new Expression($model->onEachFeature));
}
if ($model->overpassPopup) {
$definition->setOption('overpassPopup', new Expression($model->overpassPopup));
}
}
/**
* Build the amenity icons map.
*
* @param Model $model Definition model.
*
* @return array
*/
protected function buildAmenityIconsMap(Model $model)
{
$amenityIconsMap = $this->filterAmenityIconsConfig($model->amenityIcons);
if ($amenityIconsMap) {
$collection = IconModel::findMultipleByIds(array_unique($amenityIconsMap));
$icons = [];
if ($collection) {
foreach ($collection as $iconModel) {
$icons[$iconModel->id] = $iconModel->alias ?: $iconModel->id;
}
foreach ($amenityIconsMap as $amenity => $iconId) {
if (isset($icons[$iconId])) {
$amenityIconsMap[$amenity] = $icons[$iconId];
}
}
}
}
return $amenityIconsMap;
}
/**
* Filter the amenity icons config.
*
* @param mixed $amenityIconsConfig Raw config from the db.
*
* @return array
*/
private function filterAmenityIconsConfig($amenityIconsConfig)
{
$amenityIconsConfig = deserialize($amenityIconsConfig, true);
$amenityIconsMap = [];
foreach ($amenityIconsConfig as $config) {
if (!$config['amenity'] || !$config['icon']) {
continue;
}
$amenityIconsMap[$config['amenity']] = $config['icon'];
}
return $amenityIconsMap;
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Mapper\OptionsBuilder;
use Netzmacht\LeafletPHP\Definition;
/**
* Class ProviderLayerMapper maps the layer model to the tile provider definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class ProviderLayerMapper extends AbstractLayerMapper
{
/**
* Layer type.
*
* @var string
*/
protected static $type = 'provider';
/**
* Registered providers.
*
* @var array
*/
private $providers;
/**
* Construct.
*
* @param array $providers Registered providers.
*/
public function __construct(array $providers)
{
$this->providers = $providers;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function getClassName(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
if (isset($this->providers[$model->tile_provider]['class'])) {
return $this->providers[$model->tile_provider]['class'];
}
return 'Netzmacht\LeafletPHP\Plugins\LeafletProviders\Provider';
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if (!empty($this->providers[$model->tile_provider]['options'])) {
OptionsBuilder::applyOptions(
$this->providers[$model->tile_provider]['options'],
$definition,
$model
);
}
}
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
return array(
$model->alias ?: ('layer_' . $model->id),
$model->tile_provider,
$model->tile_provider_variant ?: null
);
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\LayerModel;
use Netzmacht\LeafletPHP\Definition;
/**
* Class ReferenceLayerMapper maps an reference layer to another layer.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class ReferenceLayerMapper extends AbstractLayerMapper
{
/**
* Layer type.
*
* @var string
*/
protected static $type = 'reference';
/**
* {@inheritdoc}
*/
public function handle(
$model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null,
Definition $parent = null
) {
$reference = LayerModel::findByPk($model->reference);
if (!$reference || !$reference->active) {
return null;
}
$elementId = $model->standalone ? $this->getElementId($model, $elementId) : null;
return $mapper->handle($reference, $filter, $elementId);
}
}

View File

@@ -0,0 +1,105 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Raster\TileLayer;
use Netzmacht\LeafletPHP\Value\LatLngBounds;
/**
* Class TileLayerMapper maps the database model to the tile layer definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class TileLayerMapper extends AbstractLayerMapper
{
/**
* The definition class.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Raster\TileLayer';
/**
* The layer type.
*
* @var string
*/
protected static $type = 'tile';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder
->addConditionalOption('minZoom')
->addConditionalOption('maxZoom')
->addConditionalOption('maxNativeZoom')
->addConditionalOption('tileSize')
->addConditionalOption('subdomain')
->addConditionalOption('errorTileUrl')
->addOptions('attribution', 'tms', 'continuousWorld', 'noWrap', 'zoomReverse')
->addConditionalOption('zoomOffset')
->addConditionalOption('opacity')
->addOption('zIndex')
->addOptions('unloadvisibleTiles', 'updateWhenIdle', 'detectRetina', 'reuseTiles');
}
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
$arguments = parent::buildConstructArguments($model, $mapper, $filter, $elementId);
$arguments[] = $model->tileUrl;
return $arguments;
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter, $parent);
/** @var TileLayer $definition */
$filter = deserialize($model->bounds);
if ($filter[0] && $filter[1]) {
$filter = array_map(
function ($value) {
return explode(',', $value, 3);
},
$filter
);
$filter = LatLngBounds::fromArray($filter);
$definition->setBounds($filter);
}
}
}

View File

@@ -0,0 +1,180 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Layer;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Mapper\GeoJsonMapper;
use Netzmacht\Contao\Leaflet\Model\VectorModel;
use Netzmacht\Contao\Leaflet\Frontend\RequestUrl;
use Netzmacht\JavascriptBuilder\Type\Expression;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Value\GeoJson\FeatureCollection;
use Netzmacht\LeafletPHP\Definition\Group\GeoJson;
use Netzmacht\LeafletPHP\Definition\Vector;
/**
* Class VectorsLayerMapper maps the layer model for the Vectors layer definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Layer
*/
class VectorsLayerMapper extends AbstractLayerMapper implements GeoJsonMapper
{
/**
* Layer type.
*
* @var string
*/
protected static $type = 'vectors';
/**
* {@inheritdoc}
*/
protected function getClassName(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
if ($model->deferred) {
return 'Netzmacht\LeafletPHP\Plugins\Omnivore\GeoJson';
}
return 'Netzmacht\LeafletPHP\Definition\Group\GeoJson';
}
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
if ($model->deferred) {
$options = array();
if ($model->pointToLayer) {
$options['pointToLayer'] = new Expression($model->pointToLayer);
}
if ($model->onEachFeature) {
$options['onEachFeature'] = new Expression($model->onEachFeature);
}
if ($model->boundsMode) {
$options['boundsMode'] = $model->boundsMode;
}
if (!empty($options)) {
$layer = new GeoJson($this->getElementId($model, $elementId));
$layer->setOptions($options);
return array(
$this->getElementId($model, $elementId),
RequestUrl::create($model->id, null, null, $filter),
array(),
$layer
);
}
return array(
$this->getElementId($model, $elementId),
RequestUrl::create($model->id, null, null, $filter)
);
}
return parent::buildConstructArguments($model, $mapper, $filter, $elementId);
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if ($definition instanceof GeoJson) {
$collection = $this->loadVectorModels($model);
if ($model->boundsMode) {
$definition->setOption('boundsMode', $model->boundsMode);
}
if ($collection) {
foreach ($collection as $item) {
$vector = $mapper->handle($item);
$feature = $mapper->convertToGeoJsonFeature($vector, $item);
if ($feature) {
$definition->addData($feature, true);
}
}
}
$this->addCallbacks($definition, $model);
}
}
/**
* {@inheritdoc}
*/
public function handleGeoJson(\Model $model, DefinitionMapper $mapper, Filter $filter = null)
{
$definition = new FeatureCollection();
$collection = $this->loadVectorModels($model);
if ($collection) {
foreach ($collection as $item) {
$vector = $mapper->handle($item);
$feature = $mapper->convertToGeoJsonFeature($vector, $item);
if ($feature) {
$definition->addFeature($feature, true);
}
}
}
return $definition;
}
/**
* Load vector models.
*
* @param \Model $model The layer model.
*
* @return \Model\Collection|null
*/
protected function loadVectorModels(\Model $model)
{
return VectorModel::findActiveBy('pid', $model->id, array('order' => 'sorting'));
}
/**
* Add javascript callbacks.
*
* @param GeoJson $definition The definition.
* @param \Model $model The database model.
*
* @return void
*/
protected function addCallbacks(GeoJson $definition, \Model $model)
{
if ($model->pointToLayer) {
$definition->setPointToLayer(new Expression($model->pointToLayer));
}
if ($model->onEachFeature) {
$definition->setOnEachFeature(new Expression($model->onEachFeature));
}
}
}

240
src/Mapper/MapMapper.php Normal file
View File

@@ -0,0 +1,240 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Model\ControlModel;
use Netzmacht\Contao\Leaflet\Model\MapModel;
use Netzmacht\JavascriptBuilder\Type\Expression;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Control;
use Netzmacht\LeafletPHP\Definition\Layer;
use Netzmacht\LeafletPHP\Definition\Map;
/**
* Class MapMapper maps the database map model to the leaflet definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper
*/
class MapMapper extends AbstractMapper
{
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\MapModel';
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Map';
/**
* {@inheritdoc}
*/
protected function initialize()
{
$this->optionsBuilder
->addOptions('center', 'zoom', 'zoomControl')
->addOptions('dragging', 'touchZoom', 'scrollWheelZoom', 'doubleClickZoom', 'boxZoom', 'tap', 'keyboard')
->addOptions('trackResize', 'closeOnClick', 'bounceAtZoomLimits')
->addConditionalOptions('adjustZoomExtra', array('minZoom', 'maxZoom', 'zoomSnap', 'zoomDelta'))
->addConditionalOptions('keyboard', array('keyboardPanOffset', 'keyboardZoomOffset'));
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $map,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if ($map instanceof Map && $model instanceof MapModel) {
$this->buildCustomOptions($map, $model);
$this->buildControls($map, $model, $mapper, $filter);
$this->buildLayers($map, $model, $mapper, $filter);
$this->buildBoundsCalculation($map, $model);
$this->buildLocate($map, $model);
}
}
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
return array(
$this->getElementId($model, $elementId),
$this->getElementId($model, $elementId)
);
}
/**
* Build map custom options.
*
* @param Map $map The map being built.
* @param MapModel $model The map model.
*
* @return void
*/
protected function buildCustomOptions(Map $map, MapModel $model)
{
if ($model->options) {
$options = json_decode($model->options, true);
if (is_array($options)) {
$map->setOptions($options);
}
}
$map->setOption('dynamicLoad', (bool) $model->dynamicLoad);
}
/**
* Build map controls.
*
* @param Map $map The map being built.
* @param MapModel $model The map model.
* @param DefinitionMapper $mapper The definition mapper.
* @param Filter $filter Optional request filter.
*
* @return void
*/
private function buildControls(Map $map, MapModel $model, DefinitionMapper $mapper, Filter $filter = null)
{
$collection = ControlModel::findActiveBy('pid', $model->id, array('order' => 'sorting'));
if (!$collection) {
return;
}
foreach ($collection as $control) {
$control = $mapper->handle($control, $filter, null, $map);
if ($control instanceof Control) {
$control->addTo($map);
}
}
}
/**
* Build map layers.
*
* @param Map $map The map being built.
* @param MapModel $model The map model.
* @param DefinitionMapper $mapper Definition mapper.
* @param Filter $filter Optional request filter.
*
* @return void
*/
private function buildLayers(Map $map, MapModel $model, DefinitionMapper $mapper, Filter $filter = null)
{
$collection = $model->findActiveLayers();
if ($collection) {
foreach ($collection as $layer) {
if (!$layer->active) {
continue;
}
$layer = $mapper->handle($layer, $filter, null, $map);
if ($layer instanceof Layer) {
$layer->addTo($map);
}
}
}
}
/**
* Build map bounds calculations.
*
* @param Map $map The map being built.
* @param MapModel $model The map model.
*
* @return void
*/
private function buildBoundsCalculation(Map $map, MapModel $model)
{
$adjustBounds = deserialize($model->adjustBounds, true);
if (in_array('deferred', $adjustBounds)) {
$map->setOption('adjustBounds', true);
}
if ($model->boundsPadding) {
$value = array_map('intval', explode(',', $model->boundsPadding, 4));
if (count($value) === 4) {
$map->setOption('boundsPaddingTopLeft', [$value[0], $value[1]]);
$map->setOption('boundsPaddingBottomRight', [$value[2], $value[3]]);
} elseif (count($value) === 2) {
$map->setOption('boundsPadding', $value);
}
}
if (in_array('load', $adjustBounds)) {
$map->calculateFeatureBounds();
}
}
/**
* Build map bounds calculations.
*
* @param Map $map The map being built.
* @param MapModel $model The map model.
*
* @return void
*/
private function buildLocate(Map $map, MapModel $model)
{
if ($model->locate) {
$options = array();
$mapping = array(
'setView' => 'locateSetView',
'watch' => 'locateWatch',
'enableHighAccuracy' => 'enableHighAccuracy',
);
foreach ($mapping as $option => $property) {
if ($model->$property) {
$options[$option] = (bool) $model->$property;
}
}
$mapping = array(
'maxZoom' => 'locateMaxZoom',
'timeout' => 'locateTimeout',
'maximumAge' => 'locateMaximumAge',
);
foreach ($mapping as $option => $property) {
if ($model->$property) {
$options[$option] = (int) $model->$property;
}
}
$map->locate($options);
}
}
}

52
src/Mapper/Mapper.php Normal file
View File

@@ -0,0 +1,52 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\LeafletPHP\Definition;
/**
* Interface Mapper describes the Mapper which translates a given configuration to the Leaflet definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper
*/
interface Mapper
{
/**
* Map model to the definition.
*
* @param \Model|mixed $model The model being built. Usually a contao model, but can be anything.
* @param DefinitionMapper $mapper The definition builder.
* @param Filter $filter Optional filter bounds.
* @param string $elementId Optional element.
* @param Definition|null $parent Optional passed parent.
*
* @return Definition
*/
public function handle(
$model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null,
Definition $parent = null
);
/**
* Check if mapper is responsible for the model.
*
* @param \Model $model The model being build.
* @param Filter $filter Optional filter bounds.
*
* @return bool
*/
public function match($model, Filter $filter = null);
}

View File

@@ -0,0 +1,268 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\HasOptions;
/**
* Class OptionsBuilder handles the option mapping between the database model and the definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper
*/
class OptionsBuilder
{
const VALUE_NOT_EMPTY = '__value_not_empty__';
const VALUE_EMPTY = '__value_empty__';
/**
* Options mapping.
*
* @var array
*/
private $options = array();
/**
* Conditional option mapping.
*
* @var array
*/
private $conditional = array();
/**
* Add a option mapping.
*
* @param string $option Name of the option.
* @param string $mapping Mapping column name. Set if column name differs.
*
* @return $this
*/
public function addOption($option, $mapping = null)
{
if (!isset($this->options[$option])) {
$this->options[$option] = $this->getMapping($option, $mapping);
}
return $this;
}
/**
* Add options mapping.
*
* @param array|mixed $options List of option names.
*
* @return $this
*/
public function addOptions($options)
{
$arguments = func_get_args();
if (count($arguments) > 1) {
$options = $arguments;
}
foreach ($options as $key => $value) {
if (is_numeric($key)) {
$this->addOption($value);
} else {
$this->addOption($key, $value);
}
}
return $this;
}
/**
* Add a conditional option.
*
* @param string $column Condition column.
* @param string $option Option name.
* @param null $mapping Mapping column name.
* @param mixed $value Value of the conditional column.
*
* @return $this
*/
public function addConditionalOption($column, $option = null, $mapping = null, $value = self::VALUE_NOT_EMPTY)
{
$option = $option ?: $column;
if (!isset($this->conditional[$column][$value][$option])) {
$this->conditional[$column][$value][$option] = $this->getMapping($option, $mapping);
}
return $this;
}
/**
* Add a conditional options.
*
* @param string $column Condition column.
* @param array $options Option names.
* @param mixed $value Value of the conditional column.
*
* @return $this
*/
public function addConditionalOptions($column, array $options, $value = self::VALUE_NOT_EMPTY)
{
foreach ($options as $key => $option) {
if (is_numeric($key)) {
$this->addConditionalOption($column, $option, null, $value);
} else {
$this->addConditionalOption($column, $key, $option, $value);
}
}
return $this;
}
/**
* Build options and conditional options.
*
* @param Definition $definition The definition being built.
* @param \Model $model The model.
*
* @return $this
*/
public function build($definition, $model)
{
$this->buildOptions($definition, $model);
$this->buildConditionals($definition, $model);
return $this;
}
/**
* Build options.
*
* @param Definition $definition The definition being built.
* @param \Model $model The model.
*
* @return void
*/
private function buildOptions($definition, $model)
{
$this->applyOptions($this->options, $definition, $model);
}
/**
* Build conditional options.
*
* @param Definition $definition The definition being built.
* @param \Model $model The model.
*
* @return void
*/
private function buildConditionals($definition, \Model $model)
{
foreach ($this->conditional as $column => $conditions) {
foreach ($conditions as $value => $options) {
if ($value === static::VALUE_EMPTY && empty($model->$column)) {
$this->applyOptions($options, $definition, $model);
} elseif ($value === static::VALUE_NOT_EMPTY && !empty($model->$column)) {
$this->applyOptions($options, $definition, $model);
} elseif ($model->$column == $value) {
$this->applyOptions($options, $definition, $model);
}
}
}
}
/**
* Get the mapping column.
*
* @param string $option Option name.
* @param string|null $mapping Mapping column.
*
* @return string
*/
private function getMapping($option, $mapping)
{
if ($mapping === null) {
return $option;
}
return $mapping;
}
/**
* Apply options from the model to the definition.
*
* @param array $options The options.
* @param Definition $definition The definition being built.
* @param \Model $model The model.
*
* @return void
*/
public static function applyOptions($options, $definition, $model)
{
foreach ($options as $option => $mapping) {
$default = static::getDefaultOption($option, $definition);
if ($model->$mapping === '1' || $model->$mapping === '') {
if (((bool) $model->$mapping) !== $default) {
static::applyOption($option, $model->$mapping, $definition);
}
} elseif (is_numeric($default)) {
if ($model->$mapping != $default) {
static::applyOption($option, $model->$mapping, $definition);
}
} elseif ($model->$mapping !== $default) {
static::applyOption($option, $model->$mapping, $definition);
}
}
}
/**
* Apply an option.
*
* @param string $option The option name.
* @param mixed $value The option value.
* @param Definition $definition The definition.
*
* @return void
*/
private static function applyOption($option, $value, $definition)
{
$setter = 'set' . ucfirst($option);
if (method_exists($definition, $setter)) {
$definition->$setter($value);
} elseif ($definition instanceof HasOptions) {
$definition->setOption($option, $value);
}
}
/**
* Get default option value.
*
* @param string $option The option name.
* @param Definition $definition The definition being built.
*
* @return mixed
*/
private static function getDefaultOption($option, $definition)
{
$keys = array('has', 'is', 'get');
$suffix = ucfirst($option);
foreach ($keys as $key) {
$method = $key . $suffix;
if (method_exists($definition, $method)) {
return $definition->$method();
}
}
return null;
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Style;
use Netzmacht\Contao\Leaflet\Mapper\AbstractTypeMapper;
/**
* Class AbstractStyleMapper is the base mapper for the style model.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Style
*/
abstract class AbstractStyleMapper extends AbstractTypeMapper
{
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\StyleModel';
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Style;
use Netzmacht\LeafletPHP\Definition;
/**
* Class FixedStyleMapper maps the fixed style to the corresponding definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Style
*/
class FixedStyleMapper extends AbstractStyleMapper
{
/**
* Definition class.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\Contao\Leaflet\Definition\Style\FixedStyle';
/**
* Style type.
*
* @var string
*/
protected static $type = 'fixed';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder
->addOptions('stroke', 'weight', 'opacity', 'clickable', 'className')
->addConditionalOption('color')
->addConditionalOption('lineCap')
->addConditionalOption('lineJoin')
->addConditionalOption('dashArray')
->addConditionalOptions('fill', array('fillColor', 'fillOpacity'))
->addOption('fill');
}
}

View File

@@ -0,0 +1,37 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Type;
use Netzmacht\Contao\Leaflet\Mapper\AbstractTypeMapper;
/**
* Class AbstractIconMapper is the base mapper for the icon model.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Type
*/
class AbstractIconMapper extends AbstractTypeMapper
{
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\IconModel';
/**
* {@inheritdoc}
*/
protected function initialize()
{
$this->optionsBuilder->addConditionalOption('className');
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Type;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Type\DivIcon;
/**
* Class DivIconMapper maps the icon model to the div icon definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Type
*/
class DivIconMapper extends AbstractIconMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Type\DivIcon';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'div';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder->addOption('html');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof DivIcon && $model->iconSize) {
$definition->setIconSize(explode(',', $model->iconSize, 2));
}
}
}

View File

@@ -0,0 +1,66 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Type;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Type\DivIcon;
/**
* Class DivIconMapper maps the icon model to the div icon definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Type
*/
class ExtraMarkersIconMapper extends AbstractIconMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Plugins\ExtraMarkers\ExtraMarkersIcon';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'extra';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder->addOptions(['icon', 'iconColor', 'markerColor', 'shape', 'number', 'prefix']);
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof DivIcon && $model->iconSize) {
$definition->setIconSize(explode(',', $model->iconSize, 2));
}
}
}

View File

@@ -0,0 +1,158 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Type;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\IconModel;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Type\ImageIcon;
/**
* Class ImageIconMapper maps the icon model to the image icon definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Type
*/
class ImageIconMapper extends AbstractIconMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Type\ImageIcon';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'image';
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
$arguments = parent::buildConstructArguments($model, $mapper, $filter, $elementId);
if ($model->iconImage) {
$file = \FilesModel::findByUuid($model->iconImage);
if ($file) {
$arguments[] = $file->path;
}
}
return $arguments;
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if ($definition instanceof ImageIcon) {
$this->addIcon($definition, $model);
$this->addShadow($definition, $model);
}
}
/**
* Add icon image.
*
* @param ImageIcon $definition The icon definition.
* @param IconModel $model The model.
*
* @return void
*/
private function addIcon(ImageIcon $definition, IconModel $model)
{
if ($model->iconImage) {
$file = \FilesModel::findByUuid($model->iconImage);
if ($file) {
$definition->setIconUrl($file->path);
$file = new \File($file->path);
$definition->setIconSize(array($file->width, $file->height));
if (!$model->iconAnchor) {
$definition->setIconAnchor(array($file->width / 2, $file->height));
}
if (!$model->popupAnchor) {
$definition->setPopupAnchor(array(0, 8 - $file->height));
}
}
}
if ($model->iconAnchor) {
$definition->setIconAnchor(array_map('intval', explode(',', $model->iconAnchor)));
}
if ($model->iconRetinaImage) {
$file = \FilesModel::findByUuid($model->iconRetinaImage);
if ($file) {
$definition->setIconRetinaUrl($file->path);
}
}
}
/**
* Add shadow if defined.
*
* @param ImageIcon $definition The icon definition.
* @param IconModel $model The model.
*
* @return void
*/
private function addShadow(ImageIcon $definition, $model)
{
if ($model->shadowImage) {
$file = \FilesModel::findByUuid($model->shadowImage);
if ($file) {
$definition->setShadowUrl($file->path);
$file = new \File($file->path);
$definition->setShadowSize(array($file->width, $file->height));
if (!$model->shadowAnchor) {
$definition->setShadowAnchor(array($file->width / 2, $file->height));
}
}
}
if ($model->shadowAnchor) {
$definition->setShadowAnchor(array_map('intval', explode(',', $model->shadowAnchor)));
}
if ($model->shadowRetinaImage) {
$file = \FilesModel::findByUuid($model->shadowRetinaImage);
if ($file) {
$definition->setShadowRetinaUrl($file->path);
}
}
}
}

View File

@@ -0,0 +1,137 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\UI;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Frontend\ValueFilter;
use Netzmacht\Contao\Leaflet\Mapper\AbstractMapper;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\IconModel;
use Netzmacht\Contao\Leaflet\Model\PopupModel;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Type\ImageIcon;
use Netzmacht\LeafletPHP\Definition\UI\Marker;
use Netzmacht\LeafletPHP\Definition\UI\Popup;
/**
* Class MarkerMapper maps the marker model to the marker definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\UI
*/
class MarkerMapper extends AbstractMapper
{
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\MarkerModel';
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\UI\Marker';
/**
* Frontend filter.
*
* @var ValueFilter
*/
protected $valueFilter;
/**
* Construct.
*
* @param ValueFilter $valueFilter Frontend filter.
*/
public function __construct(ValueFilter $valueFilter)
{
parent::__construct();
$this->valueFilter = $valueFilter;
}
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
$arguments = parent::buildConstructArguments($model, $mapper, $filter, $elementId);
$arguments[] = array($model->latitude, $model->longitude, $model->altitude ?: null) ?: null;
return $arguments;
}
/**
* {@inheritdoc}
*/
protected function initialize()
{
$this->optionsBuilder
->addConditionalOption('tooltip', 'title', 'tooltip')
->addConditionalOption('alt')
->addConditionalOption('zIndexOffset')
->addOptions('clickable', 'keyboard', 'draggable');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
if ($definition instanceof Marker) {
if ($model->addPopup) {
$popup = null;
$content = $this->valueFilter->filter($model->popupContent);
if ($model->popup) {
$popupModel = PopupModel::findActiveByPK($model->popup);
if ($popupModel) {
$popup = $mapper->handle($popupModel, $filter, null, $definition);
}
}
if ($popup instanceof Popup) {
$definition->bindPopup($content, $popup->getOptions());
} else {
$definition->bindPopup($content);
}
}
if ($model->customIcon) {
$iconModel = IconModel::findBy(
array('id=?', 'active=1'),
array($model->icon),
array('return' => 'Model')
);
if ($iconModel) {
/** @var ImageIcon $icon */
$icon = $mapper->handle($iconModel);
$definition->setIcon($icon);
}
}
}
}
}

View File

@@ -0,0 +1,119 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\UI;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\AbstractMapper;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\PopupModel;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\UI\Popup;
/**
* Class PopupMapper.
*
* @package Netzmacht\Contao\Leaflet\Mapper\UI
*/
class PopupMapper extends AbstractMapper
{
/**
* The definition class.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\UI\Popup';
/**
* The model class.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\PopupModel';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder
->addConditionalOption('maxWidth')
->addConditionalOption('minWidth')
->addConditionalOption('maxHeight')
->addConditionalOption('className')
->addOptions('autoPan', 'keepInView', 'closeButton', 'zoomAnimation');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter, $parent);
/** @var Popup $definition */
/** @var PopupModel $model */
$this->deserializePoint('offset', $definition, $model);
if ($model->autoPan) {
$padding = array_map(
function ($value) {
return array_map('intval', trimsplit(',', $value));
},
deserialize($model->autoPanPadding, true)
);
if ($padding[0] === $padding[1]) {
if (!empty($padding[0])) {
$definition->setAutoPanPadding($padding[0]);
}
} else {
if ($padding[0]) {
$definition->setAutoPanPaddingTopLeft($padding[0]);
}
if ($padding[1]) {
$definition->setAutoPanPaddingBottomRight($padding[1]);
}
}
}
if (!$model->closeOnClick) {
$definition->setCloseOnClick(false);
}
}
/**
* Deserialize point value and add it as option.
*
* @param string $option The option name.
* @param Popup $definition The popup definition.
* @param PopupModel $model The popup model.
*
* @return $this
*/
protected function deserializePoint($option, Popup $definition, PopupModel $model)
{
if ($model->$option) {
$setter = 'set' . ucfirst($option);
$definition->$setter(array_map('intval', explode(',', $model->$option, 2)));
}
return $this;
}
}

View File

@@ -0,0 +1,121 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
use Netzmacht\Contao\Leaflet\Definition\Style;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Frontend\ValueFilter;
use Netzmacht\Contao\Leaflet\Mapper\AbstractTypeMapper;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\Contao\Leaflet\Model\PopupModel;
use Netzmacht\Contao\Leaflet\Model\StyleModel;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\HasPopup;
use Netzmacht\LeafletPHP\Definition\UI\Popup;
use Netzmacht\LeafletPHP\Definition\Vector\Path;
/**
* Class AbstractVectorMapper is the base class for the vector model definition mapping.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class AbstractVectorMapper extends AbstractTypeMapper
{
/**
* Class of the model being build.
*
* @var string
*/
protected static $modelClass = 'Netzmacht\Contao\Leaflet\Model\VectorModel';
/**
* Frontend filter.
*
* @var ValueFilter
*/
protected $valueFilter;
/**
* Construct.
*
* @param ValueFilter $valueFilter Frontend filter.
*/
public function __construct(ValueFilter $valueFilter)
{
parent::__construct();
$this->valueFilter = $valueFilter;
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof Path && $model->style) {
$styleModel = StyleModel::findActiveByPK($model->style);
if ($styleModel) {
$style = $mapper->handle($styleModel);
if ($style instanceof Style) {
$style->apply($definition);
}
}
}
$this->buildPopup($definition, $model, $mapper, $filter);
}
/**
* Build the popup.
*
* @param Definition $definition The definition.
* @param \Model $model The model.
* @param DefinitionMapper $mapper The definition mapper.
* @param Filter $filter The filter.
*
* @return void
*/
protected function buildPopup(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null
) {
if ($definition instanceof HasPopup && $model->addPopup) {
$popup = null;
$content = $this->valueFilter->filter($model->popupContent);
if ($model->popup) {
$popupModel = PopupModel::findActiveByPK($model->popup);
if ($popupModel) {
$popup = $mapper->handle($popupModel, $filter, null, $definition);
}
}
if ($popup instanceof Popup) {
$definition->bindPopup($content, $popup->getOptions());
} else {
$definition->bindPopup($content);
}
}
}
}

View File

@@ -0,0 +1,68 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Vector\CircleMarker;
use Netzmacht\LeafletPHP\Value\LatLng;
use Netzmacht\LeafletPHP\Definition\Vector\Circle;
/**
* Class CircleMapper maps the database model to the circle definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class CircleMapper extends AbstractVectorMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Vector\Circle';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'circle';
/**
* {@inheritdoc}
*/
protected function initialize()
{
parent::initialize();
$this->optionsBuilder->addOption('radius');
}
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof CircleMarker) {
$definition->setLatLng(LatLng::fromString($model->coordinates));
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
/**
* Class CircleMarkerMapper maps the database model to the circle marker definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class CircleMarkerMapper extends CircleMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Vector\CircleMarker';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'circleMarker';
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Vector\Polygon;
/**
* Class MultiPolygonMapper maps the multi polygon database model to its definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class MultiPolygonMapper extends MultiPolylineMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Vector\Polygon';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'multiPolygon';
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof Polygon) {
$this->createLatLngs($definition, $model);
}
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Definition\Vector\Polyline;
use Netzmacht\LeafletPHP\Value\LatLng;
/**
* Class MultiPolylineMapper maps the databse model it the multi polyline definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class MultiPolylineMapper extends AbstractVectorMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Vector\Polyline';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'multiPolyline';
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof Polyline) {
$this->createLatLngs($definition, $model);
}
}
/**
* Create lat lngs for the definition.
*
* @param Polyline $definition The multi polyline.
* @param \Model $model The definition model.
*
* @return void
*/
protected function createLatLngs(Polyline $definition, \Model $model)
{
foreach (deserialize($model->multiData, true) as $ring => $data) {
$latLngs = array_map(
function ($row) {
return LatLng::fromString($row);
},
explode("\n", $data)
);
$definition->addLatLngs($latLngs, $ring);
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
/**
* Class PolygonMapper maps the database model to the polygon definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class PolygonMapper extends PolylineMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Vector\Polygon';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'polygon';
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Value\LatLng;
use Netzmacht\LeafletPHP\Definition\Vector\Polyline;
/**
* Class PolylineMapper maps the database model to the polyline definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class PolylineMapper extends AbstractVectorMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Vector\Polyline';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'polyline';
/**
* {@inheritdoc}
*/
protected function build(
Definition $definition,
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
Definition $parent = null
) {
parent::build($definition, $model, $mapper, $filter);
if ($definition instanceof Polyline) {
array_map(
function ($row) use ($definition) {
$definition->addLatLng(LatLng::fromString($row));
},
explode("\n", $model->data)
);
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
/**
* @package contao-leaflet-maps
* @author David Molineus <david.molineus@netzmacht.de>
* @copyright 2014-2016 netzmacht David Molineus
* @license LGPL 3.0
* @filesource
*
*/
namespace Netzmacht\Contao\Leaflet\Mapper\Vector;
use Netzmacht\Contao\Leaflet\Filter\Filter;
use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper;
use Netzmacht\LeafletPHP\Definition;
use Netzmacht\LeafletPHP\Value\LatLng;
use Netzmacht\LeafletPHP\Value\LatLngBounds;
/**
* Class RectangleMapper maps a database model to its rectangle vector definition.
*
* @package Netzmacht\Contao\Leaflet\Mapper\Vector
*/
class RectangleMapper extends AbstractVectorMapper
{
/**
* Class of the definition being created.
*
* @var string
*/
protected static $definitionClass = 'Netzmacht\LeafletPHP\Definition\Vector\Rectangle';
/**
* Layer type.
*
* @var string
*/
protected static $type = 'rectangle';
/**
* {@inheritdoc}
*/
protected function buildConstructArguments(
\Model $model,
DefinitionMapper $mapper,
Filter $filter = null,
$elementId = null
) {
$latLngs = array_map(
function ($latLng) {
return LatLng::fromString($latLng);
},
deserialize($model->bounds, true)
);
$arguments = parent::buildConstructArguments($model, $mapper, $filter, $elementId);
$arguments[] = new LatLngBounds($latLngs[0], $latLngs[1]);
return $arguments;
}
}