From 633be6a2bc8287116029583afdd8139259750555 Mon Sep 17 00:00:00 2001 From: David Molineus Date: Mon, 29 Dec 2014 12:17:40 +0100 Subject: [PATCH] Ongoing development. --- composer.json | 4 +- module/assets/.htaccess | 7 + module/assets/img/leaflet.png | Bin 0 -> 3203 bytes module/assets/js/contao-leaflet.js | 23 ++ module/config/autoload.php | 8 + module/config/config.php | 73 ++++- module/config/event_subscribers.php | 5 + module/config/services.php | 72 ++++ module/dca/tl_content.php | 22 ++ module/dca/tl_leaflet_map.php | 201 ++++++++++-- module/languages/en/modules.php | 4 + module/languages/en/tl_leaflet_map.php | 49 +++ module/templates/be_leaflet_geocode.html5 | 58 ++++ module/templates/ce_leaflet_map.html5 | 6 + src/Netzmacht/Contao/Leaflet/Boot.php | 89 +++++ src/Netzmacht/Contao/Leaflet/ContaoAssets.php | 82 +++++ src/Netzmacht/Contao/Leaflet/Dca/Content.php | 40 +++ src/Netzmacht/Contao/Leaflet/Dca/Leaflet.php | 63 ++++ .../Leaflet/Event/BuildDefinitionEvent.php | 71 ++++ .../Leaflet/Event/GetJavascriptEvent.php | 71 ++++ .../Event/InitializeDefinitionMapperEvent.php | 50 +++ .../Event/InitializeEventDispatcherEvent.php | 52 +++ .../Event/InitializeLeafletBuilderEvent.php | 52 +++ .../Contao/Leaflet/LeafletMapElement.php | 62 ++++ src/Netzmacht/Contao/Leaflet/MapService.php | 117 +++++++ .../Contao/Leaflet/Mapper/AbstractMapper.php | 308 ++++++++++++++++++ .../Leaflet/Mapper/DefinitionMapper.php | 116 +++++++ .../Contao/Leaflet/Mapper/MapMapper.php | 106 ++++++ .../Contao/Leaflet/Mapper/Mapper.php | 36 ++ .../Contao/Leaflet/Model/MapModel.php | 19 ++ .../Leaflet/Subscriber/BootSubscriber.php | 117 +++++++ .../Leaflet/Subscriber/EncoderSubscriber.php | 97 ++++++ 32 files changed, 2057 insertions(+), 23 deletions(-) create mode 100644 module/assets/.htaccess create mode 100644 module/assets/img/leaflet.png create mode 100644 module/assets/js/contao-leaflet.js create mode 100644 module/config/autoload.php create mode 100644 module/config/event_subscribers.php create mode 100644 module/config/services.php create mode 100644 module/dca/tl_content.php create mode 100644 module/languages/en/modules.php create mode 100644 module/languages/en/tl_leaflet_map.php create mode 100644 module/templates/be_leaflet_geocode.html5 create mode 100644 module/templates/ce_leaflet_map.html5 create mode 100644 src/Netzmacht/Contao/Leaflet/Boot.php create mode 100644 src/Netzmacht/Contao/Leaflet/ContaoAssets.php create mode 100644 src/Netzmacht/Contao/Leaflet/Dca/Content.php create mode 100644 src/Netzmacht/Contao/Leaflet/Dca/Leaflet.php create mode 100644 src/Netzmacht/Contao/Leaflet/Event/BuildDefinitionEvent.php create mode 100644 src/Netzmacht/Contao/Leaflet/Event/GetJavascriptEvent.php create mode 100644 src/Netzmacht/Contao/Leaflet/Event/InitializeDefinitionMapperEvent.php create mode 100644 src/Netzmacht/Contao/Leaflet/Event/InitializeEventDispatcherEvent.php create mode 100644 src/Netzmacht/Contao/Leaflet/Event/InitializeLeafletBuilderEvent.php create mode 100644 src/Netzmacht/Contao/Leaflet/LeafletMapElement.php create mode 100644 src/Netzmacht/Contao/Leaflet/MapService.php create mode 100644 src/Netzmacht/Contao/Leaflet/Mapper/AbstractMapper.php create mode 100644 src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php create mode 100644 src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php create mode 100644 src/Netzmacht/Contao/Leaflet/Mapper/Mapper.php create mode 100644 src/Netzmacht/Contao/Leaflet/Model/MapModel.php create mode 100644 src/Netzmacht/Contao/Leaflet/Subscriber/BootSubscriber.php create mode 100644 src/Netzmacht/Contao/Leaflet/Subscriber/EncoderSubscriber.php diff --git a/composer.json b/composer.json index 95221a5..79eef63 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,9 @@ "contao-community-alliance/event-dispatcher":"~1.0", "netzmacht/php-javascript-builder": "~1.0", "netzmacht/php-leaflet": "dev-master", - "bit3/contao-meta-palettes": "~1.5" + "bit3/contao-meta-palettes": "~1.5", + "menatwork/contao-multicolumnwizard": "~3.2", + "doctrine/cache": "~1.0" }, "require-dev":{ "netzmacht/contao-build-tools": "1.0.x-dev" diff --git a/module/assets/.htaccess b/module/assets/.htaccess new file mode 100644 index 0000000..28cc359 --- /dev/null +++ b/module/assets/.htaccess @@ -0,0 +1,7 @@ + + Order allow,deny + Allow from all + + + Require all granted + \ No newline at end of file diff --git a/module/assets/img/leaflet.png b/module/assets/img/leaflet.png new file mode 100644 index 0000000000000000000000000000000000000000..51c29cd944c0e26dceb2fefac82495297e5808a0 GIT binary patch literal 3203 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 'system/modules/leaflet/templates', + 'be_leaflet_geocode' => 'system/modules/leaflet/templates', + ) +); diff --git a/module/config/config.php b/module/config/config.php index fb0e613..5c25662 100644 --- a/module/config/config.php +++ b/module/config/config.php @@ -1,5 +1,76 @@ array('tl_leaflet_map') + 'tables' => array('tl_leaflet_map'), + 'icon' => 'system/modules/leaflet/assets/img/leaflet.png', +); + +/* + * Content elements. + */ +$GLOBALS['TL_CTE']['includes']['leaflet'] = 'Netzmacht\Contao\Leaflet\LeafletMapElement'; + + +/* + * Models. + */ +$GLOBALS['TL_MODELS']['tl_leaflet_map'] = 'Netzmacht\Contao\Leaflet\Model\MapModel'; + + +/* + * Leaflet mappers. + * + * Mappers do the translations between the database models and the leaflet definition. + */ +$GLOBALS['LEAFLET_MAPPERS'] = array(); +$GLOBALS['LEAFLET_MAPPERS'][] = 'Netzmacht\Contao\Leaflet\Mapper\MapMapper'; + + +/* + * Leaflet encoders. + * + * The encoders transforms the definitions into javascript. The encoders has to be an implementation of the + * EventDispatcherInterface of the event dispatcher. + * + * You can define the encoders using the syntax of the cca event dispatcher implementation. + * + * @see https://github.com/contao-community-alliance/event-dispatcher#event-subscriber-per-configuration + */ +$GLOBALS['LEAFLET_ENCODERS'] = array(); +$GLOBALS['LEAFLET_ENCODERS'][] = 'Netzmacht\Javascript\Subscriber\EncoderSubscriber'; +$GLOBALS['LEAFLET_ENCODERS'][] = 'Netzmacht\LeafletPHP\Encoder\MapEncoder'; +$GLOBALS['LEAFLET_ENCODERS'][] = 'Netzmacht\LeafletPHP\Encoder\ControlEncoder'; +$GLOBALS['LEAFLET_ENCODERS'][] = 'Netzmacht\LeafletPHP\Encoder\GroupEncoder'; +$GLOBALS['LEAFLET_ENCODERS'][] = 'Netzmacht\LeafletPHP\Encoder\RasterEncoder'; +$GLOBALS['LEAFLET_ENCODERS'][] = 'Netzmacht\LeafletPHP\Encoder\VectorEncoder'; +$GLOBALS['LEAFLET_ENCODERS'][] = 'Netzmacht\Contao\Leaflet\Subscriber\EncoderSubscriber'; + + +/* + * Leaflet assets. + * + * The leaflet definition are aware of the required javascript libraries. Register the assets so that they are + * loaded automatically. + * + * Each entry is an array of 2 values. The first is the resource. The second is a type. Supported types are: + * - url: An valid url. + * - file: An file path relative to the Contao Root. + * - source: Inline css/javascript. + */ +$GLOBALS['LEAFLET_ASSETS']['contao'] = array( + 'javascript' => array( + array() + ) +); + +$GLOBALS['LEAFLET_ASSETS']['leaflet'] = array( + 'css' => array( + array('http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css', 'url') + ), + 'javascript' => array( + array('http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js?3', 'url') + ) ); diff --git a/module/config/event_subscribers.php b/module/config/event_subscribers.php new file mode 100644 index 0000000..89e77f4 --- /dev/null +++ b/module/config/event_subscribers.php @@ -0,0 +1,5 @@ +share(function ($container) { + return new MapService( + $container['leaflet.definition.mapper'], + $container['leaflet.definition.builder'], + $container['event-dispatcher'] + ); +}); + + +/* + * The leaflet boot. + */ +$container['leaflet.boot'] = $container->share(function ($container) { + return new Boot($container['event-dispatcher']); +}); + + +/* + * The definition mapper. + */ +$container['leaflet.definition.mapper'] = $container->share(function ($container) { + /** @var Boot $boot */ + $boot = $container['leaflet.boot']; + $mapper = new DefinitionMapper($container['event-dispatcher']); + + return $boot->initializeDefinitionMapper($mapper); +}); + + +/* + * The local event dispatcher is used for the leaflet javascript encoding system. + */ +$container['leaflet.definition.builder.event-dispatcher'] = $container->share(function ($container) { + /** @var Boot $boot */ + $boot = $container['leaflet.boot']; + $dispatcher = new EventDispatcher(); + + return $boot->initializeEventDispatcher($dispatcher); +}); + + +/* + * The leaflet builder transforms the definition to javascript. + */ +$container['leaflet.definition.builder'] = $container->share(function($container) { + /** @var Boot $boot */ + $boot = $container['leaflet.boot']; + $dispatcher = $container['leaflet.definition.builder.event-dispatcher']; + + $encoder = new Encoder($dispatcher); + $builder = new Builder($encoder, $dispatcher); + $leaflet = new Leaflet($builder); + + return $boot->initializeLeafletBuilder($leaflet); +}); diff --git a/module/dca/tl_content.php b/module/dca/tl_content.php new file mode 100644 index 0000000..f790cb6 --- /dev/null +++ b/module/dca/tl_content.php @@ -0,0 +1,22 @@ + array('type', 'headline'), + 'leaflet' => array('leaflet_map'), + 'templates' => array(':hide', 'customTpl'), + 'protected' => array(':hide', 'protected'), + 'expert' => array(':hide', 'guests', 'cssID', 'space'), + 'invisible' => array(':hide', 'invisible', 'start', 'start') +); + +$GLOBALS['TL_DCA']['tl_content']['fields']['leaflet_map'] = array( + 'label' => &$GLOBALS['TL_LANG']['tl_content']['leaflet_map'], + 'inputType' => 'select', + 'exclude' => true, + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Content', 'getMaps'), + 'eval' => array( + 'tl_class' => 'w50', + 'chosen' => true, + ), + 'sql' => "int(10) unsigned NOT NULL default '0'" +); diff --git a/module/dca/tl_leaflet_map.php b/module/dca/tl_leaflet_map.php index 20a4100..7c8525f 100644 --- a/module/dca/tl_leaflet_map.php +++ b/module/dca/tl_leaflet_map.php @@ -5,7 +5,7 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array 'config' => array( 'dataContainer' => 'Table', 'enableVersioning' => true, - 'ctable' => array('tl_leaflet'), +// 'ctable' => array('tl_leaflet'), 'sql' => array ( 'keys' => array @@ -70,33 +70,34 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array 'metapalettes' => array( 'default' => array( - 'name' => array('title', 'alias'), - 'zoom' => array('center', 'zoom', 'adjustExtraZoom'), - 'controls' => array('zoomControl', 'attributionControl', 'controls'), - 'operation' => array( + 'title' => array('title', 'alias'), + 'zoom' => array('center', 'zoom', 'adjustZoomExtra'), + 'controls' => array('zoomControl', 'controls'), + 'interaction' => array( 'dragging', 'touchZoom', 'scrollWheelZoom', 'doubleClickZoom', 'boxZoom', 'tap', - 'adjustKeyboard' + 'keyboard' ), - 'behaviour' => array( + 'behaviour' => array( 'trackResize', - 'popupOnClick', + 'closeOnClick', 'bounceAtZoomLimits' ), - 'experts' => array( - 'cache', - 'options' + 'experts' => array( + 'options', + 'detachLibraries', + 'cache' ) ), ), 'metasubpalettes' => array( - 'adjustKeyboard' => array('keyboard', 'keyboardPanOffset', 'keyboardZoomOffset'), - 'adjustExtraZoom' => array('minZoom', 'maxZoom'), + 'keyboard' => array('keyboardPanOffset', 'keyboardZoomOffset'), + 'adjustZoomExtra' => array('minZoom', 'maxZoom'), ), 'fields' => array @@ -114,7 +115,7 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['title'], 'exclude' => true, 'inputType' => 'text', - 'eval' => array('mandatory' => true, 'maxlength' => 255), + 'eval' => array('mandatory' => true, 'maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''" ), 'alias' => array @@ -122,9 +123,82 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['alias'], 'exclude' => true, 'inputType' => 'text', - 'eval' => array('mandatory' => true, 'maxlength' => 255), + 'eval' => array('mandatory' => true, 'maxlength' => 255, 'tl_class' => 'w50'), 'sql' => "varchar(255) NOT NULL default ''" ), + 'center' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['center'], + 'exclude' => true, + 'inputType' => 'text', + 'save_callback' => array( + array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'validateCoordinate') + ), + 'wizard' => array( + array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getGeocoder') + ), + 'eval' => array( + 'maxlength' => 255, + 'tl_class' => 'long clr', + 'nullIfEmpty' => true, + ), + 'sql' => "varchar(255) NULL" + ), + 'zoom' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['zoom'], + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getZoomLevels'), + 'default' => '', + 'eval' => array( + 'maxlength' => 4, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + 'includeBlankOption' => true, + 'nullIfEmpty' => true + ), + 'sql' => "int(4) NULL" + ), + 'adjustZoomExtra' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['adjustZoomExtra'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => true, + 'eval' => array('tl_class' => 'w50 m12', 'submitOnChange' => true), + 'sql' => "char(1) NOT NULL default ''" + ), + 'minZoom' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['minZoom'], + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getZoomLevels'), + 'eval' => array( + 'maxlength' => 4, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + 'includeBlankOption' => true, + 'nullIfEmpty' => true + ), + 'sql' => "int(4) NULL" + ), + 'maxZoom' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['maxZoom'], + 'exclude' => true, + 'inputType' => 'select', + 'options_callback' => array('Netzmacht\Contao\Leaflet\Dca\Leaflet', 'getZoomLevels'), + 'eval' => array( + 'maxlength' => 4, + 'rgxp' => 'digit', + 'tl_class' => 'w50', + 'includeBlankOption' => true, + 'nullIfEmpty' => true + ), + 'sql' => "int(4) NULL" + ), 'dragging' => array ( 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['dragging'], @@ -147,18 +221,22 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array ( 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['scrollWheelZoom'], 'exclude' => true, - 'inputType' => 'checkbox', + 'inputType' => 'select', + 'options' => array('1', '', 'center'), + 'reference' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['zoomValues'], 'default' => true, - 'eval' => array('tl_class' => 'w50'), + 'eval' => array('tl_class' => 'w50', 'helpwizard' => true,), 'sql' => "char(1) NOT NULL default ''" ), 'doubleClickZoom' => array ( 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['doubleClickZoom'], 'exclude' => true, - 'inputType' => 'checkbox', + 'inputType' => 'select', + 'options' => array('1', '', 'center'), + 'reference' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['zoomValues'], 'default' => true, - 'eval' => array('tl_class' => 'w50'), + 'eval' => array('tl_class' => 'w50', 'helpwizard' => true,), 'sql' => "char(1) NOT NULL default ''" ), 'boxZoom' => array @@ -179,14 +257,95 @@ $GLOBALS['TL_DCA']['tl_leaflet_map'] = array 'eval' => array('tl_class' => 'w50'), 'sql' => "char(1) NOT NULL default ''" ), - 'adjustKeyboard' => array + 'trackResize' => array ( - 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['adjustKeyboard'], + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['trackResize'], 'exclude' => true, 'inputType' => 'checkbox', 'default' => true, 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default '1'" + ), + 'bounceAtZoomLimits' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['bounceAtZoomLimits'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => true, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default '1'" + ), + 'closeOnClick' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['closeOnClick'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => true, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default '1'" + ), + 'keyboard' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['keyboard'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => true, + 'eval' => array('tl_class' => 'w50', 'submitOnChange' => true), 'sql' => "char(1) NOT NULL default ''" ), + 'keyboardPanOffset' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['keyboardPanOffset'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => 80, + 'eval' => array('mandatory' => true, 'maxlength' => 4, 'rgxp' => 'digit', 'tl_class' => 'clr w50'), + 'sql' => "int(4) NOT NULL default '80'" + ), + 'keyboardZoomOffset' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['keyboardZoomOffset'], + 'exclude' => true, + 'inputType' => 'text', + 'default' => 1, + 'eval' => array('mandatory' => true, 'maxlength' => 4, 'rgxp' => 'digit', 'tl_class' => 'w50'), + 'sql' => "int(4) NOT NULL default '1'" + ), + 'zoomControl' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['zoomControl'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => true, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default '1'" + ), + 'options' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['options'], + 'exclude' => true, + 'inputType' => 'textarea', + 'default' => true, + 'eval' => array('tl_class' => 'clr lng', 'allowHtml'=>true, 'style' => 'min-height: 40px;'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'detachLibraries' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['detachLibraries'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50'), + 'sql' => "char(1) NOT NULL default ''" + ), + 'cache' => array + ( + 'label' => &$GLOBALS['TL_LANG']['tl_leaflet_map']['cache'], + 'exclude' => true, + 'inputType' => 'checkbox', + 'default' => false, + 'eval' => array('tl_class' => 'w50', 'submitOnChange' => true), + 'sql' => "char(1) NOT NULL default '0'" + ), ), ); diff --git a/module/languages/en/modules.php b/module/languages/en/modules.php new file mode 100644 index 0000000..18ceeb3 --- /dev/null +++ b/module/languages/en/modules.php @@ -0,0 +1,4 @@ + + + + + + +
+ diff --git a/module/templates/ce_leaflet_map.html5 b/module/templates/ce_leaflet_map.html5 new file mode 100644 index 0000000..9088421 --- /dev/null +++ b/module/templates/ce_leaflet_map.html5 @@ -0,0 +1,6 @@ +
+ diff --git a/src/Netzmacht/Contao/Leaflet/Boot.php b/src/Netzmacht/Contao/Leaflet/Boot.php new file mode 100644 index 0000000..0fd4e85 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Boot.php @@ -0,0 +1,89 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet; + +use Netzmacht\Contao\Leaflet\Event\InitializeDefinitionMapperEvent; +use Netzmacht\Contao\Leaflet\Event\InitializeEventDispatcherEvent; +use Netzmacht\Contao\Leaflet\Event\InitializeLeafletBuilderEvent; +use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper; +use Netzmacht\LeafletPHP\Leaflet; +use Symfony\Component\EventDispatcher\EventDispatcherInterface as EventDispatcher; + +/** + * Class Boot initialize the leaflet map extension. + * + * @package Netzmacht\Contao\Leaflet + */ +class Boot +{ + /** + * The event dispatcher. + * + * @var EventDispatcher + */ + private $eventDispatcher; + + /** + * Construct. + * + * @param EventDispatcher $eventDispatcher The event dispatcher. + */ + public function __construct(EventDispatcher $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + } + + /** + * Initialize definition mapper. + * + * @param DefinitionMapper $definitionMapper The definition mapper. + * + * @return DefinitionMapper + */ + public function initializeDefinitionMapper(DefinitionMapper $definitionMapper) + { + $event = new InitializeDefinitionMapperEvent($definitionMapper); + $this->eventDispatcher->dispatch($event::NAME, $event); + + return $definitionMapper; + } + + /** + * Initialize the internal used event dispatcher of the leaflet encoding system. + * + * @param EventDispatcher $eventDispatcher The internal event dispatcher. + * + * @return EventDispatcher + */ + public function initializeEventDispatcher(EventDispatcher $eventDispatcher) + { + $event = new InitializeEventDispatcherEvent($eventDispatcher); + $this->eventDispatcher->dispatch($event::NAME, $event); + + return $eventDispatcher; + } + + /** + * Initialize the leaflet builder. + * + * @param Leaflet $leaflet The leaflet builder. + * + * @return Leaflet + */ + public function initializeLeafletBuilder(Leaflet $leaflet) + { + $event = new InitializeLeafletBuilderEvent($leaflet); + $this->eventDispatcher->dispatch($event::NAME, $event); + + return $leaflet; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/ContaoAssets.php b/src/Netzmacht/Contao/Leaflet/ContaoAssets.php new file mode 100644 index 0000000..d836f26 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/ContaoAssets.php @@ -0,0 +1,82 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet; + +use Netzmacht\LeafletPHP\Assets; + +/** + * Class ContaoAssets + * @package Netzmacht\Contao\Leaflet + */ +class ContaoAssets implements Assets +{ + /** + * @var + */ + private $map; + + /** + * {@inheritdoc} + */ + public function addJavascript($script, $type = self::TYPE_SOURCE) + { + switch ($type) { + case static::TYPE_SOURCE: + $GLOBALS['TL_HEAD'][] = sprintf('', $script); + break; + + case static::TYPE_FILE: + $script .= '|static'; + // no break + + default: + $GLOBALS['TL_JAVASCRIPT'][] = $script; + } + } + + /** + * {@inheritdoc} + */ + public function addStylesheet($stylesheet, $type = self::TYPE_FILE) + { + switch ($type) { + case static::TYPE_SOURCE: + $GLOBALS['TL_HEAD'][] = sprintf('', $stylesheet); + break; + + case static::TYPE_FILE: + $stylesheet .= '||static'; + // no break + + default: + $GLOBALS['TL_CSS'][] = $stylesheet; + } + } + + /** + * {@inheritdoc} + */ + public function getMap() + { + return $this->map; + } + + /** + * {@inheritdoc} + */ + public function setMap($map) + { + $this->map = $map; + + return $this; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Dca/Content.php b/src/Netzmacht/Contao/Leaflet/Dca/Content.php new file mode 100644 index 0000000..3c78c4c --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Dca/Content.php @@ -0,0 +1,40 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Dca; + +use Netzmacht\Contao\Leaflet\Model\MapModel; + +/** + * Class Content + * @package Netzmacht\Contao\Leaflet\Dca + */ +class Content +{ + /** + * Get all leaflet maps. + * + * @return array + */ + public function getMaps() + { + $options = array(); + $collection = MapModel::findAll(); + + if ($collection) { + foreach ($collection as $map) { + $options[$map->id] = $map->title; + } + } + + return $options; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Dca/Leaflet.php b/src/Netzmacht/Contao/Leaflet/Dca/Leaflet.php new file mode 100644 index 0000000..e1fb284 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Dca/Leaflet.php @@ -0,0 +1,63 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Dca; + + +use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper; +use Netzmacht\Contao\Leaflet\Mapper\MapMapper; +use Netzmacht\Contao\Leaflet\Model\MapModel; +use Netzmacht\LeafletPHP\Definition\Type\LatLng; + +class Leaflet +{ + /** + * Validate a coordinate. + * + * @param $value + * + * @return mixed + */ + public function validateCoordinate($value) + { + if (!empty($value)) { + // Validate by creating latlng object. Throws an exception. + + LatLng::fromString($value); + } + + return $value; + } + + + public function getZoomLevels() + { + return range(1, 20); + } + + + public function getGeocoder($dataContainer) + { + $template = new \BackendTemplate('be_leaflet_geocode'); + $template->field = 'ctrl_' . $dataContainer->field; + + try { + $latLng = LatLng::fromString($dataContainer->value); + $template->marker = $latLng->toJson(); + } catch(\Exception $e) { + + } + + + return $template->parse(); + } + +} diff --git a/src/Netzmacht/Contao/Leaflet/Event/BuildDefinitionEvent.php b/src/Netzmacht/Contao/Leaflet/Event/BuildDefinitionEvent.php new file mode 100644 index 0000000..7a91d5d --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Event/BuildDefinitionEvent.php @@ -0,0 +1,71 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Event; + +use Netzmacht\LeafletPHP\Definition; +use Symfony\Component\EventDispatcher\Event; + +/** + * Class BuildDefinitionEvent is emitted when the mapper maps between the model and the definition. + * + * @package Netzmacht\Contao\Leaflet\Event + */ +class BuildDefinitionEvent extends Event +{ + const NAME = 'leaflet.mapper.definition'; + + /** + * The leaflet object definition. + * + * @var Definition + */ + private $definition; + + /** + * The model. + * + * @var \Model + */ + private $model; + + /** + * Construct. + * + * @param Definition $definition The leaflet definition. + * @param \Model $model The definition model. + */ + public function __construct(Definition $definition, \Model $model) + { + $this->definition = $definition; + $this->model = $model; + } + + /** + * Get the definition. + * + * @return Definition + */ + public function getDefinition() + { + return $this->definition; + } + + /** + * Get the model. + * + * @return \Model + */ + public function getModel() + { + return $this->model; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Event/GetJavascriptEvent.php b/src/Netzmacht/Contao/Leaflet/Event/GetJavascriptEvent.php new file mode 100644 index 0000000..8c188fe --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Event/GetJavascriptEvent.php @@ -0,0 +1,71 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Event; + +use Netzmacht\LeafletPHP\Definition\Map; +use Symfony\Component\EventDispatcher\Event; + +/** + * Class GetJavascriptEvent is emitted after the map javascript was created. + * + * @package Netzmacht\Contao\Leaflet\Event + */ +class GetJavascriptEvent extends Event +{ + const NAME = 'leaflet.service.get-javascript'; + + /** + * The generated javascript. + * + * @var string + */ + private $javascript; + + /** + * The map definition. + * + * @var Map + */ + private $map; + + /** + * Construct. + * + * @param Map $map The map definition. + * @param string $javascript The generated javascript. + */ + public function __construct($map, $javascript) + { + $this->map = $map; + $this->javascript = $javascript; + } + + /** + * Get the generated javascript. + * + * @return string + */ + public function getJavascript() + { + return $this->javascript; + } + + /** + * Get the map definition. + * + * @return Map + */ + public function getMap() + { + return $this->map; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Event/InitializeDefinitionMapperEvent.php b/src/Netzmacht/Contao/Leaflet/Event/InitializeDefinitionMapperEvent.php new file mode 100644 index 0000000..586df49 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Event/InitializeDefinitionMapperEvent.php @@ -0,0 +1,50 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Event; + +use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper; +use Symfony\Component\EventDispatcher\Event; + +/** + * Class InitializeDefinitionMapperEvent + * + * @package Netzmacht\Contao\Leaflet\Event + */ +class InitializeDefinitionMapperEvent extends Event +{ + const NAME = 'leaflet.boot.initialize-definition-mapper'; + + /** + * @var DefinitionMapper + */ + private $definitionMapper; + + /** + * Construct. + * + * @param DefinitionMapper $definitionMapper The definition mapper. + */ + public function __construct(DefinitionMapper $definitionMapper) + { + $this->definitionMapper = $definitionMapper; + } + + /** + * Get the definition mapper. + * + * @return DefinitionMapper + */ + public function getDefinitionMapper() + { + return $this->definitionMapper; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Event/InitializeEventDispatcherEvent.php b/src/Netzmacht/Contao/Leaflet/Event/InitializeEventDispatcherEvent.php new file mode 100644 index 0000000..16c9f72 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Event/InitializeEventDispatcherEvent.php @@ -0,0 +1,52 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Event; + +use Symfony\Component\EventDispatcher\Event; +use Symfony\Component\EventDispatcher\EventDispatcherInterface as EventDispatcher; + +/** + * InitializeEventDispatcherEvent is emitted then the internal event dispatcher of the encoding system is initialized. + * + * @package Netzmacht\Contao\Leaflet\Event + */ +class InitializeEventDispatcherEvent extends Event +{ + const NAME = 'leaflet.boot.initialize-event-dispatcher'; + + /** + * The event dispatcher. + * + * @var EventDispatcher + */ + private $eventDispatcher; + + /** + * The event dispatcher. + * + * @param EventDispatcher $eventDispatcher The event dispatcher. + */ + public function __construct(EventDispatcher $eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + } + + /** + * Get the event dispatcher. + * + * @return EventDispatcher + */ + public function getEventDispatcher() + { + return $this->eventDispatcher; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Event/InitializeLeafletBuilderEvent.php b/src/Netzmacht/Contao/Leaflet/Event/InitializeLeafletBuilderEvent.php new file mode 100644 index 0000000..0aea0dd --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Event/InitializeLeafletBuilderEvent.php @@ -0,0 +1,52 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Event; + +use Netzmacht\LeafletPHP\Leaflet; +use Symfony\Component\EventDispatcher\Event; + +/** + * Class InitializeLeafletBuilderEvent is emitted when the leaflet builder is created. + * + * @package Netzmacht\Contao\Leaflet\Event + */ +class InitializeLeafletBuilderEvent extends Event +{ + const NAME = 'leaflet.boot.initialize-leaflet-builder'; + + /** + * The leaflet builder. + * + * @var Leaflet + */ + private $builder; + + /** + * Construct. + * + * @param Leaflet $builder The leaflet builder. + */ + public function __construct(Leaflet $builder) + { + $this->builder = $builder; + } + + /** + * Get the builder. + * + * @return Leaflet + */ + public function getBuilder() + { + return $this->builder; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/LeafletMapElement.php b/src/Netzmacht/Contao/Leaflet/LeafletMapElement.php new file mode 100644 index 0000000..7968145 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/LeafletMapElement.php @@ -0,0 +1,62 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet; + +/** + * @property int leaflet_map + */ +class LeafletMapElement extends \ContentElement +{ + /** + * Template name. + * + * @var string + */ + protected $strTemplate = 'ce_leaflet_map'; + + /** + * @var MapService + */ + private $mapService; + + /** + * Construct. + * + * @param \ContentModel $objElement Content element model. + * @param string $strColumn Layout column. + */ + public function __construct($objElement, $strColumn = 'main') + { + parent::__construct($objElement, $strColumn); + + $this->mapService = $GLOBALS['container']['leaflet.map.service']; + } + + /** + * Compile the content element. + * + * @return void + * + * @throws \Exception + */ + protected function compile() + { + try { + $mapId = 'map_' . ($this->cssID[0] ?: $this->id); + + $this->Template->mapId = $mapId; + $this->Template->map = $this->mapService->getJavascript($this->leaflet_map, $mapId); + } catch(\Exception $e) { + throw $e; + } + } +} diff --git a/src/Netzmacht/Contao/Leaflet/MapService.php b/src/Netzmacht/Contao/Leaflet/MapService.php new file mode 100644 index 0000000..7d6b452 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/MapService.php @@ -0,0 +1,117 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet; + +use Netzmacht\Contao\Leaflet\Event\GetJavascriptEvent; +use Netzmacht\Contao\Leaflet\Mapper\DefinitionMapper; +use Netzmacht\Contao\Leaflet\Model\MapModel; +use Netzmacht\LeafletPHP\Assets; +use Netzmacht\LeafletPHP\Definition\Map; +use Netzmacht\LeafletPHP\Leaflet; +use Symfony\Component\EventDispatcher\EventDispatcherInterface as EventDispatcher; + +/** + * Class MapService. + * + * @package Netzmacht\Contao\Leaflet + */ +class MapService +{ + /** + * The definition mapper. + * + * @var DefinitionMapper + */ + private $mapper; + + /** + * The leaflet service. + * + * @var Leaflet + */ + private $leaflet; + /** + * @var EventDispatcher + */ + private $eventDispatcher; + + /** + * Construct. + * + * @param DefinitionMapper $mapper The definition mapper. + * @param Leaflet $leaflet The Leaflet instance. + * @param EventDispatcher $eventDispatcher The Contao event dispatcher. + */ + public function __construct(DefinitionMapper $mapper, Leaflet $leaflet, EventDispatcher $eventDispatcher) + { + $this->mapper = $mapper; + $this->leaflet = $leaflet; + $this->eventDispatcher = $eventDispatcher; + } + + /** + * Get map definition. + * + * @param int $mapId The map database id. + * @param string $elementId Optional element id. If none given the mapId or alias is used. + * + * @return Map + */ + public function getDefinition($mapId, $elementId = null) + { + $model = $this->getModel($mapId); + + return $this->mapper->handle($model, $elementId); + } + + /** + * Get map model. + * + * @param int $mapId Model id. + * + * @return MapModel + * + * @throws \InvalidArgumentException If no model is found. + */ + public function getModel($mapId) + { + $model = MapModel::findByPk($mapId); + + if ($model === null) { + throw new \InvalidArgumentException(sprintf('Model "%s" not found', $mapId)); + } + + return $model; + } + + /** + * Get map javascript. + * + * @param int $mapId The map id. + * @param string $elementId Optional element id. If none given the mapId or alias is used. + * + * @return string + * + * @throws \Exception If an error occurred in the process. + */ + public function getJavascript($mapId, $elementId = null) + { + $definition = $this->getDefinition($mapId, $elementId); + $assets = new ContaoAssets(); + $javascript = $this->leaflet->build($definition, $assets); + + $event = new GetJavascriptEvent($definition, $javascript); + $this->eventDispatcher->dispatch($event::NAME, $event); + + return $event->getJavascript(); + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/AbstractMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/AbstractMapper.php new file mode 100644 index 0000000..04f9da8 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Mapper/AbstractMapper.php @@ -0,0 +1,308 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Mapper; + +use Netzmacht\LeafletPHP\Definition; + +/** + * Class AbstractBuilder. + * + * @package Netzmacht\Contao\Leaflet\Builder + */ +abstract class AbstractMapper implements Mapper +{ + /** + * 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 mapping. + * + * @var array + */ + private $options = array(); + + /** + * Conditional option mapping. + * + * @var array + */ + private $conditional = array(); + + /** + * Construct. + */ + public function __construct() + { + $this->initialize(); + } + + /** + * 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, $mapping = null, $value = '1') + { + 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 = '1') + { + foreach ($options as $key => $option) { + if (is_numeric($key)) { + $this->addConditionalOption($column, $option, null, $value); + } else { + $this->addConditionalOption($column, $key, $option, $value); + } + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function handle(\Model $model, DefinitionMapper $builder) + { + $definition = $this->createInstance($model, $builder); + + $this->buildOptions($definition, $model); + $this->buildConditionals($definition, $model); + $this->doBuild($definition, $model, $builder); + + return $definition; + } + + /** + * {@inheritdoc} + */ + public function match(\Model $model) + { + $modelClass = static::$modelClass; + + return ($model instanceof $modelClass); + } + + /** + * Initialize the builder. + * + * @return void + */ + abstract protected function initialize(); + + /** + * Use for specific build methods. + * + * @param Definition $definition The definition being built. + * @param \Model $model The model. + * @param DefinitionMapper $builder The definition builder. + * + * @return void + */ + protected function doBuild(Definition $definition, \Model $model, DefinitionMapper $builder) + { + } + + /** + * Create a new definition instance. + * + * @param \Model $model The model. + * @param DefinitionMapper $mapper The definition mapper. + * + * @return Definition + */ + protected function createInstance(\Model $model, DefinitionMapper $mapper) + { + $reflector = new \ReflectionClass(static::$definitionClass); + $instance = $reflector->newInstanceArgs($this->buildConstructArguments($model, $mapper)); + + return $instance; + } + + /** + * Get construct arguments. + * + * @param \Model $model The model. + * @param DefinitionMapper $mapper The definition mapper. + * + * @return array + */ + protected function buildConstructArguments(\Model $model, DefinitionMapper $mapper) + { + return array( + $model->alias ?: $model->id + ); + } + + /** + * 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 $definition, \Model $model) + { + foreach ($this->conditional as $column => $conditions) { + foreach ($conditions as $value => $options) { + if ($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. + */ + private function applyOptions($options, $definition, $model) + { + foreach ($options as $option => $mapping) { + $setter = 'set' . ucfirst($option); + + if ($model->$option != $this->getDefaultOption($option, $definition)) { + $definition->$setter($model->$mapping); + } + } + } + + /** + * Get default option value. + * + * @param string $option The option name. + * @param Definition $definition The definition being built. + * + * @return mixed + */ + private 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; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php new file mode 100644 index 0000000..8667e2c --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Mapper/DefinitionMapper.php @@ -0,0 +1,116 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Mapper; + +use Netzmacht\Contao\Leaflet\Event\BuildDefinitionEvent; +use Netzmacht\LeafletPHP\Definition; +use Symfony\Component\EventDispatcher\EventDispatcherInterface as EventDispatcher; + +/** + * Class DefinitionBuilder is the main builder instance which contains all other builders as children. + * + * @package Netzmacht\Contao\Leaflet\Builder + */ +class DefinitionMapper +{ + /** + * Registered builders. + * + * @var AbstractMapper[][] + */ + private $builders = array(); + + /** + * The event dispatcher. + * + * @var EventDispatcher + */ + private $eventDispatcher; + + /** + * Map id of the current built map. + * + * @var string + */ + private $mapId; + + /** + * Construct. + * + * @param EventDispatcher $eventDispatcher The event dispatcher. + */ + public function __construct($eventDispatcher) + { + $this->eventDispatcher = $eventDispatcher; + } + + /** + * Add a builder. + * + * @param Mapper $builder The builder. + * @param int $priority The priority. The higher priorities get called first. + * + * @return $this + */ + public function register(Mapper $builder, $priority = 0) + { + $this->builders[$priority][] = $builder; + + return $this; + } + + /** + * Get the map id of the current built map. + * + * @return string + */ + public function getMapId() + { + return $this->mapId; + } + + /** + * Build a model. + * + * @param \Model $model The definition model. + * @param string $elementId Optional element id. If none given the mapId or alias is used. + * + * @return Definition + */ + public function handle(\Model $model, $elementId = null) + { + krsort($this->builders); + + $this->mapId = $elementId ?: ($model->alias ?: ('map_' . $model->id)); + + foreach ($this->builders as $builders) { + foreach($builders as $builder) { + if ($builder->match($model)) { + $definition = $builder->handle($model, $this); + + $event = new BuildDefinitionEvent($definition, $model); + $this->eventDispatcher->dispatch($event::NAME, $event); + + return $definition; + } + } + } + + throw new \RuntimeException( + sprintf( + 'Could not build model "%s::%s". No matching builders found.', + $model->getTable(), + $model->{$model->getPk()} + ) + ); + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php new file mode 100644 index 0000000..a55bd3a --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Mapper/MapMapper.php @@ -0,0 +1,106 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Mapper; + +use Netzmacht\Contao\Leaflet\Model\MapModel; +use Netzmacht\LeafletPHP\Definition; +use Netzmacht\LeafletPHP\Definition\Map; + +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 + ->addOptions('center', 'zoom', 'zoomControl') + ->addOptions('dragging', 'touchZoom', 'scrollWheelZoom', 'doubleClickZoom', 'boxZoom', 'tap', 'keyboard') + ->addOptions('trackResize', 'closePopupOnClick', 'bounceAtZoomLimits') + ->addConditionalOptions('adjustZoomExtra', array('minZoom', 'maxZoom')) + ->addConditionalOptions('keyboard', array('keyboardPanOffset', 'keyboardZoomOffset')); + } + + /** + * @inheritdoc + */ + protected function doBuild(Definition $map, \Model $model, DefinitionMapper $builder) + { + if ($map instanceof Map && $model instanceof MapModel) { + $this->buildCustomOptions($map, $model); + $this->buildControls($map, $model, $builder); + $this->buildLayers($map, $model, $builder); + } + } + + /** + * @inheritdoc + */ + protected function buildConstructArguments(\Model $model, DefinitionMapper $mapper) + { + return array( + $mapper->getMapId(), + $mapper->getMapId() + ); + } + + /** + * 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) { + $map->setOptions(json_decode($model->options, true)); + } + } + + /** + * Build map controls. + * + * @param Map $map The map being built. + * @param MapModel $model The map model. + * @param DefinitionMapper $mapper The definition mapper. + */ + private function buildControls(Map $map, MapModel$model, DefinitionMapper $mapper) + { + } + + /** + * Build map layers. + * + * @param Map $map The map being built. + * @param MapModel $model The map model. + * @param DefinitionMapper $mapper Definition mapper. + */ + private function buildLayers(Map $map, MapModel $model, DefinitionMapper $mapper) + { + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Mapper/Mapper.php b/src/Netzmacht/Contao/Leaflet/Mapper/Mapper.php new file mode 100644 index 0000000..bc35548 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Mapper/Mapper.php @@ -0,0 +1,36 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Mapper; + +use Netzmacht\LeafletPHP\Definition; + +interface Mapper +{ + /** + * Map model to the definition. + * + * @param \Model $model The model being built. + * @param DefinitionMapper $builder The definition builder. + * + * @return Definition + */ + public function handle(\Model $model, DefinitionMapper $builder); + + /** + * Check if builder is responsible for the model. + * + * @param \Model $model The model being build. + * + * @return bool + */ + public function match(\Model $model); +} diff --git a/src/Netzmacht/Contao/Leaflet/Model/MapModel.php b/src/Netzmacht/Contao/Leaflet/Model/MapModel.php new file mode 100644 index 0000000..105a35d --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Model/MapModel.php @@ -0,0 +1,19 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Model; + + +class MapModel extends \Model +{ + protected static $strTable = 'tl_leaflet_map'; + +} diff --git a/src/Netzmacht/Contao/Leaflet/Subscriber/BootSubscriber.php b/src/Netzmacht/Contao/Leaflet/Subscriber/BootSubscriber.php new file mode 100644 index 0000000..44c8b7d --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Subscriber/BootSubscriber.php @@ -0,0 +1,117 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Subscriber; + +use ContaoCommunityAlliance\Contao\EventDispatcher\EventDispatcherInitializer; +use Netzmacht\Contao\Leaflet\Event\GetJavascriptEvent; +use Netzmacht\Contao\Leaflet\Event\InitializeDefinitionMapperEvent; +use Netzmacht\Contao\Leaflet\Event\InitializeEventDispatcherEvent; +use Netzmacht\Contao\Leaflet\Event\InitializeLeafletBuilderEvent; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Class BootSubscriber + * + * @package Netzmacht\Contao\Leaflet\Subscriber + */ +class BootSubscriber implements EventSubscriberInterface +{ + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array( + InitializeDefinitionMapperEvent::NAME => 'initializeDefinitionMapper', + InitializeEventDispatcherEvent::NAME => 'initializeEventDispatcher', + InitializeLeafletBuilderEvent::NAME => 'initializeLeafletBuilder', + GetJavascriptEvent::NAME => 'loadAssets' + ); + } + + /** + * Create and register all configured mappers. + * + * @param InitializeDefinitionMapperEvent $event The subscribed event. + * + * @return void + * + * @SuppressWarnings(PHPMD.Superglobals) + */ + public function initializeDefinitionMapper(InitializeDefinitionMapperEvent $event) + { + $mapper = $event->getDefinitionMapper(); + + foreach ($GLOBALS['LEAFLET_MAPPERS'] as $className) { + if (is_array($className)) { + $mapper->register(new $className[0], $className[1]); + } else { + $mapper->register(new $className()); + } + } + } + + /** + * Register all leaflet encoders. + * + * @param InitializeEventDispatcherEvent $event The subscribed event. + * + * @return void + * + * @SuppressWarnings(PHPMD.Superglobals) + */ + public function initializeEventDispatcher(InitializeEventDispatcherEvent $event) + { + $dispatcher = $event->getEventDispatcher(); + $initializer = new EventDispatcherInitializer(); + + $initializer->addSubscribers($dispatcher, $GLOBALS['LEAFLET_ENCODERS']); + } + + /** + * Register all libraries assets. + * + * @param InitializeLeafletBuilderEvent $event The subscribed event. + * + * @return void + * + * @SuppressWarnings(PHPMD.Superglobals) + */ + public function initializeLeafletBuilder(InitializeLeafletBuilderEvent $event) + { + $builder = $event->getBuilder(); + + foreach ($GLOBALS['LEAFLET_ASSETS'] as $name => $assets) { + if (!empty($assets['css'])) { + foreach ($assets['css'] as $javascript) { + $builder->registerStylesheet($name, $javascript[0], $javascript[1]); + } + } + + if (!empty($assets['javascript'])) { + foreach ($assets['javascript'] as $javascript) { + $builder->registerJavascript($name, $javascript[0], $javascript[1]); + } + } + } + } + + /** + * Load Contao leaflet assets. + * + * @return void + */ + public function loadAssets() + { + $GLOBALS['TL_JAVASCRIPT'][] = 'system/modules/leaflet/assets/js/contao-leaflet.js'; + } +} diff --git a/src/Netzmacht/Contao/Leaflet/Subscriber/EncoderSubscriber.php b/src/Netzmacht/Contao/Leaflet/Subscriber/EncoderSubscriber.php new file mode 100644 index 0000000..7d6b2b3 --- /dev/null +++ b/src/Netzmacht/Contao/Leaflet/Subscriber/EncoderSubscriber.php @@ -0,0 +1,97 @@ + + * @copyright 2014 netzmacht creative David Molineus + * @license LGPL 3.0 + * @filesource + * + */ + +namespace Netzmacht\Contao\Leaflet\Subscriber; + +use Netzmacht\Javascript\Event\BuildEvent; +use Netzmacht\LeafletPHP\Definition\Map; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; + +/** + * Class EncoderSubscriber subscribes to the internal encoding event dispatcher. + * + * @package Netzmacht\Contao\Leaflet\Subscriber + */ +class EncoderSubscriber implements EventSubscriberInterface +{ + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() + { + return array( + BuildEvent::NAME => array( + array('startWrapper', 1000), + array('addAttribution'), + array('endWrapper', -1000) + ) + ); + } + + /** + * Add contao-leaflet attribution. + * + * @param BuildEvent $event + */ + public function addAttribution(BuildEvent $event) + { + $object = $event->getObject(); + + if ($object instanceof Map) { + $attribution = <<netzmacht creative' +); +HTML; + $event->getOutput()->addLine($attribution); + + $event->getOutput()->addLine("var tileLayer = new L.TileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: \"test\"}); +tileLayer.addTo(map);"); + } + } + + /** + * Start the wrapper. + * + * The encoded map is wrapped so that it is added to window.ContaoLeaflet. You can subscribe the + * "mapadded" event on window.ContaoLeaflet if you can to do some customize stuff. + * + * @param BuildEvent $event The subscribed event. + * + * @return void + */ + public function startWrapper(BuildEvent $event) + { + $object = $event->getObject(); + + if ($object instanceof Map) { + $line = sprintf('window.ContaoLeaflet.addMap(\'%s\', (function() {', $object->getId()); + $event->getOutput()->addLine($line); + } + } + + /** + * End the wrapper. + * + * @param BuildEvent $event The subscribed event. + * + * @return void + */ + public function endWrapper(BuildEvent $event) + { + $object = $event->getObject(); + + if ($object instanceof Map) { + $line = 'return map; })());'; + $event->getOutput()->addLine($line); + } + } +}