diff options
Diffstat (limited to 'www/wiki/extensions/Maps/src/MediaWiki')
8 files changed, 157 insertions, 117 deletions
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 ); |