1*38a47c60SMark Prins<?php 2*38a47c60SMark Prins/* 3*38a47c60SMark Prins * Copyright (c) 2008-2011 Mark C. Prins <mc.prins@gmail.com> 4*38a47c60SMark Prins * 5*38a47c60SMark Prins * Permission to use, copy, modify, and distribute this software for any 6*38a47c60SMark Prins * purpose with or without fee is hereby granted, provided that the above 7*38a47c60SMark Prins * copyright notice and this permission notice appear in all copies. 8*38a47c60SMark Prins * 9*38a47c60SMark Prins * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10*38a47c60SMark Prins * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*38a47c60SMark Prins * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12*38a47c60SMark Prins * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*38a47c60SMark Prins * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*38a47c60SMark Prins * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15*38a47c60SMark Prins * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16*38a47c60SMark Prins */ 17*38a47c60SMark Prins 18*38a47c60SMark Prins/** 19*38a47c60SMark Prins * Plugin OL Maps: Allow Display of a OpenLayers Map in a wiki page. 20*38a47c60SMark Prins * 21*38a47c60SMark Prins * @author Mark Prins 22*38a47c60SMark Prins */ 23*38a47c60SMark Prins 24*38a47c60SMark Prinsif (!defined('DOKU_INC')) 25*38a47c60SMark Prinsdefine('DOKU_INC', realpath(dirname(__FILE__) . '/../../') . '/'); 26*38a47c60SMark Prinsif (!defined('DOKU_PLUGIN')) 27*38a47c60SMark Prinsdefine('DOKU_PLUGIN', DOKU_INC . 'lib/plugins/'); 28*38a47c60SMark Prinsrequire_once (DOKU_PLUGIN . 'syntax.php'); 29*38a47c60SMark Prins 30*38a47c60SMark Prins/** 31*38a47c60SMark Prins * All DokuWiki plugins to extend the parser/rendering mechanism 32*38a47c60SMark Prins * need to inherit from this class 33*38a47c60SMark Prins */ 34*38a47c60SMark Prinsclass syntax_plugin_openlayersmap_olmap extends DokuWiki_Syntax_Plugin { 35*38a47c60SMark Prins /** defaults of the recognized attributes of the olmap tag. */ 36*38a47c60SMark Prins private $dflt = array ( 37*38a47c60SMark Prins 'id' => 'olmap', 38*38a47c60SMark Prins 'width' => '550px', 39*38a47c60SMark Prins 'height' => '450px', 40*38a47c60SMark Prins 'lat' => 50.0, 41*38a47c60SMark Prins 'lon' => 5.1, 42*38a47c60SMark Prins 'zoom' => 12, 43*38a47c60SMark Prins 'toolbar' => true, 44*38a47c60SMark Prins 'statusbar' => true, 45*38a47c60SMark Prins 'controls' => true, 46*38a47c60SMark Prins 'poihoverstyle' => false, 47*38a47c60SMark Prins 'baselyr'=>'OpenStreetMap', 48*38a47c60SMark Prins 'gpxfile' => '', 49*38a47c60SMark Prins 'kmlfile' => '' 50*38a47c60SMark Prins ); 51*38a47c60SMark Prins 52*38a47c60SMark Prins /** 53*38a47c60SMark Prins * Return the type of syntax this plugin defines. 54*38a47c60SMark Prins * @Override 55*38a47c60SMark Prins */ 56*38a47c60SMark Prins function getType() { 57*38a47c60SMark Prins return 'substition'; 58*38a47c60SMark Prins } 59*38a47c60SMark Prins 60*38a47c60SMark Prins /** 61*38a47c60SMark Prins * Defines how this syntax is handled regarding paragraphs. 62*38a47c60SMark Prins * @Override 63*38a47c60SMark Prins */ 64*38a47c60SMark Prins function getPType() { 65*38a47c60SMark Prins return 'block'; 66*38a47c60SMark Prins } 67*38a47c60SMark Prins 68*38a47c60SMark Prins /** 69*38a47c60SMark Prins * Returns a number used to determine in which order modes are added. 70*38a47c60SMark Prins * @Override 71*38a47c60SMark Prins */ 72*38a47c60SMark Prins function getSort() { 73*38a47c60SMark Prins return 901; 74*38a47c60SMark Prins } 75*38a47c60SMark Prins 76*38a47c60SMark Prins /** 77*38a47c60SMark Prins * This function is inherited from Doku_Parser_Mode. 78*38a47c60SMark Prins * Here is the place to register the regular expressions needed 79*38a47c60SMark Prins * to match your syntax. 80*38a47c60SMark Prins * @Override 81*38a47c60SMark Prins */ 82*38a47c60SMark Prins function connectTo($mode) { 83*38a47c60SMark Prins $this->Lexer->addSpecialPattern('<olmap ?[^>\n]*>.*?</olmap>', $mode, 'plugin_openlayersmap_olmap'); 84*38a47c60SMark Prins } 85*38a47c60SMark Prins 86*38a47c60SMark Prins /** 87*38a47c60SMark Prins * handle each olmap tag. prepare the matched syntax for use in the renderer. 88*38a47c60SMark Prins * @Override 89*38a47c60SMark Prins */ 90*38a47c60SMark Prins function handle($match, $state, $pos, & $handler) { 91*38a47c60SMark Prins // break matched cdata into its components 92*38a47c60SMark Prins list ($str_params, $str_points) = explode('>', substr($match, 7, -9), 2); 93*38a47c60SMark Prins 94*38a47c60SMark Prins $gmap = $this->_extract_params($str_params); 95*38a47c60SMark Prins $overlay = $this->_extract_points($str_points); 96*38a47c60SMark Prins 97*38a47c60SMark Prins $mapid = $gmap['id']; 98*38a47c60SMark Prins 99*38a47c60SMark Prins // determine width and height (inline styles) for the map image 100*38a47c60SMark Prins if ($gmap['width'] || $gmap['height']) { 101*38a47c60SMark Prins $style = $gmap['width'] ? 'width: ' . $gmap['width'] . ";" : ""; 102*38a47c60SMark Prins $style .= $gmap['height'] ? 'height: ' . $gmap['height'] . ";" : ""; 103*38a47c60SMark Prins $style = "style='$style'"; 104*38a47c60SMark Prins } else { 105*38a47c60SMark Prins $style = ''; 106*38a47c60SMark Prins } 107*38a47c60SMark Prins 108*38a47c60SMark Prins // unset gmap values for width and height - they don't go into javascript 109*38a47c60SMark Prins unset ($gmap['width'], $gmap['height']); 110*38a47c60SMark Prins 111*38a47c60SMark Prins // create a javascript parameter string for the map 112*38a47c60SMark Prins $param = ''; 113*38a47c60SMark Prins foreach ($gmap as $key => $val) { 114*38a47c60SMark Prins $param .= is_numeric($val) ? "$key:$val," : "$key:'" . hsc($val) . "',"; 115*38a47c60SMark Prins } 116*38a47c60SMark Prins if (!empty ($param)) { 117*38a47c60SMark Prins $param = substr($param, 0, -1); 118*38a47c60SMark Prins } 119*38a47c60SMark Prins unset ($gmap['id']); 120*38a47c60SMark Prins 121*38a47c60SMark Prins // create a javascript serialisation of the point data 122*38a47c60SMark Prins $poi = ''; 123*38a47c60SMark Prins if (!empty ($overlay)) { 124*38a47c60SMark Prins foreach ($overlay as $data) { 125*38a47c60SMark Prins list ($lat, $lon, $text, $angle, $opacity, $img) = $data; 126*38a47c60SMark Prins $poi .= ",{lat: $lat, lon: $lon, txt: '$text', angle: $angle, opacity: $opacity, img: '$img'}"; 127*38a47c60SMark Prins } 128*38a47c60SMark Prins $poi = substr($poi, 1); 129*38a47c60SMark Prins } 130*38a47c60SMark Prins $js .= "createMap({" . $param . " },[$poi]);"; 131*38a47c60SMark Prins 132*38a47c60SMark Prins return array ( 133*38a47c60SMark Prins $mapid, 134*38a47c60SMark Prins $style, 135*38a47c60SMark Prins $js 136*38a47c60SMark Prins ); 137*38a47c60SMark Prins } 138*38a47c60SMark Prins 139*38a47c60SMark Prins /** 140*38a47c60SMark Prins * render html tag/output. render the content. 141*38a47c60SMark Prins * @Override 142*38a47c60SMark Prins */ 143*38a47c60SMark Prins function render($mode, & $renderer, $data) { 144*38a47c60SMark Prins static $initialised = false; // set to true after script initialisation 145*38a47c60SMark Prins if ($mode == 'xhtml') { 146*38a47c60SMark Prins list ($mapid, $style, $param) = $data; 147*38a47c60SMark Prins $olscript = ''; 148*38a47c60SMark Prins $olEnable = false; 149*38a47c60SMark Prins $gscript = ''; 150*38a47c60SMark Prins $gEnable = false; 151*38a47c60SMark Prins $vscript = ''; 152*38a47c60SMark Prins $vEnable = false; 153*38a47c60SMark Prins $yscript = ''; 154*38a47c60SMark Prins $yEnable = false; 155*38a47c60SMark Prins 156*38a47c60SMark Prins $scriptEnable = ''; 157*38a47c60SMark Prins 158*38a47c60SMark Prins if (!$initialised) { 159*38a47c60SMark Prins $initialised = true; 160*38a47c60SMark Prins 161*38a47c60SMark Prins $gscript = $this->getConf('googleScriptUrl'); 162*38a47c60SMark Prins $gscript = $gscript ? '<script type="text/javascript" src="' . $gscript . '"></script>' : ""; 163*38a47c60SMark Prins 164*38a47c60SMark Prins $vscript = $this->getConf('veScriptUrl'); 165*38a47c60SMark Prins $vscript = $vscript ? '<script type="text/javascript" src="' . $vscript . '"></script>' : ""; 166*38a47c60SMark Prins 167*38a47c60SMark Prins $yscript = $this->getConf('yahooScriptUrl'); 168*38a47c60SMark Prins $yscript = $yscript ? '<script type="text/javascript" src="' . $yscript . '"></script>' : ""; 169*38a47c60SMark Prins 170*38a47c60SMark Prins $olscript = $this->getConf('olScriptUrl'); 171*38a47c60SMark Prins $olscript = $olscript ? '<script type="text/javascript" src="' . $olscript . '"></script>' : ""; 172*38a47c60SMark Prins $olscript = str_replace('DOKU_PLUGIN', DOKU_PLUGIN, $olscript); 173*38a47c60SMark Prins 174*38a47c60SMark Prins $scriptEnable = '<script type="text/javascript">' . "\n" . '//<![CDATA[' . "\n"; 175*38a47c60SMark Prins $scriptEnable .= $olscript ? 'olEnable = true;' : 'olEnable = false;'; 176*38a47c60SMark Prins $scriptEnable .= $yscript ? ' yEnable = true;' : ' yEnable = false;'; 177*38a47c60SMark Prins $scriptEnable .= $vscript ? ' veEnable = true;' : ' veEnable = false;'; 178*38a47c60SMark Prins $scriptEnable .= $gscript ? ' gEnable = true;' : ' gEnable = false;'; 179*38a47c60SMark Prins $scriptEnable .= "\n" . '//]]>' . "\n" . '</script>'; 180*38a47c60SMark Prins } 181*38a47c60SMark Prins $renderer->doc .= " 182*38a47c60SMark Prins $olscript 183*38a47c60SMark Prins $gscript 184*38a47c60SMark Prins $vscript 185*38a47c60SMark Prins $yscript 186*38a47c60SMark Prins $scriptEnable 187*38a47c60SMark Prins <div id='olContainer' class='olContainer'> 188*38a47c60SMark Prins <div id='$mapid-olToolbar' class='olToolbar'></div> 189*38a47c60SMark Prins <div style='clear:both;'></div> 190*38a47c60SMark Prins <div id='$mapid' $style ></div> 191*38a47c60SMark Prins <div id='$mapid-olStatusBar' class='olStatusBarContainer'> 192*38a47c60SMark Prins <div id='$mapid-statusbar-scale' class='olStatusBar olStatusBarScale'>scale</div> 193*38a47c60SMark Prins <div id='$mapid-statusbar-link' class='olStatusBar olStatusBarPermalink'> 194*38a47c60SMark Prins <a href='' id='$mapid-statusbar-link-ref'>map link</a> 195*38a47c60SMark Prins </div> 196*38a47c60SMark Prins <div id='$mapid-statusbar-mouseposition' class='olStatusBar olStatusBarMouseposition'></div> 197*38a47c60SMark Prins <div id='$mapid-statusbar-projection' class='olStatusBar olStatusBarProjection'>proj</div> 198*38a47c60SMark Prins <div id='$mapid-statusbar-text' class='olStatusBar olStatusBarText'>txt</div> 199*38a47c60SMark Prins </div> 200*38a47c60SMark Prins </div> 201*38a47c60SMark Prins <p> </p> 202*38a47c60SMark Prins <script type='text/javascript'>//<![CDATA[ 203*38a47c60SMark Prins var $mapid = $param 204*38a47c60SMark Prins //]]></script>"; 205*38a47c60SMark Prins } 206*38a47c60SMark Prins return false; 207*38a47c60SMark Prins } 208*38a47c60SMark Prins 209*38a47c60SMark Prins /** 210*38a47c60SMark Prins * extract parameters for the map from the parameter string 211*38a47c60SMark Prins * 212*38a47c60SMark Prins * @param string $str_params string of key="value" pairs 213*38a47c60SMark Prins * @return array associative array of parameters key=>value 214*38a47c60SMark Prins */ 215*38a47c60SMark Prins function _extract_params($str_params) { 216*38a47c60SMark Prins $param = array (); 217*38a47c60SMark Prins preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER); 218*38a47c60SMark Prins 219*38a47c60SMark Prins // parse match for instructions, break into key value pairs 220*38a47c60SMark Prins $gmap = $this->dflt; 221*38a47c60SMark Prins foreach ($param as $kvpair) { 222*38a47c60SMark Prins list ($match, $key, $val) = $kvpair; 223*38a47c60SMark Prins $key = strtolower($key); 224*38a47c60SMark Prins if (isset ($gmap[$key])){ 225*38a47c60SMark Prins $gmap[$key] = strtolower($val); 226*38a47c60SMark Prins } 227*38a47c60SMark Prins } 228*38a47c60SMark Prins return $gmap; 229*38a47c60SMark Prins } 230*38a47c60SMark Prins 231*38a47c60SMark Prins /** 232*38a47c60SMark Prins * extract overlay points for the map from the wiki syntax data 233*38a47c60SMark Prins * 234*38a47c60SMark Prins * @param string $str_points multi-line string of lat,lon,text triplets 235*38a47c60SMark Prins * @return array multi-dimensional array of lat,lon,text triplets 236*38a47c60SMark Prins */ 237*38a47c60SMark Prins function _extract_points($str_points) { 238*38a47c60SMark Prins $point = array (); 239*38a47c60SMark Prins //preg_match_all('/^(.*?),(.*?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER); 240*38a47c60SMark Prins preg_match_all('/^([+-]?[0-9].*?),([+-]?[0-9].*?),(.*?),(.*?),(.*?),(.*)$/um', $str_points, $point, PREG_SET_ORDER); 241*38a47c60SMark Prins 242*38a47c60SMark Prins $overlay = array (); 243*38a47c60SMark Prins foreach ($point as $pt) { 244*38a47c60SMark Prins list ($match, $lat, $lon, $angle, $opacity, $img, $text) = $pt; 245*38a47c60SMark Prins $lat = is_numeric($lat) ? $lat : 0; 246*38a47c60SMark Prins $lon = is_numeric($lon) ? $lon : 0; 247*38a47c60SMark Prins $angle = is_numeric($angle) ? $angle : 0; 248*38a47c60SMark Prins $opacity = is_numeric($opacity) ? $opacity : 0.8; 249*38a47c60SMark Prins $img = trim($img); 250*38a47c60SMark Prins // TODO validate & set up default img? 251*38a47c60SMark Prins $text = addslashes(str_replace("\n", "", p_render("xhtml", p_get_instructions($text), $info))); 252*38a47c60SMark Prins $overlay[] = array ( 253*38a47c60SMark Prins $lat, 254*38a47c60SMark Prins $lon, 255*38a47c60SMark Prins $text, 256*38a47c60SMark Prins $angle, 257*38a47c60SMark Prins $opacity, 258*38a47c60SMark Prins $img 259*38a47c60SMark Prins ); 260*38a47c60SMark Prins } 261*38a47c60SMark Prins return $overlay; 262*38a47c60SMark Prins } 263*38a47c60SMark Prins}