summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php')
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php182
1 files changed, 182 insertions, 0 deletions
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php
new file mode 100644
index 00000000..8c757acd
--- /dev/null
+++ b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php
@@ -0,0 +1,182 @@
+<?php
+
+namespace Maps\MediaWiki\ParserHooks;
+
+use FormatJson;
+use Html;
+use Maps\DataAccess\MediaWikiFileUrlFinder;
+use Maps\Elements\Location;
+use Maps\MappingService;
+use Maps\Presentation\ElementJsonSerializer;
+use Maps\Presentation\MapHtmlBuilder;
+use Maps\Presentation\WikitextParser;
+use Maps\Presentation\WikitextParsers\LocationParser;
+use Parser;
+
+/**
+ * Class handling the #display_map rendering.
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ * @author Kim Eik
+ */
+class DisplayMapRenderer {
+
+ public $service;
+
+ /**
+ * @var LocationParser
+ */
+ private $locationParser;
+
+ /**
+ * @var MediaWikiFileUrlFinder
+ */
+ private $fileUrlFinder;
+
+ /**
+ * @var WikitextParser
+ */
+ private $wikitextParser;
+ /**
+ * @var ElementJsonSerializer
+ */
+ private $elementSerializer;
+
+ public function __construct( MappingService $service = null ) {
+ $this->service = $service;
+ }
+
+ /**
+ * Handles the request from the parser hook by doing the work that's common for all
+ * mapping services, calling the specific methods and finally returning the resulting output.
+ *
+ * @param array $params
+ * @param Parser $parser
+ *
+ * @return string
+ */
+ public final function renderMap( array $params, Parser $parser ) {
+ $factory = \Maps\MapsFactory::newDefault();
+
+ $this->locationParser = $factory->newLocationParser();
+ $this->fileUrlFinder = $factory->getFileUrlFinder();
+
+ $this->wikitextParser = new WikitextParser( clone $parser );
+ $this->elementSerializer = new ElementJsonSerializer( $this->wikitextParser );
+
+ $this->handleMarkerData( $params );
+
+ $output = ( new MapHtmlBuilder() )->getMapHTML(
+ $params,
+ $this->service->newMapId(),
+ $this->service->getName()
+ );
+
+ $dependencies = $this->service->getDependencyHtml( $params );
+
+ // Only add a head item when there are dependencies.
+ if ( $dependencies ) {
+ $parser->getOutput()->addHeadItem( $dependencies );
+ }
+
+ $parser->getOutput()->addModules( $this->service->getResourceModules() );
+
+ return $output;
+ }
+
+ /**
+ * Converts the data in the coordinates parameter to JSON-ready objects.
+ * These get stored in the locations parameter, and the coordinates on gets deleted.
+ */
+ private function handleMarkerData( array &$params ) {
+ $params['centre'] = $this->getCenter( $params['centre'] );
+
+ if ( is_object( $params['wmsoverlay'] ) ) {
+ $params['wmsoverlay'] = $params['wmsoverlay']->getJSONObject();
+ }
+
+ $params['locations'] = $this->getLocationJson( $params );
+
+ unset( $params['coordinates'] );
+
+ $this->handleShapeData( $params );
+ }
+
+ private function getCenter( $coordinatesOrAddress ) {
+ if ( $coordinatesOrAddress === false ) {
+ return false;
+ }
+
+ try {
+ // FIXME: a Location makes no sense here, since the non-coordinate data is not used
+ $location = $this->locationParser->parse( $coordinatesOrAddress );
+ }
+ catch ( \Exception $ex ) {
+ // TODO: somehow report this to the user
+ return false;
+ }
+
+ return $location->getJSONObject();
+ }
+
+ private function getLocationJson( array $params ) {
+ $iconUrl = $this->fileUrlFinder->getUrlForFileName( $params['icon'] );
+ $visitedIconUrl = $this->fileUrlFinder->getUrlForFileName( $params['visitedicon'] );
+
+ $locationJsonObjects = [];
+
+ foreach ( $params['coordinates'] as $coordinatesOrAddress ) {
+ try {
+ $location = $this->locationParser->parse( $coordinatesOrAddress );
+ }
+ catch ( \Exception $ex ) {
+ // TODO: somehow report this to the user
+ continue;
+ }
+
+ $locationJsonObjects[] = $this->getLocationJsonObject(
+ $location,
+ $params,
+ $iconUrl,
+ $visitedIconUrl
+ );
+ }
+
+ return $locationJsonObjects;
+ }
+
+ private function getLocationJsonObject( Location $location, array $params, $iconUrl, $visitedIconUrl ) {
+ $jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '', $visitedIconUrl );
+
+ $this->elementSerializer->titleAndText( $jsonObj );
+
+ if ( isset( $jsonObj['inlineLabel'] ) ) {
+ $jsonObj['inlineLabel'] = strip_tags(
+ $this->wikitextParser->wikitextToHtml( $jsonObj['inlineLabel'] ),
+ '<a><img>'
+ );
+ }
+
+ return $jsonObj;
+ }
+
+ private function handleShapeData( array &$params ) {
+ $textContainers = [
+ &$params['lines'],
+ &$params['polygons'],
+ &$params['circles'],
+ &$params['rectangles'],
+ &$params['imageoverlays'], // FIXME: this is Google Maps specific!!
+ ];
+
+ foreach ( $textContainers as &$textContainer ) {
+ if ( is_array( $textContainer ) ) {
+ foreach ( $textContainer as &$obj ) {
+ $obj = $this->elementSerializer->elementToJson( $obj );
+ }
+ }
+ }
+ }
+
+}