Completed
Pull Request — master (#131)
by None
07:10
created

Maps.hooks.php (2 issues)

Severity

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
2
3
/**
4
 * Static class for hooks handled by the Maps extension.
5
 *
6
 * @since 0.7
7
 *
8
 * @licence GNU GPL v2+
9
 * @author Jeroen De Dauw < [email protected] >
10
 * @author Daniel Werner
11
 */
12
final class MapsHooks {
13
	/**
14
	 * Helper flag indicating whether the page has been purged.
15
	 * @var bool
16
	 *
17
	 * TODO: Figure out a better way to do this, not requiring this flag and make sure it works with
18
	 *       later MW versions (purging mechanism got changed somewhat around 1.18).
19
	 */
20
	static $purgedBeforeStore = false;
21
22
	public static function onExtensionCallback() {
0 ignored issues
show
onExtensionCallback uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
23
24
		if ( defined( 'Maps_VERSION' ) ) {
25
			// Do not initialize more than once.
26
			return 1;
27
		}
28
29
		define( 'Maps_VERSION' , '3.6.0-alpha' );
30
31
		// Only initialize the extension when all dependencies are present.
32
		if ( !defined( 'Validator_VERSION' ) ) {
33
			throw new Exception( 'You need to have Validator installed in order to use Maps' );
34
		}
35
36
		$GLOBALS['egMapsStyleVersion'] = $GLOBALS['wgStyleVersion'] . '-' . Maps_VERSION;
37
38
		// The different coordinate notations.
39
		define( 'Maps_COORDS_FLOAT' , 'float' );
40
		define( 'Maps_COORDS_DMS' , 'dms' );
41
		define( 'Maps_COORDS_DM' , 'dm' );
42
		define( 'Maps_COORDS_DD' , 'dd' );
43
44
		require_once __DIR__ . '/Maps_Settings.php';
45
46
		define( 'Maps_NS_LAYER' , $GLOBALS['egMapsNamespaceIndex'] + 0 );
47
		define( 'Maps_NS_LAYER_TALK' , $GLOBALS['egMapsNamespaceIndex'] + 1 );
48
	}
49
50
	public static function onExtensionFunction() {
0 ignored issues
show
onExtensionFunction uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
51
		if ( $GLOBALS['egMapsGMaps3Language'] === '' ) {
52
			$GLOBALS['egMapsGMaps3Language'] = $GLOBALS['wgLang'];
53
		}
54
55
		Hooks::run( 'MappingServiceLoad' );
56
		Hooks::run( 'MappingFeatureLoad' );
57
58
		if ( in_array( 'googlemaps3', $GLOBALS['egMapsAvailableServices'] ) ) {
59
			$GLOBALS['wgSpecialPages']['MapEditor'] = 'SpecialMapEditor';
60
			$GLOBALS['wgSpecialPageGroups']['MapEditor'] = 'maps';
61
		}
62
63
		return true;
64
	}
65
66
	public static function onParserFirstCallInit1( Parser &$parser ) {
67
		$instance = new MapsCoordinates();
68
		return $instance->init( $parser );
69
	}
70
71
	public static function onParserFirstCallInit2( Parser &$parser ) {
72
		$instance = new MapsDisplayMap();
73
		return $instance->init( $parser );
74
	}
75
76
	public static function onParserFirstCallInit3( Parser &$parser ) {
77
		$instance = new MapsDistance();
78
		return $instance->init( $parser );
79
	}
80
81
	public static function onParserFirstCallInit4( Parser &$parser ) {
82
		$instance = new MapsFinddestination();
83
		return $instance->init( $parser );
84
	}
85
86
	public static function onParserFirstCallInit5( Parser &$parser ) {
87
		$instance = new MapsGeocode();
88
		return $instance->init( $parser );
89
	}
90
91
	public static function onParserFirstCallInit6( Parser &$parser ) {
92
		$instance = new MapsGeodistance();
93
		return $instance->init( $parser );
94
	}
95
96
	public static function onParserFirstCallInit7( Parser &$parser ) {
97
		$instance = new MapsMapsDoc();
98
		return $instance->init( $parser );
99
	}
100
101
	public static function onParserFirstCallInit8( Parser &$parser ) {
102
		$instance = new MapsLayerDefinition();
103
		return $instance->init( $parser );
104
	}
105
106
	/**
107
	 * Initialization function for the Google Maps v3 service. 
108
	 * 
109
	 * @since 0.6.3
110
	 * @ingroup MapsGoogleMaps3
111
	 * 
112
	 * @return boolean true
113
	 */
114
	public static function efMapsInitGoogleMaps3() {
115
		global $wgAutoloadClasses;
116
117
		$wgAutoloadClasses['MapsGoogleMaps3'] = __DIR__ . '/includes/services/GoogleMaps3/Maps_GoogleMaps3.php';
118
119
		MapsMappingServices::registerService( 'googlemaps3', 'MapsGoogleMaps3' );
120
121
		// TODO: kill below code
122
		$googleMaps = MapsMappingServices::getServiceInstance( 'googlemaps3' );
123
		$googleMaps->addFeature( 'display_map', 'MapsDisplayMapRenderer' );
124
125
		return true;
126
	}
127
128
	public static function efMapsInitOpenLayers() {
129
		MapsMappingServices::registerService( 
130
			'openlayers',
131
			'MapsOpenLayers',
132
			array( 'display_map' => 'MapsDisplayMapRenderer' )
133
		);
134
		
135
		return true;
136
	}
137
138
	/**
139
	 * Initialization function for the Leaflet service.
140
	 *
141
	 * @ingroup Leaflet
142
	 *
143
	 * @return boolean true
144
	 */
145
	public static function efMapsInitLeaflet() {
146
		global $wgAutoloadClasses;
147
148
		$wgAutoloadClasses['MapsLeaflet'] = __DIR__ . '/Maps_Leaflet.php';
149
150
		MapsMappingServices::registerService( 'leaflet', 'MapsLeaflet' );
151
		$leafletMaps = MapsMappingServices::getServiceInstance( 'leaflet' );
152
		$leafletMaps->addFeature( 'display_map', 'MapsDisplayMapRenderer' );
153
154
		return true;
155
	}
156
157
	/**
158
	 * Adds a link to Admin Links page.
159
	 *
160
	 * @since 0.7
161
	 *
162
	 * @param ALTree $admin_links_tree
163
	 *
164
	 * @return boolean
165
	 */
166
	public static function addToAdminLinks( ALTree &$admin_links_tree ) {
167
		$displaying_data_section = $admin_links_tree->getSection( wfMessage( 'smw_adminlinks_displayingdata' )->text() );
168
169
		// Escape if SMW hasn't added links.
170
		if ( is_null( $displaying_data_section ) ) {
171
			return true;
172
		}
173
174
		$smw_docu_row = $displaying_data_section->getRow( 'smw' );
175
176
		$maps_docu_label = wfMessage( 'adminlinks_documentation', 'Maps' )->text();
177
		$smw_docu_row->addItem( AlItem::newFromExternalLink( 'https://semantic-mediawiki.org/wiki/Maps', $maps_docu_label ) );
178
179
		return true;
180
	}
181
182
	/**
183
	 * Intercept pages in the Layer namespace to handle them correctly.
184
	 *
185
	 * @param $title: Title
186
	 * @param $article: Article or null
187
	 *
188
	 * @return boolean
189
	 */
190
	public static function onArticleFromTitle( Title &$title, /* Article */ &$article ) {
191
		if ( $title->getNamespace() == Maps_NS_LAYER ) {
192
			$article = new MapsLayerPage( $title );
193
		}
194
195
		return true;
196
	}
197
198
	/**
199
	 * Adds global JavaScript variables.
200
	 *
201
	 * @since 1.0
202
         * @see http://www.mediawiki.org/wiki/Manual:Hooks/MakeGlobalVariablesScript
203
         * @param array &$vars Variables to be added into the output
204
         * @param OutputPage $outputPage OutputPage instance calling the hook
205
         * @return boolean true in all cases
206
	 */
207
	public static function onMakeGlobalVariablesScript( array &$vars, OutputPage $outputPage ) {
208
		global $egMapsGlobalJSVars;
209
210
		$vars['egMapsDebugJS'] = $GLOBALS['egMapsDebugJS'];
211
                $vars[ 'egMapsAvailableServices' ] = $GLOBALS['egMapsAvailableServices'];
212
213
		$vars += $egMapsGlobalJSVars;
214
215
		return true;
216
	}
217
218
	/**
219
	 * @since 0.7
220
	 *
221
	 * @param array $list
222
	 *
223
	 * @return boolean
224
	 */
225
	public static function onCanonicalNamespaces( array &$list ) {
226
		$list[Maps_NS_LAYER] = 'Layer';
227
		$list[Maps_NS_LAYER_TALK] = 'Layer_talk';
228
		return true;
229
	}
230
231
	/**
232
	 * This will setup database tables for layer functionality.
233
	 *
234
	 * @since 3.0
235
	 *
236
	 * @param DatabaseUpdater $updater
237
	 *
238
	 * @return true
239
	 */
240
	public static function onLoadExtensionSchemaUpdates( DatabaseUpdater $updater ) {
241
		switch( $GLOBALS['wgDBtype'] ) {
242
			case 'mysql':
243
			case 'sqlite':
244
				$updater->addExtensionTable( 'maps_layers', __DIR__ . '/schema/MapsLayers.sql' );
245
				break;
246
			case 'postgres':
247
				$updater->addExtensionTable( 'maps_layers', __DIR__ . '/schema/MapsLayers-postgres.sql' );
248
				break;
249
		}
250
251
		return true;
252
	}
253
254
	/**
255
	 * Make sure layer data will be stored into database when purging the page
256
	 *
257
	 * @since 3.0
258
	 *
259
	 * @param $article WikiPage|Article (depending on MW version, WikiPage in 1.18+)
260
	 * @return type
261
	 */
262
	public static function onArticlePurge( &$article ) {
263
		self::$purgedBeforeStore = true;
264
		return true;
265
	}
266
267
	/**
268
	 * At the end of article parsing, in case of layer page, save layers to database
269
	 *
270
	 * @since 3.0
271
	 *
272
	 * @param Parser &$parser
273
	 * @param string &$text
274
	 *
275
	 * @return true
276
	 */
277
	public static function onParserAfterTidy( Parser &$parser, &$text ) {
278
279
		$title = $parser->getTitle();
280
281
		if( $title === null
282
			|| self::$purgedBeforeStore !== true
283
		) {
284
			// just preprocessing some stuff or no purge
285
			return true;
286
		}
287
288
		self::processLayersStoreCandidate( $parser->getOutput(), $title );
289
290
		// Set helper to false immediately so we won't run into job-processing weirdness:
291
		self::$purgedBeforeStore = false;
292
293
		return true;
294
	}
295
296
	/**
297
	 * After article was edited and parsed, in case of layer page, save layers to database
298
	 *
299
	 * @since 3.0
300
	 *
301
	 * @param LinksUpdate &$linksUpdate
302
	 *
303
	 * @return true
304
	 */
305
	public static function onLinksUpdateConstructed( LinksUpdate &$linksUpdate ) {
306
		$title = $linksUpdate->getTitle();
307
308
		self::processLayersStoreCandidate( $linksUpdate->mParserOutput, $title );
309
310
		return true;
311
	}
312
313
	/**
314
	 * Checks whether the parser output has some layer data which should be stored of the
315
	 * given title and performs the task.
316
	 *
317
	 * @since 3.0
318
	 *
319
	 * @param ParserOutput $parserOutput
320
	 * @param Title $title
321
	 */
322
	protected static function processLayersStoreCandidate( ParserOutput $parserOutput, Title $title ) {
323
324
		// if site which is being parsed is in maps namespace:
325
		if( $title->getNamespace() === Maps_NS_LAYER ) {
326
327
			if( ! isset( $parserOutput->mExtMapsLayers ) ) {
328
				$parserOutput->mExtMapsLayers = new MapsLayerGroup();
329
			}
330
331
			// get MapsLayerGroup object with layers to be stored:
332
			$mapsForStore = $parserOutput->mExtMapsLayers;
333
334
			// store layers in database (also deletes previous definitions still in db):
335
			MapsLayers::storeLayers( $mapsForStore, $title );
336
		}
337
	}
338
339
	/**
340
	 * If a new parser process is getting started, clear collected layer data of the
341
	 * previous one.
342
	 *
343
	 * @since 3.0
344
	 *
345
	 * @param Parser $parser
346
	 *
347
	 * @return true
348
	 */
349
	public static function onParserClearState( Parser &$parser ) {
350
		$parser->getOutput()->mExtMapsLayers = null;
351
		return true;
352
	}
353
}
354
355