Extension:YahooMaps/YahooMaps.php
From MediaWiki.org
<?php /** * YahooMaps MediaWiki extension * * To activate this extension, include it from your LocalSettings.php * with: require_once("$IP/extensions/YahooMaps/YahooMaps.php"); */ if( !defined( 'MEDIAWIKI' ) ) { die(); } // Avoid unstubbing $wgParser too early on modern (1.12+) MW versions, as per r35980 if ( defined( 'MW_SUPPORTS_PARSERFIRSTCALLINIT' ) ) { $wgHooks['ParserFirstCallInit'][] = 'wfYahooMapsExtension'; } else { $wgExtensionFunctions[] = 'wfYahooMapsExtension'; } // Extension credits that will show up on Special:Version $wgExtensionCredits['other'][] = array( 'name' => 'Yahoo Maps Extension', 'author' => 'Chris Reigrut', 'version' => '1.0.0', 'url' => 'http://www.mediawiki.org/wiki/Extension:YahooMaps', 'description' => 'Create Yahoo maps with wikitext markers' ); function wfYahooMapsExtension() { global $wgParser; # register the extension with the WikiText parser $wgParser->setHook( 'yahoomap', 'renderYahooMap' ); $wgParser->setHook( 'yahoogeocoder', 'renderYahooGeocoder' ); } $YM_MAP_SCRIPT_INCLUDED = false; function addMapScript( $parser ) { global $YM_MAP_SCRIPT_INCLUDED; if( !$YM_MAP_SCRIPT_INCLUDED ) { $appId = getYahooAppId(); $parser->mOutput->addHeadItem("<script type='text/javascript' src='http://api.maps.yahoo.com/ajaxymap?v=3.4&appid={$appId}'></script>\n"); $YM_MAP_SCRIPT_INCLUDED = true; } } $YM_GEOCODER_SCRIPT_INCLUDED = false; function addGeocoderScript( $parser ) { global $YM_GEOCODER_SCRIPT_INCLUDED, $wgScriptPath; if( !$YM_GEOCODER_SCRIPT_INCLUDED ) { $parser->mOutput->addHeadItem("<script src='${wgScriptPath}/extensions/YahooMaps/xmlw3cdom.js'></script></script>\n"); $parser->mOutput->addHeadItem("<script src='${wgScriptPath}/extensions/YahooMaps/xmlsax.js'></script></script>\n"); $YM_GEOCODER_SCRIPT_INCLUDED = true; } } # The callback function for converting the input text to HTML output function renderYahooMap( $input, $argv, &$parser ) { addMapScript($parser); $output = ''; $id = rand(); $style = $argv['style']; $zoom = $argv['zoom']; if( $zoom == NULL ) { $zoom = 15; } $lat = $argv['lat']; if( $lat == NULL ) { $lat = 37.4041960114344; } $lon = $argv['lon']; if( $lon == NULL ) { $lon = -100.008194923401; } $appId = getYahooAppId(); //Create the Javascript for the map from the tag attributes $output .= <<<ENDPREFIX <div class = "yahoomap" id="map{$id}" style="{$style}"><span style="font-size: 20pt; line-height: 24pt; color: #F1F1F1;">This is the Yahoo Map area.<br />If you are seeing this message and not a map, it means that an error has occurred because Yahoo can't be reached right now. Generally, this is either because your browser's proxy settings are incorrect or there is a network issue.</span></div> <script type="text/javascript"> /*<![CDATA[*/ // Create the standard map var map = new YMap(document.getElementById("map{$id}"),YAHOO_MAP_REG); // Center the map at the specified lat/lon and zoom var center = new YGeoPoint({$lat},{$lon}); // Add the map type control (to select Map/Satellite/Hybrid) map.addTypeControl(); // Add the map zoom control map.addZoomLong(); ENDPREFIX; # The contents of the tag are the markers. Each line is one marker. $lines = preg_split("/[\r\n]+/", $input); foreach( $lines as $line ) { if( $line!= NULL && trim($line) != '' ) { $output .= addMarker( $parser, trim( $line ) ); } } # Finish the Javascript $output .= <<<ENDSUFFIX map.drawZoomAndCenter(center, {$zoom}); /*]]>*/ </script> ENDSUFFIX; return encode( $output ); } # Create the map marker from a line of the format: # latitude | longitude | Tag | Expanded (mouseover) text function addMarker( &$parser, $markerLine ) { $output = ''; $tokens = preg_split("/\s*\|\s*/", $markerLine); $lat = array_shift($tokens); $lon = array_shift($tokens); $baseText = parseMarkerText($parser, array_shift($tokens)); // Combine the remaining tokens (that were split around |) into the expanded text // This allows us use pipes in the expanded text (such as image alignment, alternate text for links, etc) $expandedText = parseMarkerText($parser, implode('|', $tokens)); $output .= <<<ENDMARKER // Add the marker Javascript var markerPoint = new YGeoPoint({$lat},{$lon}); var marker = new YMarker(markerPoint); marker.addLabel('${baseText}'); marker.addAutoExpand('${expandedText}'); map.addOverlay(marker); ENDMARKER; return $output; } # Parse the wikitext markup for the marker text function parseMarkerText( &$parser, $text ) { $localParser = new Parser(); # Parse the wikitext with a local parser $output = $localParser->parse($text, $parser->mTitle, $parser->mOptions, false)->getText(); # Extract the body portion (which is the text) from the full document. However, this doesn't seem necessary any more (perhaps it's the local parser) #preg_match('/(?<=\<body\>)(.*)(?=\<\/body\>)/esm', $output, $matches); # Remove CR/LFs $output = preg_replace('/[\r\n]/esm', '', $output); $output = addcslashes($output, "\'\""); return $output; } # The callback function for converting the input text to HTML output function renderYahooGeocoder( $input, $argv, &$parser ) { global $wgScriptPath; addGeocoderScript($parser); $output = ''; $appId = getYahooAppId(); // Create the JavaScript for the geocoder $output .= <<<ENDGEOCODESCRIPT <script type="text/javascript"> //<![CDATA[ var xmlhttp = false; var ymap; function callWS( target ) { if( target !== "" ){ var url = window.location.protocol + '//' + window.location.hostname + "${wgScriptPath}/extensions/YahooMaps/yproxy.php?" + encodeURI(target); xmlhttp.open('GET', url, true); xmlhttp.onreadystatechange = function() { if( xmlhttp.readyState == 4 && xmlhttp.status == 200 ) { document.getElementById('result').innerHTML = ''; parseResult(xmlhttp.responseText); } else { document.getElementById('result').innerHTML = "Loading..."; } }; xmlhttp.send(null); } } function parseResult( parseMeString ) { var parser = new DOMImplementation(); var domDoc = parser.loadXML(parseMeString); if( domDoc == null ){ alert("There was a problem parsing search results."); return; } var docRoot = domDoc.getDocumentElement(); var items = docRoot.getElementsByTagName("Result"); for( var i =0; i < items.length; i++ ) { var lat = items.item(i).getElementsByTagName("Latitude").item(0).getFirstChild().getNodeValue(); var lon = items.item(i).getElementsByTagName("Longitude").item(0).getFirstChild().getNodeValue(); var marker = lat + " | " + lon + " | " + "TAG" + " | " + "POPUP DESCRIPTION"; var smart = "<code>" + marker + "</code>"; document.getElementById('result').innerHTML = smart; // And copy it to the clipboard in IE window.clipboardData.setData("Text", marker); } } function callGeocode() { var query = document.getElementById("geoquery").value; var uri = "http://api.local.yahoo.com/MapsService/V1/geocode?appid={$appId}&location=" + query; callWS( uri ); } if( window.XMLHttpRequest ) { xmlhttp = new XMLHttpRequest(); xmlhttp.overrideMimeType('text/xml'); } else if( window.ActiveXObject ) { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } //]]> </script> <div id="yahoogeocoder" style="border: 1px solid gray; padding: 5px;"> <div class="inputelement"><button onClick="callGeocode()">Create marker</button> <input id="geoquery" value="1000 S. McCaslin Blvd, Superior, CO, 80027" size="50"></input></div> <br /> <div id="result" style="height: 25px;"></div> </div> ENDGEOCODESCRIPT; return encode( $output ); } function getYahooAppId() { global $wgYahooMapsAppId; if( $wgYahooMapsAppId == null || $wgYahooMapsAppId == '' ) { return "YahooDemo"; } return $wgYahooMapsAppId; } # Process the page after tidy runs, decoding all encoded portions if( !function_exists( 'processEncodedOutput ') ) { $wgHooks['ParserAfterTidy'][] = 'processEncodedOutput'; function processEncodedOutput( &$out, &$text ) { # Find all hidden content and restore to normal $text = decode($text); return true; } # Encode the given string so that it will no longer be processed by the wikitext engine function encode( $text ) { return '-- ENCODED_CONTENT '.base64_encode($text).' --'; } # Decode all of the encoded portions of the page function decode( $text ) { return preg_replace( '/-- ENCODED_CONTENT ([0-9a-zA-Z\\+\/]+=*) --/esm', 'base64_decode("$1")', $text ); } }
