Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions DefaultSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@

// Boolean. Whether Maps configuration may also be set on the MediaWiki:Maps JSON config page,
// which is editable only by users with the editinterface and editsitejson rights. When false,
// that page is never read and only LocalSettings.php applies. The wiki page currently exposes
// the Leaflet layer settings; its values take precedence over LocalSettings.php.
// that page is never read and only LocalSettings.php applies. The wiki page exposes most Maps
// settings, grouped by service and topic (see the README); its values take precedence over
// LocalSettings.php. Secrets, script-injection primitives and setup-time switches stay PHP-only.
'egMapsEnableInWikiConfig' => true,


Expand Down
51 changes: 43 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,63 @@ via [Professional.Wiki](https://professional.wiki/). Discounts for work that is

## On-wiki configuration

Most settings are configured in `LocalSettings.php` (see the
[configuration documentation](https://maps.extension.wiki/wiki/Configuration)). Wiki administrators
without server access can also configure the Leaflet layers on the `MediaWiki:Maps` page. It holds
JSON and, like other site configuration, is editable only by users with the `editinterface` and
`editsitejson` rights. For example, to add a custom tile layer that authors can then select with the
`layers` parameter:
Most settings can be configured in `LocalSettings.php` (see the
[configuration documentation](https://maps.extension.wiki/wiki/Configuration)) or, for wiki
administrators without server access, on the `MediaWiki:Maps` page. It holds JSON and, like other
site configuration, is editable only by users with the `editinterface` and `editsitejson` rights.
Settings are grouped by service and topic:

```json
{
"general": {
"mapWidth": "100%",
"mapHeight": "500px",
"distanceUnit": "km"
},
"coordinates": {
"notation": "float",
"directional": false
},
"geocoding": {
"service": "google"
},
"leaflet": {
"defaultZoom": 5,
"layerDefinitions": {
"Historic 1904": {
"url": "https://tiles.example.org/historic1904/{z}/{x}/{y}.png",
"options": { "attribution": "Historic map tiles", "maxZoom": 18 }
}
}
},
"googleMaps": {
"zoom": 5,
"type": "satellite"
}
}
```

The page is validated when saved and combined with `LocalSettings.php`, with the wiki page taking
precedence. Changes take effect the next time a page with a map is parsed.
The available groups and keys correspond to `LocalSettings.php` settings:

* **general**: `mapWidth`, `mapHeight`, `defaultTitle`, `defaultLabel`, `resizableByDefault`,
`rezoomForKml`, `pagesWithMapsCategory`, `distanceUnits`, `distanceUnit`, `distanceDecimals`
* **coordinates**: `availableNotations`, `notation`, `directional`
* **geocoding**: `service` (`geonames`, `google` or `nominatim`)
* **semanticMediaWiki**: `showTitle`, `hideNamespace`, `template`, `coordinateFormat`,
`coordinateDirectional`
* **leaflet**: `layerDefinitions`, `defaultLayers`, `defaultOverlays`, `availableLayers`,
`availableOverlays`, `defaultZoom`
* **googleMaps**: `zoom`, `type`, `types`, `controls`, `typeControlStyle`, `zoomControlStyle`,
`autoInfoWindows`, `layers`, `showPoi`, `language`

The page is validated when saved and combined with `LocalSettings.php`, with the wiki value taking
precedence. Most settings are replaced wholesale; only `layerDefinitions`, `availableLayers` and
`availableOverlays` are merged per name, so the wiki only needs to list the entries it changes.
Changes take effect the next time a page with a map is parsed.

Secrets (API keys), settings that run before a wiki page can be read, and other server-only options
stay exclusive to `LocalSettings.php`. Set `$egMapsEnableInWikiConfig` to `false` to ignore the page
entirely.

## Project status

Expand Down
2 changes: 1 addition & 1 deletion RELEASE-NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ different releases and which versions of PHP and MediaWiki they support, see the

Released on TBD.

* Added an on-wiki JSON configuration page at `MediaWiki:Maps` for the Leaflet layer settings (custom layer definitions, the default and available base layers and overlays). It is editable only by administrators and interface administrators, is validated on save, and is combined with `LocalSettings.php` with the wiki page taking precedence. Set `$egMapsEnableInWikiConfig` to `false` to disable it.
* Added an on-wiki JSON configuration page at `MediaWiki:Maps` exposing most Maps settings, grouped by service and topic (general map, coordinate, geocoding, Semantic MediaWiki, Leaflet and Google Maps options), including the Leaflet custom layer definitions and available layers. It is editable only by administrators and interface administrators, is validated on save, and is combined with `LocalSettings.php` with the wiki page taking precedence. Secrets, script-injection primitives and setup-time settings stay exclusive to `LocalSettings.php`. Set `$egMapsEnableInWikiConfig` to `false` to disable it.
* Hardened the custom Leaflet layer definitions used by `$egMapsLeafletLayerDefinitions` and the config page (breaking change): the `url` and `errorTileUrl` must be `http(s)` URLs, only an allowlist of Leaflet `options` is kept, and `attribution` is sanitized to plain text and `http(s)` links. Definitions relying on raw HTML attribution or non-allowlisted options need updating.

## Maps 13.1.0
Expand Down
9 changes: 9 additions & 0 deletions i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,15 @@
"maps-config-error-invalid-json": "The configuration must be a JSON object.",
"maps-config-error-not-object": "The value of \"$1\" must be a JSON object.",
"maps-config-error-unknown-key": "Unknown configuration key \"$1\".",
"maps-config-error-invalid-boolean": "\"$1\" must be true or false.",
"maps-config-error-invalid-integer": "\"$1\" must be a whole number.",
"maps-config-error-integer-too-small": "\"$1\" must be $2 or greater.",
"maps-config-error-invalid-string": "\"$1\" must be text.",
"maps-config-error-invalid-enum": "\"$1\" must be one of: $2.",
"maps-config-error-invalid-enum-list": "\"$1\" must be a list containing only: $2.",
"maps-config-error-invalid-dimension": "\"$1\" must be a size such as 400, \"400px\" or \"auto\".",
"maps-config-error-invalid-number-map": "\"$1\" must be a map of names to positive numbers.",
"maps-config-error-invalid-language": "\"$1\" must be a valid language code, such as \"en\" or \"en-GB\".",
"maps-config-error-invalid-layer-name": "\"$1\" is not a valid layer name.",
"maps-config-error-unknown-layer-key": "Layer \"$1\" has an unknown property \"$2\".",
"maps-config-error-invalid-url": "Layer \"$1\" must have a \"url\" that starts with http:// or https://.",
Expand Down
13 changes: 11 additions & 2 deletions i18n/qqq.json
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,17 @@
"maps-validator-message-nodesc": "Indicates that no parameter description is available",
"maps-config-invalid": "Heading shown above the list of errors when an edit to the MediaWiki:Maps JSON config page is rejected.",
"maps-config-error-invalid-json": "Error shown when the MediaWiki:Maps config is not a JSON object.",
"maps-config-error-not-object": "Error shown when a value that must be a JSON object is not. $1 is the location, e.g. \"leaflet\" or \"layerDefinitions\".",
"maps-config-error-unknown-key": "Error shown when the config contains an unrecognized key. $1 is the unknown key.",
"maps-config-error-not-object": "Error shown when a value that must be a JSON object is not. $1 is the location, e.g. \"general\" or \"leaflet.layerDefinitions\".",
"maps-config-error-unknown-key": "Error shown when the config contains an unrecognized group or key. $1 is the unknown key, e.g. \"general\" or \"general.mapWidth\".",
"maps-config-error-invalid-boolean": "Error shown when a setting that must be a boolean is not. $1 is the location, e.g. \"general.resizableByDefault\".",
"maps-config-error-invalid-integer": "Error shown when a setting that must be a whole number is not. $1 is the location, e.g. \"leaflet.defaultZoom\".",
"maps-config-error-integer-too-small": "Error shown when a whole-number setting is below its minimum. $1 is the location, $2 is the minimum.",
"maps-config-error-invalid-string": "Error shown when a setting that must be text is not. $1 is the location, e.g. \"general.defaultTitle\".",
"maps-config-error-invalid-enum": "Error shown when a setting is not one of its allowed values. $1 is the location, $2 is the comma-separated list of allowed values.",
"maps-config-error-invalid-enum-list": "Error shown when a setting is not a list of allowed values. $1 is the location, $2 is the comma-separated list of allowed values.",
"maps-config-error-invalid-dimension": "Error shown when a map size setting is not a valid dimension. $1 is the location, e.g. \"general.mapWidth\".",
"maps-config-error-invalid-number-map": "Error shown when the distance units setting is not a map of names to positive numbers. $1 is the location.",
"maps-config-error-invalid-language": "Error shown when the Google Maps language setting is not a valid language code. $1 is the location.",
"maps-config-error-invalid-layer-name": "Error shown when a custom Leaflet layer has an invalid name. $1 is the name.",
"maps-config-error-unknown-layer-key": "Error shown when a custom Leaflet layer definition has an unrecognized property. $1 is the layer name, $2 is the property.",
"maps-config-error-invalid-url": "Error shown when a custom Leaflet layer has no valid url. $1 is the layer name.",
Expand Down
115 changes: 0 additions & 115 deletions src/CombiningLeafletConfigLookup.php

This file was deleted.

32 changes: 32 additions & 0 deletions src/Config/AvailabilityType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare( strict_types = 1 );

namespace Maps\Config;

/**
* A map of layer names to booleans, used for the available base layers and overlays. Merged per
* name with the PHP settings rather than replaced, so the wiki only needs to list the layers it
* changes.
*/
class AvailabilityType implements ConfigType {

public function validate( mixed $value, string $location ): array {
return $this->isAvailabilityMap( $value ) ? [] : [ [ 'maps-config-error-invalid-availability', $location ] ];
}

private function isAvailabilityMap( mixed $value ): bool {
if ( !is_array( $value ) || ( $value !== [] && array_is_list( $value ) ) ) {
return false;
}

foreach ( $value as $enabled ) {
if ( !is_bool( $enabled ) ) {
return false;
}
}

return true;
}

}
13 changes: 13 additions & 0 deletions src/Config/BooleanType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare( strict_types = 1 );

namespace Maps\Config;

class BooleanType implements ConfigType {

public function validate( mixed $value, string $location ): array {
return is_bool( $value ) ? [] : [ [ 'maps-config-error-invalid-boolean', $location ] ];
}

}
Loading
Loading