summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Maps/src
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Maps/src')
-rw-r--r--www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcher.php93
-rw-r--r--www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcherResult.php31
-rw-r--r--www/wiki/extensions/Maps/src/DataAccess/JsonFileParser.php79
-rw-r--r--www/wiki/extensions/Maps/src/GoogleMapsService.php71
-rw-r--r--www/wiki/extensions/Maps/src/LeafletService.php66
-rw-r--r--www/wiki/extensions/Maps/src/MappingService.php6
-rw-r--r--www/wiki/extensions/Maps/src/MapsFactory.php34
-rw-r--r--www/wiki/extensions/Maps/src/MapsFunctions.php32
-rw-r--r--www/wiki/extensions/Maps/src/MapsSetup.php87
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContent.php57
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContentHandler.php6
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/MapsHooks.php61
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapFunction.php117
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php7
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/FindDestinationFunction.php4
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/MapsDocFunction.php19
-rw-r--r--www/wiki/extensions/Maps/src/MediaWiki/Specials/SpecialMapEditor.php3
-rw-r--r--www/wiki/extensions/Maps/src/Presentation/GeoJsonMapPageUi.php83
-rw-r--r--www/wiki/extensions/Maps/src/Presentation/GeoJsonNewPageUi.php27
-rw-r--r--www/wiki/extensions/Maps/src/Presentation/MapHtmlBuilder.php10
-rw-r--r--www/wiki/extensions/Maps/src/Presentation/MapsDistanceParser.php2
-rw-r--r--www/wiki/extensions/Maps/src/Presentation/OutputFacade.php62
-rw-r--r--www/wiki/extensions/Maps/src/SemanticMW/ResultPrinters/MapPrinter.php17
23 files changed, 684 insertions, 290 deletions
diff --git a/www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcher.php b/www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcher.php
new file mode 100644
index 00000000..ea7724d5
--- /dev/null
+++ b/www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcher.php
@@ -0,0 +1,93 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace Maps\DataAccess;
+
+use FileFetcher\FileFetcher;
+use FileFetcher\FileFetchingException;
+use MediaWiki\Storage\RevisionLookup;
+
+/**
+ * Returns the content of the JSON file at the specified location as array.
+ * Empty array is returned on failure.
+ *
+ * @licence GNU GPL v2+
+ * @author Jeroen De Dauw < jeroendedauw@gmail.com >
+ */
+class GeoJsonFetcher {
+
+ private $fileFetcher;
+ private $titleParser;
+ private $revisionLookup;
+
+ public function __construct( FileFetcher $fileFetcher, \TitleParser $titleParser, RevisionLookup $revisionLookup ) {
+ $this->fileFetcher = $fileFetcher;
+ $this->titleParser = $titleParser;
+ $this->revisionLookup = $revisionLookup;
+ }
+
+ public function parse( string $fileLocation ): array {
+ return $this->fetch( $fileLocation )->getContent();
+ }
+
+ public function fetch( string $fileLocation ) {
+ try {
+ $title = $this->titleParser->parseTitle( $fileLocation, NS_GEO_JSON );
+ $revision = $this->revisionLookup->getRevisionByTitle( $title );
+
+ if ( $revision !== null ) {
+ $content = $revision->getContent( 'main' );
+
+ if ( $content instanceof \JsonContent ) {
+ return new GeoJsonFetcherResult(
+ $this->normalizeJson( $content->getNativeData() ),
+ $revision->getId(),
+ $title
+ );
+ }
+ }
+ }
+ catch ( \MalformedTitleException $e ) {
+ }
+
+ // Prevent reading JSON files on the server
+ if( !filter_var( $fileLocation, FILTER_VALIDATE_URL) ) {
+ return $this->newEmptyResult();
+ }
+
+ try {
+ return new GeoJsonFetcherResult(
+ $this->normalizeJson( $this->fileFetcher->fetchFile( $fileLocation ) ),
+ null,
+ null
+ );
+ }
+ catch ( FileFetchingException $ex ) {
+ return $this->newEmptyResult();
+ }
+ }
+
+ private function newEmptyResult(): GeoJsonFetcherResult {
+ return new GeoJsonFetcherResult(
+ [],
+ null,
+ null
+ );
+ }
+
+ private function normalizeJson( ?string $jsonString ): array {
+ if ( $jsonString === null ) {
+ return [];
+ }
+
+ $json = json_decode( $jsonString, true );
+
+ if ( $json === null ) {
+ return [];
+ }
+
+ return $json;
+ }
+
+}
diff --git a/www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcherResult.php b/www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcherResult.php
new file mode 100644
index 00000000..7345b649
--- /dev/null
+++ b/www/wiki/extensions/Maps/src/DataAccess/GeoJsonFetcherResult.php
@@ -0,0 +1,31 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace Maps\DataAccess;
+
+class GeoJsonFetcherResult {
+
+ private $content;
+ private $revisionId;
+ private $source;
+
+ public function __construct( array $content, ?int $revisionId, ?\TitleValue $source ) {
+ $this->content = $content;
+ $this->revisionId = $revisionId;
+ $this->source = $source;
+ }
+
+ public function getContent(): array {
+ return $this->content;
+ }
+
+ public function getTitleValue(): ?\TitleValue {
+ return $this->source;
+ }
+
+ public function getRevisionId(): ?int {
+ return $this->revisionId;
+ }
+
+}
diff --git a/www/wiki/extensions/Maps/src/DataAccess/JsonFileParser.php b/www/wiki/extensions/Maps/src/DataAccess/JsonFileParser.php
deleted file mode 100644
index 81d6cfa0..00000000
--- a/www/wiki/extensions/Maps/src/DataAccess/JsonFileParser.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-
-declare( strict_types = 1 );
-
-namespace Maps\DataAccess;
-
-use FileFetcher\FileFetcher;
-use FileFetcher\FileFetchingException;
-use Maps\MapsFactory;
-use ValueParsers\ParseException;
-use ValueParsers\ValueParser;
-
-/**
- * Returns the content of the JSON file at the specified location as array.
- * Empty array is returned on failure.
- *
- * @licence GNU GPL v2+
- * @author Jeroen De Dauw < jeroendedauw@gmail.com >
- */
-class JsonFileParser implements ValueParser {
-
- private $fileFetcher;
- private $pageContentFetcher;
- private $defaultNamespace;
-
- public function __construct( $fileFetcher = null, PageContentFetcher $pageContentFetcher = null ) {
- $this->fileFetcher = $fileFetcher instanceof FileFetcher
- ? $fileFetcher : MapsFactory::newDefault()->getGeoJsonFileFetcher();
-
- $this->pageContentFetcher = $pageContentFetcher instanceof PageContentFetcher
- ? $pageContentFetcher : MapsFactory::newDefault()->getPageContentFetcher();
-
- $this->defaultNamespace = NS_GEO_JSON;
- }
-
- /**
- * @param string $fileLocation
- *
- * @return array
- * @throws ParseException
- */
- public function parse( $fileLocation ) {
- $jsonString = $this->getJsonString( $fileLocation );
-
- if ( $jsonString === null ) {
- return [];
- }
-
- $json = json_decode( $jsonString, true );
-
- if ( $json === null ) {
- return [];
- }
-
- return $json;
- }
-
- private function getJsonString( string $fileLocation ): ?string {
- $content = $this->pageContentFetcher->getPageContent( $fileLocation, $this->defaultNamespace );
-
- if ( $content instanceof \JsonContent ) {
- return $content->getNativeData();
- }
-
- // Prevent reading JSON files on the server
- if( !filter_var( $fileLocation, FILTER_VALIDATE_URL) ) {
- return null;
- }
-
- try {
- return $this->fileFetcher->fetchFile( $fileLocation );
- }
- catch ( FileFetchingException $ex ) {
- return null;
- }
- }
-
-
-}
diff --git a/www/wiki/extensions/Maps/src/GoogleMapsService.php b/www/wiki/extensions/Maps/src/GoogleMapsService.php
index 9c1b91b9..b1ccba34 100644
--- a/www/wiki/extensions/Maps/src/GoogleMapsService.php
+++ b/www/wiki/extensions/Maps/src/GoogleMapsService.php
@@ -3,6 +3,8 @@
namespace Maps;
use Html;
+use ParamProcessor\ProcessedParam;
+use ParamProcessor\ProcessingResult;
/**
* @licence GNU GPL v2+
@@ -49,7 +51,19 @@ class GoogleMapsService implements MappingService {
global $egMapsGMaps3DefTypeStyle, $egMapsGMaps3DefZoomStyle, $egMapsGMaps3AutoInfoWindows;
global $egMapsResizableByDefault;
- $params = [];
+ $params = MapsFunctions::getCommonParameters();
+
+ $params['visitedicon'] = [
+ 'default' => '',
+ 'message' => 'maps-displaymap-par-visitedicon',
+ ];
+
+ $params['wmsoverlay'] = [
+ 'type' => 'wmsoverlay',
+ 'default' => false,
+ 'delimiter' => ' ',
+ 'message' => 'maps-displaymap-par-wmsoverlay',
+ ];
$params['zoom'] = [
'type' => 'integer',
@@ -150,7 +164,8 @@ class GoogleMapsService implements MappingService {
'message' => 'maps-googlemaps3-par-poi',
];
- $params['markercluster'] = [
+ $params['cluster'] = [
+ 'aliases' => [ 'markercluster' ],
'type' => 'boolean',
'default' => false,
'message' => 'maps-par-markercluster',
@@ -199,11 +214,18 @@ class GoogleMapsService implements MappingService {
'message' => 'maps-par-kml',
'islist' => true,
'post-format' => function( array $kmlFileNames ) {
- return array_map(
- function( string $fileName ) {
- return wfExpandUrl( MapsFunctions::getFileUrl( $fileName ) );
- },
- $kmlFileNames
+ return array_values(
+ array_filter(
+ array_map(
+ function( string $fileName ) {
+ return wfExpandUrl( MapsFunctions::getFileUrl( $fileName ) );
+ },
+ $kmlFileNames
+ ),
+ function( string $fileName ) {
+ return $fileName !== '';
+ }
+ )
);
}
];
@@ -220,13 +242,15 @@ class GoogleMapsService implements MappingService {
// new CriterionSearchMarkers() FIXME
];
- $params['enablefullscreen'] = [
+ $params['fullscreen'] = [
+ 'aliases' => [ 'enablefullscreen' ],
'type' => 'boolean',
'default' => false,
'message' => 'maps-par-enable-fullscreen',
];
$params['scrollwheelzoom'] = [
+ 'aliases' => [ 'scrollzoom' ],
'type' => 'boolean',
'default' => false,
'message' => 'maps-par-scrollwheelzoom',
@@ -251,7 +275,7 @@ class GoogleMapsService implements MappingService {
}
public function getResourceModules(): array {
- return [ 'ext.maps.googlemaps3', 'ext.sm.googlemaps3ajax' ];
+ return [ 'ext.maps.googlemaps3', 'ext.maps.googlemaps3ajax' ];
}
public static function getApiScript( $langCode, array $urlArgs = [] ) {
@@ -311,4 +335,33 @@ class GoogleMapsService implements MappingService {
)
];
}
+
+ public function processingResultToMapParams( ProcessingResult $processingResult ): array {
+ $parameters = $processingResult->getParameters();
+
+ if ( array_key_exists( 'zoom', $parameters ) && $parameters['zoom']->wasSetToDefault() && count(
+ $parameters['coordinates']->getValue()
+ ) > 1 ) {
+ $parameters['zoom'] = $this->getParameterWithValue( $parameters['zoom'], false );
+ }
+
+ $mapParams = [];
+
+ foreach ( $parameters as $parameter ) {
+ $mapParams[$parameter->getName()] = $parameter->getValue();
+ }
+
+ return $mapParams;
+ }
+
+ private function getParameterWithValue( ProcessedParam $param, $value ) {
+ return new ProcessedParam(
+ $param->getName(),
+ $value,
+ $param->wasSetToDefault(),
+ $param->getOriginalName(),
+ $param->getOriginalValue()
+ );
+ }
+
}
diff --git a/www/wiki/extensions/Maps/src/LeafletService.php b/www/wiki/extensions/Maps/src/LeafletService.php
index 0e41d670..6d189fdb 100644
--- a/www/wiki/extensions/Maps/src/LeafletService.php
+++ b/www/wiki/extensions/Maps/src/LeafletService.php
@@ -3,6 +3,8 @@
namespace Maps;
use Html;
+use ParamProcessor\ParameterTypes;
+use ParamProcessor\ProcessingResult;
/**
* @licence GNU GPL v2+
@@ -24,19 +26,17 @@ class LeafletService implements MappingService {
}
public function getParameterInfo(): array {
- global $GLOBALS;
-
- $params = [];
+ $params = MapsFunctions::getCommonParameters();
$params['zoom'] = [
- 'type' => 'integer',
+ 'type' => ParameterTypes::INTEGER,
'range' => [ 0, 20 ],
'default' => false,
'message' => 'maps-par-zoom'
];
$params['defzoom'] = [
- 'type' => 'integer',
+ 'type' => ParameterTypes::INTEGER,
'range' => [ 0, 20 ],
'default' => self::getDefaultZoom(),
'message' => 'maps-leaflet-par-defzoom'
@@ -51,8 +51,9 @@ class LeafletService implements MappingService {
'islist' => true,
];
- $params['overlaylayers'] = [
- 'type' => 'string',
+ $params['overlays'] = [
+ 'aliases' => [ 'overlaylayers' ],
+ 'type' => ParameterTypes::STRING,
'values' => array_keys( $GLOBALS['egMapsLeafletAvailableOverlayLayers'], true, true ),
'default' => $GLOBALS['egMapsLeafletOverlayLayers'],
'message' => 'maps-leaflet-par-overlaylayers',
@@ -60,59 +61,68 @@ class LeafletService implements MappingService {
];
$params['resizable'] = [
- 'type' => 'boolean',
+ 'type' => ParameterTypes::BOOLEAN,
'default' => $GLOBALS['egMapsResizableByDefault'],
'message' => 'maps-par-resizable'
];
- $params['enablefullscreen'] = [
- 'type' => 'boolean',
+ $params['fullscreen'] = [
+ 'aliases' => [ 'enablefullscreen' ],
+ 'type' => ParameterTypes::BOOLEAN,
'default' => false,
'message' => 'maps-par-enable-fullscreen',
];
$params['scrollwheelzoom'] = [
- 'type' => 'boolean',
+ 'aliases' => [ 'scrollzoom' ],
+ 'type' => ParameterTypes::BOOLEAN,
'default' => true,
'message' => 'maps-par-scrollwheelzoom',
];
- $params['markercluster'] = [
- 'type' => 'boolean',
+ $params['cluster'] = [
+ 'aliases' => [ 'markercluster' ],
+ 'type' => ParameterTypes::BOOLEAN,
'default' => false,
'message' => 'maps-par-markercluster',
];
$params['clustermaxzoom'] = [
- 'type' => 'integer',
+ 'type' => ParameterTypes::INTEGER,
'default' => 20,
'message' => 'maps-par-clustermaxzoom',
];
$params['clusterzoomonclick'] = [
- 'type' => 'boolean',
+ 'type' => ParameterTypes::BOOLEAN,
'default' => true,
'message' => 'maps-par-clusterzoomonclick',
];
$params['clustermaxradius'] = [
- 'type' => 'integer',
+ 'type' => ParameterTypes::INTEGER,
'default' => 80,
'message' => 'maps-par-maxclusterradius',
];
$params['clusterspiderfy'] = [
- 'type' => 'boolean',
+ 'type' => ParameterTypes::BOOLEAN,
'default' => true,
'message' => 'maps-leaflet-par-clusterspiderfy',
];
$params['geojson'] = [
- 'type' => 'jsonfile',
+ 'type' => ParameterTypes::STRING,
'default' => '',
'message' => 'maps-displaymap-par-geojson',
];
+ $params['clicktarget'] = [
+ 'type' => ParameterTypes::STRING,
+ 'default' => '',
+ 'message' => 'maps-leaflet-par-clicktarget',
+ ];
+
return $params;
}
@@ -132,7 +142,7 @@ class LeafletService implements MappingService {
}
public function getResourceModules(): array {
- return [ 'ext.maps.leaflet', 'ext.sm.leafletajax' ];
+ return [ 'ext.maps.leaflet.loader', 'ext.maps.leaflet.leafletajax' ];
}
public function getDependencyHtml( array $params ): string {
@@ -151,7 +161,7 @@ class LeafletService implements MappingService {
}
private function getDependencies( array $params ): array {
- $leafletPath = $GLOBALS['wgScriptPath'] . '/extensions/Maps/resources/leaflet/leaflet';
+ $leafletPath = $GLOBALS['wgScriptPath'] . '/extensions/Maps/resources/lib/leaflet';
return array_merge(
[
@@ -181,4 +191,20 @@ class LeafletService implements MappingService {
return array_unique( $layerDependencies );
}
+ public function processingResultToMapParams( ProcessingResult $processingResult ): array {
+ $mapParams = $processingResult->getParameterArray();
+
+ if ( $mapParams['geojson'] !== '' ) {
+ $fetcher = MapsFactory::newDefault()->newGeoJsonFetcher();
+
+ $result = $fetcher->fetch( $mapParams['geojson'] );
+
+ $mapParams['geojson'] = $result->getContent();
+ $mapParams['GeoJsonSource'] = $result->getTitleValue() === null ? null : $result->getTitleValue()->getText();
+ $mapParams['GeoJsonRevisionId'] = $result->getRevisionId();
+ }
+
+ return $mapParams;
+ }
+
}
diff --git a/www/wiki/extensions/Maps/src/MappingService.php b/www/wiki/extensions/Maps/src/MappingService.php
index 184ef712..960315d1 100644
--- a/www/wiki/extensions/Maps/src/MappingService.php
+++ b/www/wiki/extensions/Maps/src/MappingService.php
@@ -3,6 +3,8 @@
namespace Maps;
use ParamProcessor\ParamDefinition;
+use ParamProcessor\ProcessedParam;
+use ParamProcessor\ProcessingResult;
/**
* @licence GNU GPL v2+
@@ -28,6 +30,8 @@ interface MappingService {
*/
public function getResourceModules(): array;
- public function newMapId();
+ public function newMapId(): string;
+
+ public function processingResultToMapParams( ProcessingResult $processingResult ): array;
}
diff --git a/www/wiki/extensions/Maps/src/MapsFactory.php b/www/wiki/extensions/Maps/src/MapsFactory.php
index 6ab23d5d..a8fd1338 100644
--- a/www/wiki/extensions/Maps/src/MapsFactory.php
+++ b/www/wiki/extensions/Maps/src/MapsFactory.php
@@ -4,6 +4,7 @@ declare( strict_types = 1 );
namespace Maps;
+use DataValues\Geo\Parsers\LatLongParser;
use FileFetcher\Cache\Factory as CacheFactory;
use FileFetcher\FileFetcher;
use Jeroen\SimpleGeocoder\Geocoder;
@@ -13,13 +14,22 @@ use Jeroen\SimpleGeocoder\Geocoders\FileFetchers\GoogleGeocoder;
use Jeroen\SimpleGeocoder\Geocoders\FileFetchers\NominatimGeocoder;
use Jeroen\SimpleGeocoder\Geocoders\NullGeocoder;
use Maps\DataAccess\CachingGeocoder;
+use Maps\DataAccess\GeoJsonFetcher;
use Maps\DataAccess\MapsFileFetcher;
use Maps\DataAccess\MediaWikiFileUrlFinder;
use Maps\DataAccess\PageContentFetcher;
use Maps\MediaWiki\ParserHooks\DisplayMapFunction;
use Maps\Presentation\CoordinateFormatter;
+use Maps\Presentation\WikitextParsers\CircleParser;
+use Maps\Presentation\WikitextParsers\DistanceParser;
+use Maps\Presentation\WikitextParsers\ImageOverlayParser;
+use Maps\Presentation\WikitextParsers\LineParser;
use Maps\Presentation\WikitextParsers\LocationParser;
+use Maps\Presentation\WikitextParsers\PolygonParser;
+use Maps\Presentation\WikitextParsers\RectangleParser;
+use Maps\Presentation\WikitextParsers\WmsOverlayParser;
use MediaWiki\MediaWikiServices;
+use ParamProcessor\ParamDefinitionFactory;
use SimpleCache\Cache\Cache;
use SimpleCache\Cache\MediaWikiCache;
@@ -165,4 +175,28 @@ class MapsFactory {
);
}
+ public function getParamDefinitionFactory(): ParamDefinitionFactory {
+ $factory = ParamDefinitionFactory::newDefault();
+
+ $factory->registerType( 'coordinate', [ 'string-parser' => LatLongParser::class ] );
+ $factory->registerType( 'mapslocation', [ 'string-parser' => LocationParser::class ] );
+ $factory->registerType( 'mapsline', [ 'string-parser' => LineParser::class ] );
+ $factory->registerType( 'mapscircle', [ 'string-parser' => CircleParser::class ] );
+ $factory->registerType( 'mapsrectangle', [ 'string-parser' => RectangleParser::class ] );
+ $factory->registerType( 'mapspolygon', [ 'string-parser' => PolygonParser::class ] );
+ $factory->registerType( 'distance', [ 'string-parser' => DistanceParser::class ] );
+ $factory->registerType( 'wmsoverlay', [ 'string-parser' => WmsOverlayParser::class ] );
+ $factory->registerType( 'mapsimageoverlay', [ 'string-parser' => ImageOverlayParser::class ] );
+
+ return $factory;
+ }
+
+ public function newGeoJsonFetcher( FileFetcher $fileFetcher = null ): GeoJsonFetcher {
+ return new GeoJsonFetcher(
+ $fileFetcher ?? $this->getGeoJsonFileFetcher(),
+ $this->mediaWikiServices->getTitleParser(),
+ $this->mediaWikiServices->getRevisionLookup()
+ );
+ }
+
}
diff --git a/www/wiki/extensions/Maps/src/MapsFunctions.php b/www/wiki/extensions/Maps/src/MapsFunctions.php
index 47cd1358..06274cc1 100644
--- a/www/wiki/extensions/Maps/src/MapsFunctions.php
+++ b/www/wiki/extensions/Maps/src/MapsFunctions.php
@@ -75,24 +75,19 @@ final class MapsFunctions {
public static function getCommonParameters() {
$params = [];
- $params['mappingservice'] = [
- 'type' => 'string',
- 'aliases' => 'service',
- 'default' => $GLOBALS['egMapsDefaultService'],
- 'values' => MapsFactory::globalInstance()->getMappingServices()->getAllNames(),
- ];
-
$params['width'] = [
'type' => 'dimension',
'allowauto' => true,
'units' => [ 'px', 'ex', 'em', '%', '' ],
'default' => $GLOBALS['egMapsMapWidth'],
+ 'message' => 'maps-par-width',
];
$params['height'] = [
'type' => 'dimension',
'units' => [ 'px', 'ex', 'em', '' ],
'default' => $GLOBALS['egMapsMapHeight'],
+ 'message' => 'maps-par-height',
];
$params['centre'] = [
@@ -100,16 +95,9 @@ final class MapsFunctions {
'aliases' => [ 'center' ],
'default' => false,
'manipulatedefault' => false,
+ 'message' => 'maps-par-centre',
];
- // Give grep a chance to find the usages:
- // maps-par-mappingservice, maps-par-geoservice, maps-par-width,
- // maps-par-height, maps-par-centre
- foreach ( $params as $name => &$data ) {
- $data['name'] = $name;
- $data['message'] = 'maps-par-' . $name;
- }
-
$params['title'] = [
'name' => 'title',
'default' => $GLOBALS['egMapsDefaultTitle'],
@@ -124,10 +112,6 @@ final class MapsFunctions {
'default' => '',
];
- $params['visitedicon'] = [
- 'default' => '',
- ];
-
$params['lines'] = [
'type' => 'mapsline',
'default' => [],
@@ -156,12 +140,6 @@ final class MapsFunctions {
'islist' => true,
];
- $params['wmsoverlay'] = [
- 'type' => 'wmsoverlay',
- 'default' => false,
- 'delimiter' => ' ',
- ];
-
$params['maxzoom'] = [
'type' => 'integer',
'default' => false,
@@ -188,8 +166,8 @@ final class MapsFunctions {
// Give grep a chance to find the usages:
// maps-displaymap-par-title, maps-displaymap-par-label, maps-displaymap-par-icon,
- // maps-displaymap-par-visitedicon, aps-displaymap-par-lines, maps-displaymap-par-polygons,
- // maps-displaymap-par-circles, maps-displaymap-par-rectangles, maps-displaymap-par-wmsoverlay,
+ // aps-displaymap-par-lines, maps-displaymap-par-polygons,
+ // maps-displaymap-par-circles, maps-displaymap-par-rectangles,
// maps-displaymap-par-maxzoom, maps-displaymap-par-minzoom, maps-displaymap-par-copycoords,
// maps-displaymap-par-static
foreach ( $params as $name => &$param ) {
diff --git a/www/wiki/extensions/Maps/src/MapsSetup.php b/www/wiki/extensions/Maps/src/MapsSetup.php
index 245d3915..d682339b 100644
--- a/www/wiki/extensions/Maps/src/MapsSetup.php
+++ b/www/wiki/extensions/Maps/src/MapsSetup.php
@@ -5,7 +5,7 @@ declare( strict_types = 1 );
namespace Maps;
use DataValues\Geo\Parsers\LatLongParser;
-use Maps\DataAccess\JsonFileParser;
+use Maps\DataAccess\GeoJsonFetcher;
use Maps\MediaWiki\Content\GeoJsonContent;
use Maps\MediaWiki\Content\GeoJsonContentHandler;
use Maps\MediaWiki\ParserHooks\CoordinatesFunction;
@@ -47,15 +47,6 @@ class MapsSetup {
}
}
- private function registerAllTheThings() {
- $this->registerParserHooks();
- $this->registerPermissions();
- $this->registerParameterTypes();
- $this->registerHooks();
-
- $this->mwGlobals['wgContentHandlers'][GeoJsonContent::CONTENT_MODEL_ID] = GeoJsonContentHandler::class;
- }
-
private function defaultSettings() {
if ( $this->mwGlobals['egMapsGMaps3Language'] === '' ) {
$this->mwGlobals['egMapsGMaps3Language'] = $this->mwGlobals['wgLang'];
@@ -74,6 +65,15 @@ class MapsSetup {
}
}
+ private function registerAllTheThings() {
+ $this->registerParserHooks();
+ $this->registerPermissions();
+ $this->registerParameterTypes();
+ $this->registerHooks();
+ $this->registerGeoJsonContentModel();
+ $this->registerEditApiModuleFallbacks();
+ }
+
private function registerParserHooks() {
if ( $this->mwGlobals['egMapsEnableCoordinateFunction'] ) {
$this->mwGlobals['wgHooks']['ParserFirstCallInit'][] = function ( Parser &$parser ) {
@@ -109,13 +109,7 @@ class MapsSetup {
$hookName,
function ( $text, array $arguments, Parser $parser ) {
if ( $text !== null ) {
- $defaultParameters = DisplayMapFunction::getHookDefinition( "\n" )->getDefaultParameters();
- $defaultParam = array_shift( $defaultParameters );
-
- // If there is a first default parameter, set the tag contents as its value.
- if ( $defaultParam !== null ) {
- $arguments[$defaultParam] = $text;
- }
+ $arguments[DisplayMapFunction::getDefaultParameters()[0]] = $text;
}
return MapsFactory::newDefault()->getDisplayMapFunction()->getMapHtmlForParameterList( $parser, $arguments );
@@ -192,15 +186,66 @@ class MapsSetup {
$this->mwGlobals['wgParamDefinitions']['mapsimageoverlay'] = [
'string-parser' => ImageOverlayParser::class,
];
-
- $this->mwGlobals['wgParamDefinitions']['jsonfile'] = [
- 'string-parser' => JsonFileParser::class,
- ];
}
private function registerHooks() {
$this->mwGlobals['wgHooks']['AdminLinks'][] = 'Maps\MediaWiki\MapsHooks::addToAdminLinks';
$this->mwGlobals['wgHooks']['MakeGlobalVariablesScript'][] = 'Maps\MediaWiki\MapsHooks::onMakeGlobalVariablesScript';
+ $this->mwGlobals['wgHooks']['SkinTemplateNavigation'][] = 'Maps\MediaWiki\MapsHooks::onSkinTemplateNavigation';
+ $this->mwGlobals['wgHooks']['BeforeDisplayNoArticleText'][] = 'Maps\MediaWiki\MapsHooks::onBeforeDisplayNoArticleText';
+ $this->mwGlobals['wgHooks']['ShowMissingArticle'][] = 'Maps\MediaWiki\MapsHooks::onShowMissingArticle';
+ $this->mwGlobals['wgHooks']['ListDefinedTags'][] = 'Maps\MediaWiki\MapsHooks::onRegisterTags';
+ $this->mwGlobals['wgHooks']['ChangeTagsListActive'][] = 'Maps\MediaWiki\MapsHooks::onRegisterTags';
+ $this->mwGlobals['wgHooks']['ChangeTagsAllowedAdd'][] = 'Maps\MediaWiki\MapsHooks::onChangeTagsAllowedAdd';
+ $this->mwGlobals['wgHooks']['ResourceLoaderTestModules'][] = 'Maps\MediaWiki\MapsHooks::onResourceLoaderTestModules';
+ }
+
+ private function registerGeoJsonContentModel() {
+ $this->mwGlobals['wgContentHandlers'][GeoJsonContent::CONTENT_MODEL_ID] = GeoJsonContentHandler::class;
+ }
+
+ private function registerEditApiModuleFallbacks() {
+ // mediawiki.api.edit is present in 1.31 but not 1.32
+ // Once Maps requires MW 1.32+, this can be removed after replacing usage of mediawiki.api.edit
+ if ( version_compare( $this->mwGlobals['wgVersion'], '1.32', '>=' ) ) {
+ $this->mwGlobals['wgResourceModules']['mediawiki.api.edit'] = [
+ 'dependencies' => [
+ 'mediawiki.api'
+ ],
+ 'targets' => [ 'desktop', 'mobile' ]
+ ];
+ }
+
+ // 1.35 combines the jquery.ui modules into one
+ if ( version_compare( $this->mwGlobals['wgVersion'], '1.35', '>=' ) ) {
+ $this->mwGlobals['wgResourceModules']['jquery.ui.resizable'] = [
+ 'dependencies' => [
+ 'jquery.ui'
+ ],
+ 'targets' => [ 'desktop', 'mobile' ]
+ ];
+
+ $this->mwGlobals['wgResourceModules']['jquery.ui.autocomplete'] = [
+ 'dependencies' => [
+ 'jquery.ui'
+ ],
+ 'targets' => [ 'desktop', 'mobile' ]
+ ];
+
+ $this->mwGlobals['wgResourceModules']['jquery.ui.slider'] = [
+ 'dependencies' => [
+ 'jquery.ui'
+ ],
+ 'targets' => [ 'desktop', 'mobile' ]
+ ];
+
+ $this->mwGlobals['wgResourceModules']['jquery.ui.dialog'] = [
+ 'dependencies' => [
+ 'jquery.ui'
+ ],
+ 'targets' => [ 'desktop', 'mobile' ]
+ ];
+ }
}
}
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContent.php b/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContent.php
index 72a89b04..c6eaae23 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContent.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContent.php
@@ -2,48 +2,55 @@
namespace Maps\MediaWiki\Content;
-use Html;
+use FormatJson;
+use Maps\Presentation\GeoJsonMapPageUi;
+use Maps\Presentation\OutputFacade;
use ParserOptions;
use ParserOutput;
+use Status;
use Title;
class GeoJsonContent extends \JsonContent {
public const CONTENT_MODEL_ID = 'GeoJSON';
+ public static function newEmptyContentString(): string {
+ $text = '{"type": "FeatureCollection", "features": []}';
+ return FormatJson::encode( FormatJson::parse( $text )->getValue(), true, FormatJson::UTF8_OK );
+ }
+
public function __construct( string $text, string $modelId = self::CONTENT_MODEL_ID ) {
- parent::__construct( $text, $modelId );
+ parent::__construct(
+ $text,
+ $modelId
+ );
+ }
+
+ public function getData(): Status {
+ $status = parent::getData();
+
+ if ( $status->isGood() && !$this->isGeoJson( $status->getValue() ) ) {
+ return Status::newFatal( 'Invalid GeoJson' );
+ }
+
+ return $status;
+ }
+
+ private function isGeoJson( $json ): bool {
+ return property_exists( $json, 'type' )
+ && $json->type === 'FeatureCollection'
+ && property_exists( $json, 'features' )
+ && is_array( $json->features );
}
protected function fillParserOutput( Title $title, $revId, ParserOptions $options,
$generateHtml, ParserOutput &$output ) {
if ( $generateHtml && $this->isValid() ) {
- $output->setText( $this->getMapHtml( $this->beautifyJSON() ) );
- $output->addModules( 'ext.maps.leaflet.editor' );
+ ( GeoJsonMapPageUi::forExistingPage( $this->beautifyJSON() ) )->addToOutput( OutputFacade::newFromParserOutput( $output ) );
} else {
$output->setText( '' );
}
}
- private function getMapHtml( string $jsonString ): string {
- return
- Html::element(
- 'div',
- [
- 'id' => 'GeoJsonMap',
- 'class' => 'GeoJsonMap',
- ]
- )
- . '<style>'
- . '.GeoJsonMap {width: "100%"; height: 600px; display: "inline-block"}'
- . '</style>'
- .
- Html::element(
- 'script',
- [],
- 'var GeoJson =' . $jsonString . ';'
- );
- }
-
-} \ No newline at end of file
+}
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContentHandler.php b/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContentHandler.php
index b192a9c3..de6c38b1 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContentHandler.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/Content/GeoJsonContentHandler.php
@@ -12,4 +12,8 @@ class GeoJsonContentHandler extends \JsonContentHandler {
return GeoJsonContent::class;
}
-} \ No newline at end of file
+ public function makeEmptyContent() {
+ return new GeoJsonContent( GeoJsonContent::newEmptyContentString() );
+ }
+
+}
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/MapsHooks.php b/www/wiki/extensions/Maps/src/MediaWiki/MapsHooks.php
index e2a8ad95..9cefac2d 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/MapsHooks.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/MapsHooks.php
@@ -1,9 +1,13 @@
<?php
+
namespace Maps\MediaWiki;
use AlItem;
use ALTree;
+use Maps\Presentation\GeoJsonNewPageUi;
+use Maps\Presentation\OutputFacade;
+use SkinTemplate;
/**
* Static class for hooks handled by the Maps extension.
@@ -59,10 +63,67 @@ final class MapsHooks {
$vars['egMapsDebugJS'] = $GLOBALS['egMapsDebugJS'];
$vars['egMapsAvailableServices'] = $GLOBALS['egMapsAvailableServices'];
$vars['egMapsLeafletLayersApiKeys'] = $GLOBALS['egMapsLeafletLayersApiKeys'];
+ $vars['egMapsLeafletLayersDark'] = $GLOBALS['egMapsLeafletLayersDark'];
$vars += $GLOBALS['egMapsGlobalJSVars'];
return true;
}
+ public static function onSkinTemplateNavigation( SkinTemplate $skinTemplate, array &$links ) {
+ if ( $skinTemplate->getTitle() === null ) {
+ return true;
+ }
+
+ if ( $skinTemplate->getTitle()->getNamespace() === NS_GEO_JSON ) {
+ if ( array_key_exists( 'edit', $links['views'] ) ) {
+ $links['views']['edit']['text'] = wfMessage(
+ $skinTemplate->getTitle()->exists() ? 'maps-geo-json-edit-source': 'maps-geo-json-create-source'
+ );
+ }
+ }
+
+ return true;
+ }
+
+ public static function onBeforeDisplayNoArticleText( \Article $article ) {
+ return !self::shouldShowGeoJsonCreatePageUi( $article );
+ }
+
+ public static function onShowMissingArticle( \Article $article ) {
+ if ( self::shouldShowGeoJsonCreatePageUi( $article ) ) {
+ $ui = new GeoJsonNewPageUi( OutputFacade::newFromOutputPage( $article->getContext()->getOutput() ) );
+ $ui->addToOutput();
+ }
+
+ return true;
+ }
+
+ private static function shouldShowGeoJsonCreatePageUi( \Article $article ): bool {
+ return $article->getTitle()->getNamespace() === NS_GEO_JSON
+ && $article->getContext()->getUser()->isAllowed( 'createpage' );
+ }
+
+ public static function onRegisterTags( array &$tags ) {
+ $tags[] = 'maps-visual-edit';
+ return true;
+ }
+
+ public static function onChangeTagsAllowedAdd( array &$allowedTags, array $tags, \User $user = null ) {
+ $allowedTags[] = 'maps-visual-edit';
+ }
+
+ public static function onResourceLoaderTestModules( array &$modules, $resourceLoader ) {
+ $modules['qunit']['ext.maps.test'] = [
+ 'scripts' => [
+ 'tests/js/leaflet/GeoJsonTest.js',
+ ],
+ 'dependencies' => [
+ 'ext.maps.leaflet.geojson',
+ ],
+ 'localBasePath' => __DIR__ . '/../../',
+ 'remoteExtPath' => 'Maps'
+ ];
+ }
+
}
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapFunction.php b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapFunction.php
index bad0d842..5d64b52e 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapFunction.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapFunction.php
@@ -3,12 +3,12 @@
namespace Maps\MediaWiki\ParserHooks;
use Maps;
-use Maps\MapsFunctions;
+use Maps\MappingService;
use Maps\MappingServices;
+use Maps\MapsFactory;
use Maps\Presentation\ParameterExtractor;
use MWException;
-use ParamProcessor;
-use ParamProcessor\ProcessedParam;
+use ParamProcessor\Processor;
use Parser;
/**
@@ -38,7 +38,7 @@ class DisplayMapFunction {
* @throws MWException
*/
public function getMapHtmlForKeyValueStrings( Parser $parser, array $parameters ): string {
- $processor = new \ParamProcessor\Processor( new \ParamProcessor\Options() );
+ $processor = new Processor( new \ParamProcessor\Options() );
$service = $this->services->getServiceOrDefault(
$this->extractServiceName(
@@ -50,14 +50,20 @@ class DisplayMapFunction {
$processor->setFunctionParams(
$parameters,
- array_merge(
- self::getHookDefinition( ';' )->getParameters(),
- $service->getParameterInfo()
- ),
- self::getHookDefinition( ';' )->getDefaultParameters()
+ [],
+ self::getDefaultParameters()
+ );
+
+ $processor->setParameterDefinitions(
+ $this->getAllParameterDefinitions( $service, ';' )
);
- return $this->getMapHtmlFromProcessor( $parser, $processor );
+ $this->trackMap( $parser );
+
+ return $this->renderer->renderMap(
+ $service->processingResultToMapParams( $processor->processParameters() ),
+ $parser
+ );
}
/**
@@ -69,65 +75,35 @@ class DisplayMapFunction {
* @throws MWException
*/
public function getMapHtmlForParameterList( Parser $parser, array $parameters ) {
- $processor = new \ParamProcessor\Processor( new \ParamProcessor\Options() );
+ $processor = new Processor( new \ParamProcessor\Options() );
$service = $this->services->getServiceOrDefault( $this->extractServiceName( $parameters ) );
$this->renderer->service = $service;
- $processor->setParameters(
- $parameters,
- array_merge(
- self::getHookDefinition( "\n" )->getParameters(),
- $service->getParameterInfo()
- )
+ $processor->setParameters( $parameters );
+ $processor->setParameterDefinitions(
+ $this->getAllParameterDefinitions( $service, "\n" )
);
- return $this->getMapHtmlFromProcessor( $parser, $processor );
- }
-
- private function getMapHtmlFromProcessor( Parser $parser, ParamProcessor\Processor $processor ) {
- $params = $processor->processParameters()->getParameters();
-
- $this->defaultMapZoom( $params );
-
$this->trackMap( $parser );
return $this->renderer->renderMap(
- $this->processedParametersToKeyValueArray( $params ),
+ $service->processingResultToMapParams( $processor->processParameters() ),
$parser
);
}
- private function extractServiceName( array $parameters ): string {
- $service = ( new ParameterExtractor() )->extract(
- [ 'mappingservice', 'service' ],
- $parameters
- );
-
- return $service ?? '';
- }
-
- private function processedParametersToKeyValueArray( array $params ): array {
- $parameters = [];
-
- foreach ( $params as $parameter ) {
- $parameters[$parameter->getName()] = $parameter->getValue();
- }
+ private function getAllParameterDefinitions( MappingService $service, string $locationDelimiter ) {
+ $params = [];
- return $parameters;
- }
-
- public static function getHookDefinition( string $locationDelimiter ): \ParserHooks\HookDefinition {
- return new \ParserHooks\HookDefinition(
- [ 'display_map', 'display_point', 'display_points', 'display_line' ],
- self::getParameterDefinitions( $locationDelimiter ),
- [ 'coordinates' ]
- );
- }
-
- private static function getParameterDefinitions( $locationDelimiter ): array {
- $params = MapsFunctions::getCommonParameters();
+ $params['mappingservice'] = [
+ 'type' => 'string',
+ 'aliases' => 'service',
+ 'default' => $GLOBALS['egMapsDefaultService'],
+ 'values' => MapsFactory::globalInstance()->getMappingServices()->getAllNames(),
+ 'message' => 'maps-par-mappingservice'
+ ];
$params['coordinates'] = [
'type' => 'string',
@@ -138,28 +114,25 @@ class DisplayMapFunction {
'message' => 'maps-displaymap-par-coordinates',
];
- return $params;
+ return MapsFactory::globalInstance()->getParamDefinitionFactory()->newDefinitionsFromArrays(
+ array_merge(
+ $params,
+ $service->getParameterInfo()
+ )
+ );
}
- /**
- * @param ProcessedParam[] $parameters
- */
- private function defaultMapZoom( array &$parameters ) {
- if ( array_key_exists( 'zoom', $parameters ) && $parameters['zoom']->wasSetToDefault() && count(
- $parameters['coordinates']->getValue()
- ) > 1 ) {
- $parameters['zoom'] = $this->getParameterWithValue( $parameters['zoom'], false );
- }
+ private function extractServiceName( array $parameters ): string {
+ $service = ( new ParameterExtractor() )->extract(
+ [ 'mappingservice', 'service' ],
+ $parameters
+ );
+
+ return $service ?? '';
}
- private function getParameterWithValue( ProcessedParam $param, $value ) {
- return new ProcessedParam(
- $param->getName(),
- $value,
- $param->wasSetToDefault(),
- $param->getOriginalName(),
- $param->getOriginalValue()
- );
+ public static function getDefaultParameters(): array {
+ return [ 'coordinates' ];
}
private function trackMap( Parser $parser ) {
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php
index 8c757acd..4fcb93ba 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/DisplayMapRenderer.php
@@ -2,8 +2,6 @@
namespace Maps\MediaWiki\ParserHooks;
-use FormatJson;
-use Html;
use Maps\DataAccess\MediaWikiFileUrlFinder;
use Maps\Elements\Location;
use Maps\MappingService;
@@ -92,7 +90,8 @@ class DisplayMapRenderer {
private function handleMarkerData( array &$params ) {
$params['centre'] = $this->getCenter( $params['centre'] );
- if ( is_object( $params['wmsoverlay'] ) ) {
+ // FIXME: this parameter is google maps service specific
+ if ( array_key_exists( 'wmsoverlay', $params ) && is_object( $params['wmsoverlay'] ) ) {
$params['wmsoverlay'] = $params['wmsoverlay']->getJSONObject();
}
@@ -122,7 +121,7 @@ class DisplayMapRenderer {
private function getLocationJson( array $params ) {
$iconUrl = $this->fileUrlFinder->getUrlForFileName( $params['icon'] );
- $visitedIconUrl = $this->fileUrlFinder->getUrlForFileName( $params['visitedicon'] );
+ $visitedIconUrl = $this->fileUrlFinder->getUrlForFileName( $params['visitedicon'] ?? '' );
$locationJsonObjects = [];
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/FindDestinationFunction.php b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/FindDestinationFunction.php
index e7cb319c..05859ca0 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/FindDestinationFunction.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/FindDestinationFunction.php
@@ -3,8 +3,8 @@
namespace Maps\MediaWiki\ParserHooks;
use DataValues\Geo\Values\LatLongValue;
-use Maps\MapsFactory;
use Maps\GeoFunctions;
+use Maps\MapsFactory;
use ParserHook;
/**
@@ -117,4 +117,4 @@ class FindDestinationFunction extends ParserHook {
return [ 'location', 'bearing', 'distance' ];
}
-} \ No newline at end of file
+}
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/MapsDocFunction.php b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/MapsDocFunction.php
index 6a365378..e294736b 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/MapsDocFunction.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/ParserHooks/MapsDocFunction.php
@@ -2,7 +2,6 @@
namespace Maps\MediaWiki\ParserHooks;
-use Maps\MappingServices;
use Maps\MapsFactory;
use ParamProcessor\ParamDefinition;
use ParserHook;
@@ -35,12 +34,14 @@ class MapsDocFunction extends ParserHook {
public function render( array $parameters ) {
$this->language = $parameters['language'];
- $params = $this->getServiceParameters( $parameters['service'] );
+ $factory = MapsFactory::globalInstance();
- return $this->getParameterTable( $params );
+ $params = $this->getServiceParameters( $factory, $parameters['service'] );
+
+ return $this->getParameterTable( $factory, $params );
}
- private function getServiceParameters( $service ) {
+ private function getServiceParameters( MapsFactory $factory, string $service ) {
return array_merge(
[
'zoom' => [
@@ -48,21 +49,17 @@ class MapsDocFunction extends ParserHook {
'message' => 'maps-par-zoom',
]
],
- MapsFactory::globalInstance()->getMappingServices()->getService( $service )->getParameterInfo()
+ $factory->getMappingServices()->getService( $service )->getParameterInfo()
);
}
/**
* Returns the wikitext for a table listing the provided parameters.
- *
- * @param array $parameters
- *
- * @return string
*/
- private function getParameterTable( array $parameters ) {
+ private function getParameterTable( MapsFactory $factory, array $parameters ): string {
$tableRows = [];
- $parameters = ParamDefinition::getCleanDefinitions( $parameters );
+ $parameters = $factory->getParamDefinitionFactory()->newDefinitionsFromArrays( $parameters );
foreach ( $parameters as $parameter ) {
$tableRows[] = $this->getDescriptionRow( $parameter );
diff --git a/www/wiki/extensions/Maps/src/MediaWiki/Specials/SpecialMapEditor.php b/www/wiki/extensions/Maps/src/MediaWiki/Specials/SpecialMapEditor.php
index 76b5dad5..0226113e 100644
--- a/www/wiki/extensions/Maps/src/MediaWiki/Specials/SpecialMapEditor.php
+++ b/www/wiki/extensions/Maps/src/MediaWiki/Specials/SpecialMapEditor.php
@@ -3,7 +3,6 @@
namespace Maps\MediaWiki\Specials;
use Maps\GoogleMapsService;
-use Maps\MediaWiki\Specials\MapEditorHtml;
use SpecialPage;
/**
@@ -45,7 +44,7 @@ class SpecialMapEditor extends SpecialPage {
)
);
- $outputPage->addModules( 'mapeditor' );
+ $outputPage->addModules( 'ext.maps.wikitext.editor' );
$editorHtml = new MapEditorHtml( $this->getAttribs() );
$html = $editorHtml->getEditorHtml();
$outputPage->addHTML( $html );
diff --git a/www/wiki/extensions/Maps/src/Presentation/GeoJsonMapPageUi.php b/www/wiki/extensions/Maps/src/Presentation/GeoJsonMapPageUi.php
new file mode 100644
index 00000000..89440f1f
--- /dev/null
+++ b/www/wiki/extensions/Maps/src/Presentation/GeoJsonMapPageUi.php
@@ -0,0 +1,83 @@
+<?php
+
+declare( strict_types = 1 );
+
+namespace Maps\Presentation;
+
+use Html;
+
+class GeoJsonMapPageUi {
+
+ private $json;
+
+ public static function forExistingPage( string $mapJson ): self {
+ return new self( $mapJson );
+ }
+
+ private function __construct( ?string $json ) {
+ $this->json = $json;
+ }
+
+ public function addToOutput( OutputFacade $output ) {
+ $leafletPath = $GLOBALS['wgScriptPath'] . '/extensions/Maps/resources/lib/leaflet';
+
+ $output->addHeadItem(
+ 'MapsGeoJsonHeadItem',
+ Html::linkedStyle( "$leafletPath/leaflet.css" ) . Html::linkedScript( "$leafletPath/leaflet.js" )
+ );
+
+ $output->addHTML( $this->getJavascript() . $this->getHtml() );
+ $output->addModules( 'ext.maps.geojson.page' );
+ }
+
+ private function getJavascript(): string {
+ return Html::element(
+ 'script',
+ [],
+ $this->getJsonJs()
+ );
+ }
+
+ private function getJsonJs(): string {
+ return 'var GeoJson ='
+ . $this->json
+ . ';';
+ }
+
+ private function getHtml(): string {
+ return $this->wrapHtmlInThumbDivs(
+ Html::rawElement(
+ 'div',
+ [
+ 'id' => 'GeoJsonMap',
+ 'style' => 'width: 100%; height: 600px; background-color: #eeeeee; overflow: hidden;',
+ 'class' => 'maps-map maps-leaflet maps-geojson-editor'
+ ],
+ Html::element(
+ 'div',
+ [
+ 'class' => 'maps-loading-message'
+ ],
+ wfMessage( 'maps-loading-map' )->inContentLanguage()->text()
+ )
+ )
+ );
+ }
+
+ private function wrapHtmlInThumbDivs( string $html ): string {
+ return Html::rawElement(
+ 'div',
+ [
+ 'class' => 'thumb'
+ ],
+ Html::rawElement(
+ 'div',
+ [
+ 'class' => 'thumbinner'
+ ],
+ $html
+ )
+ );
+ }
+
+}
diff --git a/www/wiki/extensions/Maps/src/Presentation/GeoJsonNewPageUi.php b/www/wiki/extensions/Maps/src/Presentation/GeoJsonNewPageUi.php
new file mode 100644
index 00000000..5de1df71
--- /dev/null
+++ b/www/wiki/extensions/Maps/src/Presentation/GeoJsonNewPageUi.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Maps\Presentation;
+
+class GeoJsonNewPageUi {
+
+ private $output;
+
+ public function __construct( OutputFacade $output ) {
+ $this->output = $output;
+ }
+
+ public function addToOutput() {
+ $this->output->addModules( 'ext.maps.geojson.new.page' );
+
+ $this->output->addHtml(
+ \Html::element(
+ 'button',
+ [
+ 'id' => 'maps-geojson-new'
+ ],
+ wfMessage( 'maps-geo-json-create-page-button' )->inContentLanguage()->text()
+ )
+ );
+ }
+
+}
diff --git a/www/wiki/extensions/Maps/src/Presentation/MapHtmlBuilder.php b/www/wiki/extensions/Maps/src/Presentation/MapHtmlBuilder.php
index aa47e558..7d74ad34 100644
--- a/www/wiki/extensions/Maps/src/Presentation/MapHtmlBuilder.php
+++ b/www/wiki/extensions/Maps/src/Presentation/MapHtmlBuilder.php
@@ -22,12 +22,18 @@ class MapHtmlBuilder {
'div',
[
'id' => $mapName,
- 'style' => "width: {$params['width']}; height: {$params['height']}; background-color: #cccccc; overflow: hidden;",
+ 'style' => "width: {$params['width']}; height: {$params['height']}; background-color: #eeeeee; overflow: hidden;",
'class' => 'maps-map maps-' . $serviceName
],
- wfMessage( 'maps-loading-map' )->inContentLanguage()->escaped() .
Html::element(
'div',
+ [
+ 'class' => 'maps-loading-message'
+ ],
+ wfMessage( 'maps-loading-map' )->inContentLanguage()->text()
+ )
+ . Html::element(
+ 'div',
[ 'style' => 'display:none', 'class' => 'mapdata' ],
FormatJson::encode( $params )
)
diff --git a/www/wiki/extensions/Maps/src/Presentation/MapsDistanceParser.php b/www/wiki/extensions/Maps/src/Presentation/MapsDistanceParser.php
index c8fb0ef1..7c0d595a 100644
--- a/www/wiki/extensions/Maps/src/Presentation/MapsDistanceParser.php
+++ b/www/wiki/extensions/Maps/src/Presentation/MapsDistanceParser.php
@@ -99,7 +99,7 @@ class MapsDistanceParser {
$strlen = strlen( $distance );
for ( $i = 0; $i < $strlen; $i++ ) {
- if ( !ctype_digit( $distance{$i} ) && !in_array( $distance{$i}, [ ',', '.' ] ) ) {
+ if ( !ctype_digit( $distance[$i] ) && !in_array( $distance[$i], [ ',', '.' ] ) ) {
$value = substr( $distance, 0, $i );
$unit = substr( $distance, $i );
break;
diff --git a/www/wiki/extensions/Maps/src/Presentation/OutputFacade.php b/www/wiki/extensions/Maps/src/Presentation/OutputFacade.php
new file mode 100644
index 00000000..119f3b1d
--- /dev/null
+++ b/www/wiki/extensions/Maps/src/Presentation/OutputFacade.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Maps\Presentation;
+
+use OutputPage;
+use ParserOutput;
+
+class OutputFacade {
+
+ /**
+ * @var OutputPage
+ */
+ private $outputPage;
+
+ /**
+ * @var ParserOutput
+ */
+ private $parserOutput;
+
+ public static function newFromOutputPage( OutputPage $outputPage ) {
+ $instance = new self();
+ $instance->outputPage = $outputPage;
+ return $instance;
+ }
+
+ public static function newFromParserOutput( ParserOutput $parserOutput ) {
+ $instance = new self();
+ $instance->parserOutput = $parserOutput;
+ return $instance;
+ }
+
+ public function addHtml( string $html ) {
+ if ( $this->outputPage !== null ) {
+ $this->outputPage->addHTML( $html );
+ }
+
+ if ( $this->parserOutput !== null ) {
+ $this->parserOutput->setText( $this->parserOutput->getRawText() . $html );
+ }
+ }
+
+ public function addModules( string ...$modules ) {
+ if ( $this->outputPage !== null ) {
+ $this->outputPage->addModules( $modules );
+ }
+
+ if ( $this->parserOutput !== null ) {
+ $this->parserOutput->addModules( $modules );
+ }
+ }
+
+ public function addHeadItem( string $name, string $html ) {
+ if ( $this->outputPage !== null ) {
+ $this->outputPage->addHeadItem( $name, $html );
+ }
+
+ if ( $this->parserOutput !== null ) {
+ $this->parserOutput->addHeadItem( $html, $name );
+ }
+ }
+
+}
diff --git a/www/wiki/extensions/Maps/src/SemanticMW/ResultPrinters/MapPrinter.php b/www/wiki/extensions/Maps/src/SemanticMW/ResultPrinters/MapPrinter.php
index 6ab945f6..7a5f64b5 100644
--- a/www/wiki/extensions/Maps/src/SemanticMW/ResultPrinters/MapPrinter.php
+++ b/www/wiki/extensions/Maps/src/SemanticMW/ResultPrinters/MapPrinter.php
@@ -2,19 +2,15 @@
namespace Maps\SemanticMW\ResultPrinters;
-use FormatJson;
-use Html;
use Linker;
use Maps\Elements\BaseElement;
use Maps\Elements\Location;
use Maps\FileUrlFinder;
use Maps\MappingService;
-use Maps\MapsFunctions;
use Maps\Presentation\ElementJsonSerializer;
use Maps\Presentation\MapHtmlBuilder;
use Maps\Presentation\WikitextParser;
use Maps\Presentation\WikitextParsers\LocationParser;
-use ParamProcessor\ParamDefinition;
use Parser;
use SMW\Query\ResultPrinters\ResultPrinter;
use SMWOutputs;
@@ -113,6 +109,8 @@ class MapPrinter extends ResultPrinter {
return $this->fatalErrorMsg;
}
+ $this->isHTML = true;
+
$factory = \Maps\MapsFactory::newDefault();
$this->locationParser = $factory->newLocationParser();
$this->fileUrlFinder = $factory->getFileUrlFinder();
@@ -205,7 +203,7 @@ class MapPrinter extends ResultPrinter {
$params['centre'] = $this->getCenter( $params['centre'] );
$iconUrl = $this->fileUrlFinder->getUrlForFileName( $params['icon'] );
- $visitedIconUrl = $this->fileUrlFinder->getUrlForFileName( $params['visitedicon'] );
+ $visitedIconUrl = $this->fileUrlFinder->getUrlForFileName( $params['visitedicon'] ?? '' );
$params['locations'] = $this->getJsonForStaticLocations(
$params['staticlocations'],
@@ -318,10 +316,6 @@ class MapPrinter extends ResultPrinter {
$params = parent::getParameters();
$paramInfo = $this->getParameterInfo();
- // Do not display this as an option, as the format already determines it
- // TODO: this can probably be done cleaner with some changes in Maps
- unset( $paramInfo['mappingservice'] );
-
$params = array_merge( $params, $paramInfo );
return $params;
@@ -335,10 +329,7 @@ class MapPrinter extends ResultPrinter {
private function getParameterInfo() {
global $smgQPShowTitle, $smgQPTemplate, $smgQPHideNamespace;
- $params = array_merge(
- ParamDefinition::getCleanDefinitions( MapsFunctions::getCommonParameters() ),
- $this->service->getParameterInfo()
- );
+ $params = $this->service->getParameterInfo();
$params['staticlocations'] = [
'type' => 'mapslocation',