Extension:YahooMaps/YahooMaps.php

From MediaWiki.org
Jump to: navigation, search
<?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>&nbsp;<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
                );
        }
}
Personal tools
Namespaces
Variants
Actions
Site
Support
Download
Development
Communication
Print/export
Toolbox