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