Completed
Push — merge-sm ( 99c666...2dd49e )
by Jeroen De
73:58 queued 71:18
created

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 34 and the first side effect is on line 26.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * Initialization file for the Maps extension.
4
 *
5
 * @links https://github.com/JeroenDeDauw/Maps/blob/master/README.md#maps Documentation
6
 * @links https://github.com/JeroenDeDauw/Maps/issues Support
7
 * @links https://github.com/JeroenDeDauw/Maps Source code
8
 *
9
 * @license https://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
10
 * @author Jeroen De Dauw < [email protected] >
11
 */
12
13
use DataValues\Geo\Parsers\GeoCoordinateParser;
14
use FileFetcher\SimpleFileFetcher;
15
use Maps\CircleParser;
16
use Maps\DistanceParser;
17
use Maps\ImageOverlayParser;
18
use Maps\LineParser;
19
use Maps\LocationParser;
20
use Maps\PolygonParser;
21
use Maps\RectangleParser;
22
use Maps\ServiceParam;
23
use Maps\WmsOverlayParser;
24
25
if ( !defined( 'MEDIAWIKI' ) ) {
26
	die( 'Not an entry point.' );
27
}
28
29
if ( defined( 'Maps_VERSION' ) ) {
30
	// Do not initialize more than once.
31
	return 1;
32
}
33
34
define( 'Maps_VERSION' , '4.0-alpha' );
35
define( 'SM_VERSION', Maps_VERSION );
36
37
// Include the composer autoloader if it is present.
38
if ( is_readable( __DIR__ . '/vendor/autoload.php' ) ) {
39
	include_once( __DIR__ . '/vendor/autoload.php' );
40
}
41
42
// Only initialize the extension when all dependencies are present.
43
if ( !defined( 'Validator_VERSION' ) ) {
44
	throw new Exception( 'You need to have Validator installed in order to use Maps' );
45
}
46
47
if ( version_compare( $GLOBALS['wgVersion'], '1.23c' , '<' ) ) {
48
	throw new Exception(
49
		'This version of Maps requires MediaWiki 1.23 or above; use Maps 3.5.x for older versions.'
50
		. ' More information at https://github.com/JeroenDeDauw/Maps/blob/master/INSTALL.md'
51
	);
52
}
53
54
call_user_func( function() {
55
	$GLOBALS['wgExtensionCredits']['parserhook'][] = [
56
		'path' => __FILE__ ,
57
		'name' => 'Maps' ,
58
		'version' => Maps_VERSION ,
59
		'author' => [
60
			'[https://www.mediawiki.org/wiki/User:Jeroen_De_Dauw Jeroen De Dauw]',
61
			'...'
62
		] ,
63
		'url' => 'https://github.com/JeroenDeDauw/Maps/blob/master/README.md#maps' ,
64
		'descriptionmsg' => 'maps-desc',
65
		'license-name' => 'GPL-2.0+'
66
	];
67
68
	// The different coordinate notations.
69
	define( 'Maps_COORDS_FLOAT' , 'float' );
70
	define( 'Maps_COORDS_DMS' , 'dms' );
71
	define( 'Maps_COORDS_DM' , 'dm' );
72
	define( 'Maps_COORDS_DD' , 'dd' );
73
74
	$GLOBALS['egMapsStyleVersion'] = $GLOBALS['wgStyleVersion'] . '-' . Maps_VERSION;
75
76
	// Internationalization
77
	$GLOBALS['wgMessagesDirs']['Maps'] = __DIR__ . '/i18n';
78
	$GLOBALS['wgExtensionMessagesFiles']['MapsMagic'] = __DIR__ . '/Maps.i18n.magic.php';
79
	$GLOBALS['wgExtensionMessagesFiles']['MapsAlias'] = __DIR__ . '/Maps.i18n.alias.php';
80
81
	$GLOBALS['wgResourceModules'] = array_merge( $GLOBALS['wgResourceModules'], include 'Maps.resources.php' );
82
83
	$GLOBALS['wgAPIModules']['geocode'] = 'Maps\Api\Geocode';
84
85
	// Register the initialization function of Maps.
86
	$GLOBALS['wgExtensionFunctions'][] = function () {
87
88
		if ( $GLOBALS['egMapsGMaps3Language'] === '' ) {
89
			$GLOBALS['egMapsGMaps3Language'] = $GLOBALS['wgLang'];
90
		}
91
92
		Hooks::run( 'MappingServiceLoad' );
93
		Hooks::run( 'MappingFeatureLoad' );
94
95
		if ( in_array( 'googlemaps3', $GLOBALS['egMapsAvailableServices'] ) ) {
96
			$GLOBALS['wgSpecialPages']['MapEditor'] = 'SpecialMapEditor';
97
			$GLOBALS['wgSpecialPageGroups']['MapEditor'] = 'maps';
98
		}
99
100
		return true;
101
	};
102
103
	$GLOBALS['wgHooks']['AdminLinks'][]                = 'MapsHooks::addToAdminLinks';
104
	$GLOBALS['wgHooks']['MakeGlobalVariablesScript'][] = 'MapsHooks::onMakeGlobalVariablesScript';
105
106
	// Parser hooks
107
108
	// Required for #coordinates.
109
	$GLOBALS['wgHooks']['ParserFirstCallInit'][] = function( Parser &$parser ) {
110
		$instance = new MapsCoordinates();
111
		return $instance->init( $parser );
112
	};
113
114
	$GLOBALS['wgHooks']['ParserFirstCallInit'][] = function( Parser &$parser ) {
115
		$instance = new MapsDisplayMap();
116
		return $instance->init( $parser );
117
	};
118
119
	$GLOBALS['wgHooks']['ParserFirstCallInit'][] = function( Parser &$parser ) {
120
		$instance = new MapsDistance();
121
		return $instance->init( $parser );
122
	};
123
124
	$GLOBALS['wgHooks']['ParserFirstCallInit'][] = function( Parser &$parser ) {
125
		$instance = new MapsFinddestination();
126
		return $instance->init( $parser );
127
	};
128
129
	$GLOBALS['wgHooks']['ParserFirstCallInit'][] = function( Parser &$parser ) {
130
		$instance = new MapsGeocode();
131
		return $instance->init( $parser );
132
	};
133
134
	$GLOBALS['wgHooks']['ParserFirstCallInit'][] = function( Parser &$parser ) {
135
		$instance = new MapsGeodistance();
136
		return $instance->init( $parser );
137
	};
138
139
	$GLOBALS['wgHooks']['ParserFirstCallInit'][] = function( Parser &$parser ) {
140
		$instance = new MapsMapsDoc();
141
		return $instance->init( $parser );
142
	};
143
144
	// Geocoders
145
146
	// Registration of the GeoNames service geocoder.
147
	$GLOBALS['wgHooks']['GeocoderFirstCallInit'][] = 'MapsGeonamesGeocoder::register';
148
149
	// Registration of the Google Geocoding (v2) service geocoder.
150
	$GLOBALS['wgHooks']['GeocoderFirstCallInit'][] = 'MapsGoogleGeocoder::register';
151
152
	// Registration of the geocoder.us service geocoder.
153
	$GLOBALS['wgHooks']['GeocoderFirstCallInit'][] = 'MapsGeocoderusGeocoder::register';
154
155
	// Registration of the OSM Nominatim service geocoder.
156
	$GLOBALS['wgHooks']['GeocoderFirstCallInit'][] = function() {
157
		\Maps\Geocoders::registerGeocoder(
158
			'nominatim',
159
			new \Maps\Geocoders\NominatimGeocoder( new SimpleFileFetcher() )
160
		);
161
		return true;
162
	};
163
164
	// Mapping services
165
166
	// Include the mapping services that should be loaded into Maps.
167
	// Commenting or removing a mapping service will make Maps completely ignore it, and so improve performance.
168
169
	// Google Maps API v3
170
	// TODO: improve loading mechanism
171
	include_once __DIR__ . '/includes/services/GoogleMaps3/GoogleMaps3.php';
172
173
	// OpenLayers API
174
	// TODO: improve loading mechanism
175
	include_once __DIR__ . '/includes/services/OpenLayers/OpenLayers.php';
176
177
	// Leaflet API
178
	// TODO: improve loading mechanism
179
	include_once __DIR__ . '/includes/services/Leaflet/Leaflet.php';
180
181
182
	require_once __DIR__ . '/Maps_Settings.php';
183
184
	$GLOBALS['wgAvailableRights'][] = 'geocode';
185
186
	// Users that can geocode. By default the same as those that can edit.
187
	foreach ( $GLOBALS['wgGroupPermissions'] as $group => $rights ) {
188
		if ( array_key_exists( 'edit' , $rights ) ) {
189
			$GLOBALS['wgGroupPermissions'][$group]['geocode'] = $GLOBALS['wgGroupPermissions'][$group]['edit'];
190
		}
191
	}
192
193
	$GLOBALS['wgParamDefinitions']['coordinate'] = [
194
		'string-parser' => GeoCoordinateParser::class,
195
	];
196
197
	$GLOBALS['wgParamDefinitions']['mappingservice'] = [
198
		'definition'=> ServiceParam::class,
199
	];
200
201
	$GLOBALS['wgParamDefinitions']['mapslocation'] = [
202
		'string-parser' => LocationParser::class,
203
	];
204
205
	$GLOBALS['wgParamDefinitions']['mapsline'] = [
206
		'string-parser' => LineParser::class,
207
	];
208
209
	$GLOBALS['wgParamDefinitions']['mapscircle'] = [
210
		'string-parser' => CircleParser::class,
211
	];
212
213
	$GLOBALS['wgParamDefinitions']['mapsrectangle'] = [
214
		'string-parser' => RectangleParser::class,
215
	];
216
217
	$GLOBALS['wgParamDefinitions']['mapspolygon'] = [
218
		'string-parser' => PolygonParser::class,
219
	];
220
221
	$GLOBALS['wgParamDefinitions']['distance'] = [
222
		'string-parser' => DistanceParser::class,
223
	];
224
225
	$GLOBALS['wgParamDefinitions']['wmsoverlay'] = [
226
		'string-parser' => WmsOverlayParser::class,
227
	];
228
229
	$GLOBALS['wgParamDefinitions']['mapsimageoverlay'] = [
230
		'string-parser' => ImageOverlayParser::class,
231
	];
232
233
	if ( defined( 'SMW_VERSION' ) ) { // TODO: add setting to disable auto-enabling of SM features
234
		SemanticMaps::newFromMediaWikiGlobals( $GLOBALS )->initExtension();
235
	}
236
} );
237
238
class SemanticMaps {
239
240
	private $mwGlobals;
241
242
	public static function newFromMediaWikiGlobals( array &$mwGlobals ) {
243
		return new self( $mwGlobals );
244
	}
245
246
	private function __construct( array &$mwGlobals ) {
247
		$this->mwGlobals =& $mwGlobals;
248
	}
249
250
	/**
251
	 * @since 3.4
252
	 */
253
	public function initExtension() {
254
		require_once __DIR__ . '/SemanticMaps/SM_Settings.php';
255
256
		// Hook for initializing the Geographical Data types.
257
		$this->mwGlobals['wgHooks']['SMW::DataType::initTypes'][] = 'SemanticMapsHooks::initGeoDataTypes';
258
259
		// Hook for defining the default query printer for queries that ask for geographical coordinates.
260
		$this->mwGlobals['wgHooks']['SMWResultFormat'][] = 'SemanticMapsHooks::addGeoCoordsDefaultFormat';
261
262
		// Hook for adding a Semantic Maps links to the Admin Links extension.
263
		$this->mwGlobals['wgHooks']['AdminLinks'][] = 'SemanticMapsHooks::addToAdminLinks';
264
265
		$this->mwGlobals['wgHooks']['sfFormPrinterSetup'][] = 'SemanticMaps\FormInputsSetup::run';
266
267
		$this->registerResourceModules();
268
269
		$this->registerGoogleMaps();
270
		$this->registerLeaflet();
271
		$this->registerOpenLayers();
272
273
		$this->mwGlobals['smwgResultFormats']['kml'] = SMKMLPrinter::class;
274
275
		$this->mwGlobals['wgHooks']['MappingServiceLoad'][] = function() {
276
			$this->mwGlobals['smwgResultAliases'][$this->mwGlobals['egMapsDefaultServices']['qp']][] = 'map';
277
			SMMapPrinter::registerDefaultService( $this->mwGlobals['egMapsDefaultServices']['qp'] );
278
		};
279
280
		// Internationalization
281
		$this->mwGlobals['wgMessagesDirs']['SemanticMaps'] = __DIR__ . '/i18n';
282
	}
283
284
	private function registerResourceModules() {
285
		$moduleTemplate = [
286
			'position' => 'bottom',
287
			'group' => 'ext.semanticmaps',
288
		];
289
290
		$this->mwGlobals['wgResourceModules']['ext.sm.forminputs'] = $moduleTemplate + [
291
				'dependencies' => [ 'ext.maps.coord' ],
292
				'localBasePath' => __DIR__ . '/SemanticMaps/src/forminputs',
293
				'remoteExtPath' => 'Maps/SemanticMaps/src/forminputs',
294
				'scripts' => [
295
					'jquery.mapforminput.js'
296
				],
297
				'messages' => [
298
					'semanticmaps_enteraddresshere',
299
					'semanticmaps-updatemap',
300
					'semanticmaps_lookupcoordinates',
301
					'semanticmaps-forminput-remove',
302
					'semanticmaps-forminput-add',
303
					'semanticmaps-forminput-locations'
304
				]
305
			];
306
307
		$this->mwGlobals['wgResourceModules']['ext.sm.common'] = $moduleTemplate + [
308
				'localBasePath' => __DIR__ . '/SemanticMaps/src',
309
				'remoteExtPath' => 'Maps/SemanticMaps/src',
310
				'scripts' => [
311
					'ext.sm.common.js'
312
				]
313
			];
314
	}
315
316
	private function registerGoogleMaps() {
317
		$moduleTemplate = [
318
			'localBasePath' => __DIR__ . '/SemanticMaps/src/services/GoogleMaps3',
319
			'remoteExtPath' => 'Maps/SemanticMaps/src/services/GoogleMaps3',
320
			'group' => 'ext.semanticmaps',
321
		];
322
323
		$this->mwGlobals['wgResourceModules']['ext.sm.fi.googlemaps3ajax'] = $moduleTemplate + [
324
				'dependencies' => [
325
					'ext.maps.googlemaps3',
326
					'ext.sm.common'
327
				],
328
				'scripts' => [
329
					'ext.sm.googlemaps3ajax.js'
330
				]
331
			];
332
333
		$this->mwGlobals['wgResourceModules']['ext.sm.fi.googlemaps3'] = $moduleTemplate + [
334
				'dependencies' => [
335
					'ext.sm.fi.googlemaps3.single',
336
				],
337
				'scripts' => [
338
					'ext.sm.googlemapsinput.js',
339
				],
340
			];
341
342
		$this->mwGlobals['wgResourceModules']['ext.sm.fi.googlemaps3.single'] = $moduleTemplate + [
343
				'dependencies' => [
344
					'ext.maps.googlemaps3',
345
					'ext.sm.forminputs',
346
				],
347
				'scripts' => [
348
					'jquery.googlemapsinput.js',
349
				],
350
				'messages' => [
351
				]
352
			];
353
354
		$this->mwGlobals['wgHooks']['MappingServiceLoad'][] = function() {
355
			/* @var MapsMappingService $googleMaps */
356
			$googleMaps = MapsMappingServices::getServiceInstance( 'googlemaps3' );
357
			$googleMaps->addResourceModules( array( 'ext.sm.fi.googlemaps3ajax' ) );
358
359
			$googleMaps->addFeature( 'fi', SMGoogleMaps3FormInput::class );
360
361
			SMMapPrinter::registerService( $googleMaps );
362
363
			$this->mwGlobals['smwgResultFormats'][$googleMaps->getName()] = SMMapPrinter::class;
364
			$this->mwGlobals['smwgResultAliases'][$googleMaps->getName()] = $googleMaps->getAliases();
365
		};
366
	}
367
368
	private function registerLeaflet() {
369
		$this->mwGlobals['wgResourceModules']['ext.sm.fi.leafletajax'] = [
370
			'localBasePath' => __DIR__ . '/SemanticMaps/src/services/Leaflet',
371
			'remoteExtPath' => 'Maps/SemanticMaps/src/services/Leaflet',
372
			'group' => 'ext.semanticmaps',
373
			'dependencies' => [
374
				'ext.maps.leaflet',
375
				'ext.sm.common'
376
			],
377
			'scripts' => [
378
				'ext.sm.leafletajax.js'
379
			]
380
		];
381
382
		$this->mwGlobals['wgHooks']['MappingServiceLoad'][] = function() {
383
			/* @var MapsMappingService $leaflet */
384
			$leaflet = MapsMappingServices::getServiceInstance( 'leaflet' );
385
			$leaflet->addResourceModules( array( 'ext.sm.fi.leafletajax' ) );
386
387
			SMMapPrinter::registerService( $leaflet );
388
389
			$this->mwGlobals['smwgResultFormats'][$leaflet->getName()] = SMMapPrinter::class;
390
			$this->mwGlobals['smwgResultAliases'][$leaflet->getName()] = $leaflet->getAliases();
391
		};
392
	}
393
394
	private function registerOpenLayers() {
395
		$this->mwGlobals['wgResourceModules']['ext.sm.fi.openlayersajax'] = [
396
			'localBasePath' => __DIR__ . '/SemanticMaps/src/services/OpenLayers',
397
			'remoteExtPath' => 'Maps/SemanticMaps/src/services/OpenLayers',
398
			'group' => 'ext.semanticmaps',
399
			'dependencies' => [
400
				'ext.maps.openlayers',
401
				'ext.sm.common'
402
			],
403
			'scripts' => [
404
				'ext.sm.openlayersajax.js'
405
			]
406
		];
407
408
		$this->mwGlobals['wgHooks']['MappingServiceLoad'][] = function() {
409
			/* @var MapsMappingService $openLayers */
410
			$openLayers = MapsMappingServices::getServiceInstance( 'openlayers' );
411
			$openLayers->addResourceModules( array( 'ext.sm.fi.openlayersajax' ) );
412
413
			SMMapPrinter::registerService( $openLayers );
414
415
			$this->mwGlobals['smwgResultFormats'][$openLayers->getName()] = SMMapPrinter::class;
416
			$this->mwGlobals['smwgResultAliases'][$openLayers->getName()] = $openLayers->getAliases();
417
		};
418
	}
419
420
	/**
421
	 * @since 3.4
422
	 *
423
	 * @return string|null
424
	 */
425
	public static function getVersion() {
426
		return SM_VERSION;
427
	}
428
429
}
430
431