1<?php
2/**
3 * Plugin Google Maps: Allow Display of a Google Map in a wiki page.
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Christopher Smith <chris@jalakai.co.uk>
7 * @author     Borodin Oleg <onborodin@gmail.com>
8 */
9
10if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../').'/');
11if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
12require_once(DOKU_PLUGIN.'syntax.php');
13
14// ---------- [ Settings ] -----------------------------------------
15
16/**
17 * All DokuWiki plugins to extend the parser/rendering mechanism
18 * need to inherit from this class
19 */
20class syntax_plugin_googlemap3 extends DokuWiki_Syntax_Plugin {
21
22    var $dflt = array(
23      'type' => 'map',
24      'width' => '',
25      'height' => '',
26      'lat'  => 0,
27      'lng' => 0,
28      'zoom' => 4,
29      'controls' => 'on',
30      'kml' => 'off',
31      'helper' => 'on'
32    );
33
34    function getInfo(){
35      return array(
36        'author' => 'Borodin Oleg',
37        'email'  => 'onborodin@gmail.com',
38        'date'   => '2008-11-11',
39        'name'   => 'Google Maps Plugin',
40        'desc'   => 'Add maps to your wiki
41                     Syntax: <googlemap params>overlaypoints</googlemap>',
42        'url'    => 'http://wantus.homeunix.org/en/unix/googlemaps',
43      );
44    }
45
46    function getType() { return 'substition'; }
47    function getPType() { return 'block'; }
48    function getSort() { return 900; }
49
50    function connectTo($mode) {
51        $this->Lexer->addSpecialPattern('<googlemap3 ?[^>\n]*>.*?</googlemap3>',$mode,'plugin_googlemap3');
52    }
53
54
55    function handle($match, $state, $pos, &$handler){
56
57      // break matched cdata into its components
58      list($str_params,$str_points) = explode('>',substr($match,10,-12),2);
59
60      $gmap = $this->_extract_params($str_params);
61      $overlay = $this->_extract_points($str_points);
62
63
64      // determine width and height (inline styles) for the map image
65      if ($gmap['width'] || $gmap['height']) {
66        $style = $gmap['width'] ? 'width: '.$gmap['width'].";" : "";
67        $style .= $gmap['height'] ? 'height: '.$gmap['height'].";" : "";
68        $style = "style='$style'";
69      } else {
70        $style = '';
71      }
72
73      // unset gmap values for width and height - they don't go into javascript
74      unset($gmap['width'],$gmap['height']);
75
76      // create a javascript parameter string for the map
77      $param = '';
78      foreach ($gmap as $key => $val) {
79          $param .= is_numeric($val) ? " $key : $val," : "$key : '".hsc($val)."',";
80      }
81
82      if (!empty($param)) $param = substr($param,0,-1);
83
84      // create a javascript serialisation of the point data
85      $points = '';
86      if (!empty($overlay)) {
87        foreach ($overlay as $data) {
88          list($lat,$lng,$msg,$text) = $data;
89          $points .= ",{lat:$lat, lng:$lng, msg: '$msg', txt: '$text'}";
90        }
91        $points = ", overlay : [ ".substr($points,1)." ]";
92      }
93
94      $js = "googleMapArray[googleMapArray.length] = {".$param.$points." }; ";
95
96      return array($style, $js);
97    }
98
99    function render($mode, &$renderer, $data) {
100
101      if ($mode == 'xhtml') {
102        list($style, $param) = $data;
103
104        // set parameters for init_googlemap3()
105        $renderer->doc .= "
106<div class='googlemap3' $style>
107<script type='text/javascript' charset='utf-8'><!--//--><![CDATA[//><!--
108
109$param
110
111if ( googlscriptloaded < 1) {
112  window.onload = loadScript;
113  googlscriptloaded++;
114}
115
116//--><!]]></script>
117</div>
118";
119      }
120      return false;
121    }
122
123    /**
124     * extract parameters for the googlemap from the parameter string
125     *
126     * @param   string    $str_params   string of key="value" pairs
127     * @return  array                   associative array of parameters key=>value
128     */
129    function _extract_params($str_params) {
130
131      $param = array();
132      preg_match_all('/(\w*)="(.*?)"/us',$str_params,$param,PREG_SET_ORDER);
133
134      // parse match for instructions, break into key value pairs
135      $gmap = $this->dflt;
136      foreach($param as $kvpair) {
137        list($match,$key,$val) = $kvpair;
138        $key = strtolower($key);
139        if (isset($gmap[$key])) $gmap[$key] = strtolower($val);
140      }
141
142      return $gmap;
143    }
144
145    /**
146     * extract overlay points for the googlemap from the wiki syntax data
147     *
148     * @param   string    $str_points   multi-line string of lat,lng,msg,text
149     * @return  array                   multi-dimensional array of lat,lng,msg,text
150     */
151    function _extract_points($str_points) {
152
153      $point = array();
154      preg_match_all('/^(.*?)[;,](.*?)[;,](.*?);(.*)$/um',$str_points,$point,PREG_SET_ORDER);
155
156      $overlay = array();
157      foreach ($point as $pt) {
158        list($match,$lat,$lng,$msg,$text) = $pt;
159
160        $lat = is_numeric($lat) ? $lat : 0;
161        $lng = is_numeric($lng) ? $lng : 0;
162
163        $text = addslashes(str_replace("\n","",p_render("xhtml",p_get_instructions($text),$info)));
164
165        $overlay[] = array($lat,$lng,$msg,$text);
166      }
167
168      return $overlay;
169    }
170
171}
172/* EOF */