1 <?php
2 /**
3  * DokuWiki Plugin cnmap (Syntax Component)
4  *
5  * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
6  * @author  Lshan <ldg@szzxue.com>
7  */
8 
9 // must be run within Dokuwiki
10 if (!defined('DOKU_INC')) {
11     die();
12 }
13 
14 class syntax_plugin_cnmap extends DokuWiki_Syntax_Plugin
15 {
16     private $css_len_pattern ="/(^(auto|0)$|^[+-]?[0-9]+\.?([0-9]+)?)(px|em|ex|%|in|cm|mm|pt|pc)$/";
17     private $providers = array('amap','bmap') ;
18 
19     private $amap_script_src = '<script src="https://webapi.amap.com/maps?';
20     private $bmap_script_src = '<script type="text/javascript" src="http://api.map.baidu.com/api?';
21 
22     /**
23      * @return string Syntax mode type
24      */
25     public function getType()
26     {
27         return 'substition';
28     }
29 
30     /**
31      * @return string Paragraph type
32      */
33     public function getPType()
34     {
35         return 'block';
36     }
37 
38     /**
39      * @return int Sort order - Low numbers go before high numbers
40      */
41     public function getSort()
42     {
43         return 70;
44     }
45 
46     /**
47      * Connect lookup pattern to lexer.
48      *
49      * @param string $mode Parser mode
50      */
51     public function connectTo($mode)
52     {
53         $this->Lexer->addSpecialPattern('{{cnmap>.*?}}',$mode,'plugin_cnmap');
54     }
55 
56 //    public function postConnect()
57 //    {
58 //        $this->Lexer->addExitPattern('</FIXME>', 'plugin_cnmap');
59 //    }
60 
61     /**
62      * Handle matches of the cnmap syntax
63      *
64      * @param string       $match   The match of the syntax
65      * @param int          $state   The state of the handler
66      * @param int          $pos     The position in the document
67      * @param Doku_Handler $handler The handler
68      *
69      * @return array Data for the renderer
70      */
71     public function handle($match, $state, $pos, Doku_Handler $handler)
72     {
73         $data = $this->parseMatch($match);
74 
75         return $data;
76     }
77 
78     /**
79      * Render xhtml output or metadata
80      *
81      * @param string        $mode     Renderer mode (supported modes: xhtml)
82      * @param Doku_Renderer $renderer The renderer
83      * @param array         $data     The data from the handler() function
84      *
85      * @return bool If rendering was successful.
86      */
87     public function render($mode, Doku_Renderer $renderer, $data)
88     {
89         if ($mode !== 'xhtml') {
90             return false;
91         }
92 
93         $pos = false;
94         switch($data['provider'])
95         {
96             case "amap":
97                 $pos = strpos($renderer->doc, $this->amap_script_src);
98                 break;
99             case "bmap":
100                 $pos = strpos($renderer->doc, $this->bmap_script_src);
101                 break;
102             default:
103                 break;
104         }
105         if ($pos !== false)
106         {
107             $data[0]= "<!-- ";
108             $data[2]= " -->";
109         }
110 
111         $html_tpl = @file_get_contents(__DIR__."/tpl/".$data['provider'].".tpl.html");
112         $html = @vsprintf($html_tpl,  $data);
113         $renderer->doc .= $html ;
114 
115         return true;
116     }
117 
118     /**
119      * Parse and validate matches of the cnmap syntax
120      *
121      * @param string       $match   The match of the syntax
122      * Example :
123      *   {{cnmap>?lng=116.397428&lat=39.90923}}
124      *   {{cnmap>bmap?lng=116.397428&lat=39.90923&width=100%&height=500px&zoom=17&title=title of marker&mark=yes&sat=yes}}
125      *
126      * @return array Data for the renderer
127      */
128     public function parseMatch($match) {
129         $match = substr($match, strlen('{{cnmap>'), -strlen('}}'));
130         list($provider, $query) = explode('?', $match, 2);
131 
132         $args = array();
133         parse_str($query, $args);
134 
135         $args['provider'] = in_array($provider, $this->providers)? $provider : $this->getConf('provider');
136 
137         $args['zoom'] = intval($args['zoom']);
138         if($args['zoom'] < 3 || $args['zoom'] > 19)
139             $args['zoom'] = $this->getConf('zoom');
140 
141         if(preg_match($this->css_len_pattern, $args['width']) != 1 )
142             $args['width'] = $this->getConf('width');
143 
144         if(preg_match($this->css_len_pattern, $args['height']) != 1 )
145             $args['height'] = $this->getConf('height');
146 
147         if(!isset($args['title']))
148             $args['title']='';
149 
150         if(!isset($args['mark']))
151             $args['mark']= $this->getConf('mark');
152          else
153         {
154              $args['mark'] = strtolower($args['mark']);
155              $args['mark'] = (($args['mark'] == 'y') || ($args['mark'] == 'yes')|| ($args['mark'] == 'on'));
156         }
157 
158         if(!isset($args['sat']))
159             $args['sat']= $this->getConf('sat');
160          else
161         {
162              $args['sat'] = strtolower($args['sat']);
163              $args['sat'] = (($args['sat'] == 'y') || ($args['sat'] == 'yes')|| ($args['sat'] == 'on'));
164         }
165 
166         switch($args['provider'])
167         {
168             case "amap":
169                 return $this->parseMatchAmap($args);
170             case "bmap":
171                 return $this->parseMatchBmap($args);
172             default:
173                 return $this->parseMatchAmap($args);
174         }
175     }
176 
177     /**
178      * Parse and validate args of the amap syntax
179      *
180      * @param array       $args   The match of the syntax
181      *   Ref : https://lbs.amap.com/api/javascript-api/summary
182      *
183      * @return array Data for the renderer
184      */
185     public function parseMatchAmap($args) {
186         $id = rand(1000,2000);
187         $container_id ="amap_container_".$id;
188 
189         $args['title']=addslashes($args['title']);
190         $args['title']=str_replace("<","\\<", $args['title']);
191         $args['title']=str_replace(">","\\>", $args['title']);
192 
193         $data = array();
194         array_push($data,  "");
195         array_push($data,  $this->getConf('amap_api_key'));
196         array_push($data,  "");
197 
198         array_push($data,  $container_id);
199         array_push($data,  $args['width']);
200         array_push($data,  $args['height']);
201         array_push($data,  $container_id);
202         array_push($data,  $id);
203         array_push($data,  $args['lng']);
204         array_push($data,  $args['lat']);
205         array_push($data,  $container_id);
206         array_push($data,  $args['zoom']);
207         array_push($data,  $args['mark']?"true":"false");
208         array_push($data,  $args['title']);
209         array_push($data,  $args['sat']?"true":"false");
210         array_push($data,  $id);
211 
212         $data['provider']= $args['provider'];
213 
214         return $data;
215     }
216 
217     /**
218      * Parse and validate args of the bmap syntax
219      *
220      * @param array       $args   The match of the syntax
221      *   Ref : http://lbsyun.baidu.com/index.php?title=jspopular
222      *
223      * @return array Data for the renderer
224      */
225     public function parseMatchBmap($args) {
226         $id = rand(2000,3000);
227         $container_id ="bmap_container_".$id;
228 
229         $args['title']=addslashes($args['title']);
230         $args['title']=str_replace("<","\\<", $args['title']);
231         $args['title']=str_replace(">","\\>", $args['title']);
232 
233         $data = array();
234         array_push($data,  "");
235         array_push($data,  $this->getConf('bmap_api_key'));
236         array_push($data,  "");
237 
238         array_push($data,  $container_id);
239         array_push($data,  $args['width']);
240         array_push($data,  $args['height']);
241         array_push($data,  $container_id);
242         array_push($data,  $id);
243         array_push($data,  $args['lng']);
244         array_push($data,  $args['lat']);
245         array_push($data,  $container_id);
246         array_push($data,  $args['zoom']);
247         array_push($data,  $args['mark']?"true":"false");
248         array_push($data,  $args['title']);
249         array_push($data,  $args['sat']?"true":"false");
250         array_push($data,  $id);
251 
252         $data['provider']= $args['provider'];
253 
254         return $data;
255     }
256 }
257 
258