Passed
Push — master ( 630eee...e4be3b )
by Mark
05:32 queued 10s
created

syntax_plugin_openlayersmap_olmap   F

Complexity

Total Complexity 107

Size/Duplication

Total Lines 844
Duplicated Lines 0 %

Importance

Changes 62
Bugs 12 Features 9
Metric Value
eloc 432
c 62
b 12
f 9
dl 0
loc 844
rs 2
wmc 107

16 Methods

Rating   Name   Duplication   Size   Complexity  
A getPType() 0 2 1
F handle() 0 165 19
A connectTo() 0 4 1
A getType() 0 2 1
A getSort() 0 2 1
A convertDDtoDMS() 0 7 1
A calcBBOX() 0 20 2
B getGoogle() 0 51 11
B extractParams() 0 28 7
A convertLon() 0 8 2
D getStaticOSM() 0 106 19
A getFileName() 0 7 1
C getBing() 0 57 14
F render() 0 115 19
B extractPoints() 0 41 6
A convertLat() 0 8 2

How to fix   Complexity   

Complex Class

Complex classes like syntax_plugin_openlayersmap_olmap often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use syntax_plugin_openlayersmap_olmap, and based on these observations, apply Extract Interface, too.

1
<?php
2
/*
3
 * Copyright (c) 2008-2021 Mark C. Prins <[email protected]>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 *
17
 * @phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
18
 */
19
20
/**
21
 * DokuWiki Plugin openlayersmap (Syntax Component).
22
 * Provides for display of an OpenLayers based map in a wiki page.
23
 *
24
 * @author Mark Prins
25
 */
26
class syntax_plugin_openlayersmap_olmap extends DokuWiki_Syntax_Plugin {
0 ignored issues
show
Bug introduced by
The type DokuWiki_Syntax_Plugin was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
27
28
    /**
29
     * defaults of the known attributes of the olmap tag.
30
     */
31
    private $dflt = array(
32
        'id'            => 'olmap',
33
        'width'         => '550px',
34
        'height'        => '450px',
35
        'lat'           => 50.0,
36
        'lon'           => 5.1,
37
        'zoom'          => 12,
38
        'autozoom'      => 1,
39
        'statusbar'     => true,
40
        'toolbar'       => true,
41
        'controls'      => true,
42
        'poihoverstyle' => false,
43
        'baselyr'       => 'OpenStreetMap',
44
        'gpxfile'       => '',
45
        'kmlfile'       => '',
46
        'geojsonfile'   => '',
47
        'summary'       => ''
48
    );
49
50
    /**
51
     *
52
     * @see DokuWiki_Syntax_Plugin::getType()
53
     */
54
    public function getType(): string {
55
        return 'substition';
56
    }
57
58
    /**
59
     *
60
     * @see DokuWiki_Syntax_Plugin::getPType()
61
     */
62
    public function getPType(): string {
63
        return 'block';
64
    }
65
66
    /**
67
     *
68
     * @see Doku_Parser_Mode::getSort()
69
     */
70
    public function getSort(): int {
71
        return 901;
72
    }
73
74
    /**
75
     *
76
     * @see Doku_Parser_Mode::connectTo()
77
     */
78
    public function connectTo($mode) {
79
        $this->Lexer->addSpecialPattern(
80
            '<olmap ?[^>\n]*>.*?</olmap>', $mode,
81
            'plugin_openlayersmap_olmap'
82
        );
83
    }
84
85
    /**
86
     *
87
     * @see DokuWiki_Syntax_Plugin::handle()
88
     */
89
    public function handle($match, $state, $pos, Doku_Handler $handler): array {
0 ignored issues
show
Bug introduced by
The type Doku_Handler was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
90
        // break matched cdata into its components
91
        list ($str_params, $str_points) = explode('>', substr($match, 7, -9), 2);
92
        // get the lat/lon for adding them to the metadata (used by geotag)
93
        preg_match('(lat[:|=]\"-?\d*\.?\d*\")', $match, $mainLat);
94
        preg_match('(lon[:|=]\"-?\d*\.?\d*\")', $match, $mainLon);
95
        $mainLat = substr($mainLat [0], 5, -1);
96
        $mainLon = substr($mainLon [0], 5, -1);
97
        if(!is_numeric($mainLat)) {
98
            $mainLat = $this->dflt ['lat'];
99
        }
100
        if(!is_numeric($mainLon)) {
101
            $mainLon = $this->dflt ['lon'];
102
        }
103
104
        $gmap          = $this->extractParams($str_params);
105
        $overlay       = $this->extractPoints($str_points);
106
        $_firstimageID = '';
107
108
        $_nocache = false;
109
        // choose maptype based on the specified tag
110
        $imgUrl = "{{";
111
        if(stripos($gmap ['baselyr'], 'google') !== false) {
112
            // Google
113
            $imgUrl .= $this->getGoogle($gmap, $overlay);
114
            $imgUrl .= "&.png";
115
        } elseif(stripos($gmap ['baselyr'], 'bing') !== false) {
116
            // Bing
117
            if(!$this->getConf('bingAPIKey')) {
118
                // in case there is no Bing api key we'll use OSM
119
                $_firstimageID = $this->getStaticOSM($gmap, $overlay);
120
                $imgUrl        .= $_firstimageID;
121
                if($this->getConf('optionStaticMapGenerator') == 'remote') {
122
                    $imgUrl .= "&.png";
123
                }
124
            } else {
125
                // seems that Bing doesn't like the DW client, turn off caching
126
                $_nocache = true;
127
                $imgUrl   .= $this->getBing($gmap, $overlay) . "&.png";
128
            }
129
        } /* elseif (stripos ( $gmap ['baselyr'], 'mapquest' ) !== false) {
130
            // MapQuest
131
            if (! $this->getConf ( 'mapquestAPIKey' )) {
132
                // no API key for MapQuest, use OSM
133
                $_firstimageID = $this->getStaticOSM ( $gmap, $overlay );
134
                $imgUrl .= $_firstimageID;
135
                if ($this->getConf ( 'optionStaticMapGenerator' ) == 'remote') {
136
                    $imgUrl .= "&.png";
137
                }
138
            } else {
139
                $imgUrl .= $this->_getMapQuest ( $gmap, $overlay );
140
                $imgUrl .= "&.png";
141
            }
142
        } */ else {
143
            // default OSM
144
            $_firstimageID = $this->getStaticOSM($gmap, $overlay);
145
            $imgUrl        .= $_firstimageID;
146
            if($this->getConf('optionStaticMapGenerator') == 'remote') {
147
                $imgUrl .= "&.png";
148
            }
149
        }
150
151
        // append dw p_render specific params and render
152
        $imgUrl .= "?" . str_replace("px", "", $gmap ['width']) . "x"
153
            . str_replace("px", "", $gmap ['height']);
154
        $imgUrl .= "&nolink";
155
156
        // add nocache option for selected services
157
        if($_nocache) {
158
            $imgUrl .= "&nocache";
159
        }
160
161
        $imgUrl .= " |" . $gmap ['summary'] . " }}";
162
163
        // dbglog($imgUrl,"complete image tags is:");
164
165
        $mapid = $gmap ['id'];
166
        // create a javascript parameter string for the map
167
        $param = '';
168
        foreach($gmap as $key => $val) {
169
            $param .= is_numeric($val) ? "$key: $val, " : "$key: '" . hsc($val) . "', ";
0 ignored issues
show
Bug introduced by
The function hsc was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

169
            $param .= is_numeric($val) ? "$key: $val, " : "$key: '" . /** @scrutinizer ignore-call */ hsc($val) . "', ";
Loading history...
170
        }
171
        if(!empty ($param)) {
172
            $param = substr($param, 0, -2);
173
        }
174
        unset ($gmap ['id']);
175
176
        // create a javascript serialisation of the point data
177
        $poi      = '';
178
        $poitable = '';
179
        $rowId    = 0;
180
        if(!empty ($overlay)) {
181
            foreach($overlay as $data) {
182
                list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
183
                $rowId++;
184
                $poi .= ", {lat:$lat,lon:$lon,txt:'$text',angle:$angle,opacity:$opacity,img:'$img',rowId: $rowId}";
185
186
                if($this->getConf('displayformat') === 'DMS') {
187
                    $lat = $this->convertLat($lat);
188
                    $lon = $this->convertLon($lon);
189
                } else {
190
                    $lat .= 'º';
191
                    $lon .= 'º';
192
                }
193
194
                $poitable .= '
195
                    <tr>
196
                    <td class="rowId">' . $rowId . '</td>
197
                    <td class="icon"><img src="' . DOKU_BASE . 'lib/plugins/openlayersmap/icons/' . $img . '" alt="'
0 ignored issues
show
Bug introduced by
The constant DOKU_BASE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
198
                    . substr($img, 0, -4) . $this->getlang('alt_legend_poi') . '" /></td>
199
                    <td class="lat" title="' . $this->getLang('olmapPOIlatTitle') . '">' . $lat . '</td>
200
                    <td class="lon" title="' . $this->getLang('olmapPOIlonTitle') . '">' . $lon . '</td>
201
                    <td class="txt">' . $text . '</td>
202
                    </tr>';
203
            }
204
            $poi = substr($poi, 2);
205
        }
206
        if(!empty ($gmap ['kmlfile'])) {
207
            $poitable .= '
208
                    <tr>
209
                    <td class="rowId"><img src="' . DOKU_BASE
210
                . 'lib/plugins/openlayersmap/toolbar/kml_file.png" alt="KML file" /></td>
211
                    <td class="icon"><img src="' . DOKU_BASE . 'lib/plugins/openlayersmap/toolbar/kml_line.png" alt="'
212
                . $this->getlang('alt_legend_kml') . '" /></td>
213
                    <td class="txt" colspan="3">KML track: ' . $this->getFileName($gmap ['kmlfile']) . '</td>
214
                    </tr>';
215
        }
216
        if(!empty ($gmap ['gpxfile'])) {
217
            $poitable .= '
218
                    <tr>
219
                    <td class="rowId"><img src="' . DOKU_BASE
220
                . 'lib/plugins/openlayersmap/toolbar/gpx_file.png" alt="GPX file" /></td>
221
                    <td class="icon"><img src="' . DOKU_BASE
222
                . 'lib/plugins/openlayersmap/toolbar/gpx_line.png" alt="'
223
                . $this->getlang('alt_legend_gpx') . '" /></td>
224
                    <td class="txt" colspan="3">GPX track: ' . $this->getFileName($gmap ['gpxfile']) . '</td>
225
                    </tr>';
226
        }
227
        if(!empty ($gmap ['geojsonfile'])) {
228
            $poitable .= '
229
                    <tr>
230
                    <td class="rowId"><img src="' . DOKU_BASE
231
                . 'lib/plugins/openlayersmap/toolbar/geojson_file.png" alt="GeoJSON file" /></td>
232
                    <td class="icon"><img src="' . DOKU_BASE
233
                . 'lib/plugins/openlayersmap/toolbar/geojson_line.png" alt="'
234
                . $this->getlang('alt_legend_geojson') . '" /></td>
235
                    <td class="txt" colspan="3">GeoJSON track: ' . $this->getFileName($gmap ['geojsonfile']) . '</td>
236
                    </tr>';
237
        }
238
239
        $autozoom = empty ($gmap ['autozoom']) ? $this->getConf('autoZoomMap') : $gmap ['autozoom'];
240
        $js       = "{mapOpts: {" . $param . ", displayformat: '" . $this->getConf('displayformat')
241
            . "', autozoom: " . $autozoom . "}, poi: [$poi]};";
242
        // unescape the json
243
        $poitable = stripslashes($poitable);
244
245
        return array(
246
            $mapid,
247
            $js,
248
            $mainLat,
249
            $mainLon,
250
            $poitable,
251
            $gmap ['summary'],
252
            $imgUrl,
253
            $_firstimageID
254
        );
255
    }
256
257
    /**
258
     * extract parameters for the map from the parameter string
259
     *
260
     * @param string $str_params
261
     *            string of key="value" pairs
262
     * @return array associative array of parameters key=>value
263
     */
264
    private function extractParams(string $str_params): array {
265
        $param = array();
266
        preg_match_all('/(\w*)="(.*?)"/us', $str_params, $param, PREG_SET_ORDER);
267
        // parse match for instructions, break into key value pairs
268
        $gmap = $this->dflt;
269
        foreach($gmap as $key => &$value) {
270
            $defval = $this->getConf('default_' . $key);
271
            if($defval !== '') {
272
                $value = $defval;
273
            }
274
        }
275
        unset ($value);
276
        foreach($param as $kvpair) {
277
            list ($match, $key, $val) = $kvpair;
278
            $key = strtolower($key);
279
            if(isset ($gmap [$key])) {
280
                if($key == 'summary') {
281
                    // preserve case for summary field
282
                    $gmap [$key] = $val;
283
                } elseif($key == 'id') {
284
                    // preserve case for id field
285
                    $gmap [$key] = $val;
286
                } else {
287
                    $gmap [$key] = strtolower($val);
288
                }
289
            }
290
        }
291
        return $gmap;
292
    }
293
294
    /**
295
     * extract overlay points for the map from the wiki syntax data
296
     *
297
     * @param string $str_points
298
     *            multi-line string of lat,lon,text triplets
299
     * @return array multi-dimensional array of lat,lon,text triplets
300
     */
301
    private function extractPoints(string $str_points): array {
302
        $point = array();
303
        // preg_match_all('/^([+-]?[0-9].*?),\s*([+-]?[0-9].*?),(.*?),(.*?),(.*?),(.*)$/um',
304
        //      $str_points, $point, PREG_SET_ORDER);
305
        /*
306
         * group 1: ([+-]?[0-9]+(?:\.[0-9]*)?)
307
         * group 2: ([+-]?[0-9]+(?:\.[0-9]*)?)
308
         * group 3: (.*?)
309
         * group 4: (.*?)
310
         * group 5: (.*?)
311
         * group 6: (.*)
312
         */
313
        preg_match_all(
314
            '/^([+-]?[0-9]+(?:\.[0-9]*)?),\s*([+-]?[0-9]+(?:\.[0-9]*)?),(.*?),(.*?),(.*?),(.*)$/um',
315
            $str_points, $point, PREG_SET_ORDER
316
        );
317
        // create poi array
318
        $overlay = array();
319
        foreach($point as $pt) {
320
            list ($match, $lat, $lon, $angle, $opacity, $img, $text) = $pt;
321
            $lat     = is_numeric($lat) ? $lat : 0;
322
            $lon     = is_numeric($lon) ? $lon : 0;
323
            $angle   = is_numeric($angle) ? $angle : 0;
324
            $opacity = is_numeric($opacity) ? $opacity : 0.8;
325
            // TODO validate using exist & set up default img?
326
            $img  = trim($img);
327
            $text = p_get_instructions($text);
0 ignored issues
show
Bug introduced by
The function p_get_instructions was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

327
            $text = /** @scrutinizer ignore-call */ p_get_instructions($text);
Loading history...
328
            // dbg ( $text );
329
            $text = p_render("xhtml", $text, $info);
0 ignored issues
show
Bug introduced by
The function p_render was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

329
            $text = /** @scrutinizer ignore-call */ p_render("xhtml", $text, $info);
Loading history...
Comprehensibility Best Practice introduced by
The variable $info seems to be never defined.
Loading history...
330
            // dbg ( $text );
331
            $text       = addslashes(str_replace("\n", "", $text));
332
            $overlay [] = array(
333
                $lat,
334
                $lon,
335
                $text,
336
                $angle,
337
                $opacity,
338
                $img
339
            );
340
        }
341
        return $overlay;
342
    }
343
344
    /**
345
     * Create a Google maps static image url w/ the poi.
346
     *
347
     * @param array $gmap
348
     * @param array $overlay
349
     * @return string
350
     */
351
    private function getGoogle(array $gmap, array $overlay): string {
352
        $sUrl = $this->getConf('iconUrlOverload');
353
        if(!$sUrl) {
354
            $sUrl = DOKU_URL;
0 ignored issues
show
Bug introduced by
The constant DOKU_URL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
355
        }
356
        switch($gmap ['baselyr']) {
357
            case 'google hybrid' :
358
                $maptype = 'hybrid';
359
                break;
360
            case 'google sat' :
361
                $maptype = 'satellite';
362
                break;
363
            case 'terrain' :
364
            case 'google relief' :
365
                $maptype = 'terrain';
366
                break;
367
            case 'google road' :
368
            default :
369
                $maptype = 'roadmap';
370
                break;
371
        }
372
        // TODO maybe use viewport / visible instead of center/zoom,
373
        // see: https://developers.google.com/maps/documentation/staticmaps/index#Viewports
374
        // http://maps.google.com/maps/api/staticmap?center=51.565690,5.456756&zoom=16&size=600x400&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/marker.png|label:1|51.565690,5.456756&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/marker-blue.png|51.566197,5.458966|label:2&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.567177,5.457909|label:3&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.566283,5.457330|label:4&markers=icon:http://wild-water.nl/dokuwiki/lib/plugins/openlayersmap/icons/parking.png|51.565630,5.457695|label:5&sensor=false&format=png&maptype=roadmap
375
        $imgUrl = "https://maps.googleapis.com/maps/api/staticmap?";
376
        $imgUrl .= "&size=" . str_replace("px", "", $gmap ['width']) . "x"
377
            . str_replace("px", "", $gmap ['height']);
378
        //if (!$this->getConf( 'autoZoomMap')) { // no need for center & zoom params }
379
        $imgUrl .= "&center=" . $gmap ['lat'] . "," . $gmap ['lon'];
380
        // max is 21 (== building scale), but that's overkill..
381
        if($gmap ['zoom'] > 17) {
382
            $imgUrl .= "&zoom=17";
383
        } else {
384
            $imgUrl .= "&zoom=" . $gmap ['zoom'];
385
        }
386
        if(!empty ($overlay)) {
387
            $rowId = 0;
388
            foreach($overlay as $data) {
389
                list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
390
                $imgUrl .= "&markers=icon%3a" . $sUrl . "lib/plugins/openlayersmap/icons/" . $img . "%7c"
391
                    . $lat . "," . $lon . "%7clabel%3a" . ++$rowId;
392
            }
393
        }
394
        $imgUrl .= "&format=png&maptype=" . $maptype;
395
        global $conf;
396
        $imgUrl .= "&language=" . $conf ['lang'];
397
        if($this->getConf('googleAPIkey')) {
398
            $imgUrl .= "&key=" . $this->getConf('googleAPIkey');
399
        }
400
        // dbglog($imgUrl,'syntax_plugin_openlayersmap_olmap::getGoogle: Google image url is:');
401
        return $imgUrl;
402
    }
403
404
    /**
405
     * Create a MapQuest static map API image url.
406
     *
407
     * @param array $gmap
408
     * @param array $overlay
409
     */
410
    /*
411
   private function _getMapQuest($gmap, $overlay) {
412
       $sUrl = $this->getConf ( 'iconUrlOverload' );
413
       if (! $sUrl) {
414
           $sUrl = DOKU_URL;
415
       }
416
       switch ($gmap ['baselyr']) {
417
           case 'mapquest hybrid' :
418
               $maptype = 'hyb';
419
               break;
420
           case 'mapquest sat' :
421
               // because sat coverage is very limited use 'hyb' instead of 'sat' so we don't get a blank map
422
               $maptype = 'hyb';
423
               break;
424
           case 'mapquest road' :
425
           default :
426
               $maptype = 'map';
427
               break;
428
       }
429
       $imgUrl = "http://open.mapquestapi.com/staticmap/v4/getmap?declutter=true&";
430
       if (count ( $overlay ) < 1) {
431
           $imgUrl .= "?center=" . $gmap ['lat'] . "," . $gmap ['lon'];
432
           // max level for mapquest is 16
433
           if ($gmap ['zoom'] > 16) {
434
               $imgUrl .= "&zoom=16";
435
           } else {
436
               $imgUrl .= "&zoom=" . $gmap ['zoom'];
437
           }
438
       }
439
       // use bestfit instead of center/zoom, needs upperleft/lowerright corners
440
       // $bbox=$this->calcBBOX($overlay, $gmap['lat'], $gmap['lon']);
441
       // $imgUrl .= "bestfit=".$bbox['minlat'].",".$bbox['maxlon'].",".$bbox['maxlat'].",".$bbox['minlon'];
442
443
       // TODO declutter option works well for square maps but not for rectangular, maybe compensate for that
444
       //       or compensate the mbr..
445
446
       $imgUrl .= "&size=" . str_replace ( "px", "", $gmap ['width'] ) . "," . str_replace ("px","",$gmap['height']);
447
448
       // TODO mapquest allows using one image url with a multiplier $NUMBER eg:
449
       // $NUMBER = 2
450
       // $imgUrl .= DOKU_URL."/".DOKU_PLUGIN."/".getPluginName()."/icons/".$img.",$NUMBER,C,"
451
        //  .$lat1.",".$lon1.",0,0,0,0,C,".$lat2.",".$lon2.",0,0,0,0";
452
       if (! empty ( $overlay )) {
453
           $imgUrl .= "&xis=";
454
           foreach ( $overlay as $data ) {
455
               list ( $lat, $lon, $text, $angle, $opacity, $img ) = $data;
456
               // $imgUrl .= $sUrl."lib/plugins/openlayersmap/icons/".$img.",1,C,".$lat.",".$lon.",0,0,0,0,";
457
               $imgUrl .= $sUrl . "lib/plugins/openlayersmap/icons/" . $img . ",1,C," . $lat . "," . $lon . ",";
458
           }
459
           $imgUrl = substr ( $imgUrl, 0, - 1 );
460
       }
461
       $imgUrl .= "&imageType=png&type=" . $maptype;
462
       $imgUrl .= "&key=".$this->getConf ( 'mapquestAPIKey' );
463
       // dbglog($imgUrl,'syntax_plugin_openlayersmap_olmap::_getMapQuest: MapQuest image url is:');
464
       return $imgUrl;
465
   }
466
   */
467
468
    /**
469
     * Create a static OSM map image url w/ the poi from http://staticmap.openstreetmap.de (staticMapLite)
470
     * use http://staticmap.openstreetmap.de "staticMapLite" or a local version
471
     *
472
     * @param array $gmap
473
     * @param array $overlay
474
     *
475
     * @return false|string
476
     * @todo implementation for http://ojw.dev.openstreetmap.org/StaticMapDev/
477
     */
478
    private function getStaticOSM(array $gmap, array $overlay) {
479
        global $conf;
480
481
        if($this->getConf('optionStaticMapGenerator') == 'local') {
482
            // using local basemap composer
483
            if(!$myMap = plugin_load('helper', 'openlayersmap_staticmap')) {
0 ignored issues
show
Bug introduced by
The function plugin_load was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

483
            if(!$myMap = /** @scrutinizer ignore-call */ plugin_load('helper', 'openlayersmap_staticmap')) {
Loading history...
484
                dbglog(
0 ignored issues
show
Bug introduced by
The function dbglog was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

484
                /** @scrutinizer ignore-call */ 
485
                dbglog(
Loading history...
485
                    $myMap,
486
                    'openlayersmap_staticmap plugin is not available for use.'
487
                );
488
            }
489
            if(!$geophp = plugin_load('helper', 'geophp')) {
490
                dbglog($geophp, 'geophp plugin is not available for use.');
491
            }
492
            $size = str_replace("px", "", $gmap ['width']) . "x"
493
                . str_replace("px", "", $gmap ['height']);
494
495
            $markers = array();
496
            if(!empty ($overlay)) {
497
                foreach($overlay as $data) {
498
                    list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
499
                    $iconStyle  = substr($img, 0, strlen($img) - 4);
500
                    $markers [] = array(
501
                        'lat'  => $lat,
502
                        'lon'  => $lon,
503
                        'type' => $iconStyle
504
                    );
505
                }
506
            }
507
508
            $apikey = '';
509
            switch($gmap ['baselyr']) {
510
                case 'mapnik' :
511
                case 'openstreetmap' :
512
                    $maptype = 'openstreetmap';
513
                    break;
514
                case 'transport' :
515
                    $maptype = 'transport';
516
                    $apikey  = $this->getConf('tfApiKey');
0 ignored issues
show
Unused Code introduced by
The assignment to $apikey is dead and can be removed.
Loading history...
517
                    break;
518
                case 'landscape' :
519
                    $maptype = 'landscape';
520
                    $apikey  = $this->getConf('tfApiKey');
521
                    break;
522
                case 'outdoors' :
523
                    $maptype = 'outdoors';
524
                    $apikey  = $this->getConf('tfApiKey');
525
                    break;
526
                case 'cycle map' :
527
                    $maptype = 'cycle';
528
                    $apikey  = $this->getConf('tfApiKey');
529
                    break;
530
                case 'hike and bike map' :
531
                    $maptype = 'hikeandbike';
532
                    break;
533
                case 'mapquest hybrid' :
534
                case 'mapquest road' :
535
                case 'mapquest sat' :
536
                    $maptype = 'mapquest';
537
                    break;
538
                default :
539
                    $maptype = '';
540
                    break;
541
            }
542
543
            $result = $myMap->getMap(
544
                $gmap ['lat'], $gmap ['lon'], $gmap ['zoom'], $size, $maptype, $markers,
545
                $gmap ['gpxfile'], $gmap ['kmlfile'], $gmap ['geojsonfile']
546
            );
547
        } else {
548
            // using external basemap composer
549
550
            // https://staticmap.openstreetmap.de/staticmap.php?center=47.000622235634,10
551
            //.117187497601&zoom=5&size=500x350
552
            // &markers=48.999812532766,8.3593749976708,lightblue1|43.154850037315,17.499999997306,
553
            //  lightblue1|49.487527053077,10.820312497573,ltblu-pushpin|47.951071133739,15.917968747369,
554
            //  ol-marker|47.921629720114,18.027343747285,ol-marker-gold|47.951071133739,19.257812497236,
555
            //  ol-marker-blue|47.180141361692,19.257812497236,ol-marker-green
556
            $imgUrl = "https://staticmap.openstreetmap.de/staticmap.php";
557
            $imgUrl .= "?center=" . $gmap ['lat'] . "," . $gmap ['lon'];
558
            $imgUrl .= "&size=" . str_replace("px", "", $gmap ['width']) . "x"
559
                . str_replace("px", "", $gmap ['height']);
560
561
            if($gmap ['zoom'] > 16) {
562
                // actually this could even be 18, but that seems overkill
563
                $imgUrl .= "&zoom=16";
564
            } else {
565
                $imgUrl .= "&zoom=" . $gmap ['zoom'];
566
            }
567
568
            if(!empty ($overlay)) {
569
                $rowId  = 0;
570
                $imgUrl .= "&markers=";
571
                foreach($overlay as $data) {
572
                    list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
573
                    $rowId++;
574
                    $iconStyle = "lightblue$rowId";
575
                    $imgUrl    .= "$lat,$lon,$iconStyle%7c";
576
                }
577
                $imgUrl = substr($imgUrl, 0, -3);
578
            }
579
580
            $result = $imgUrl;
581
        }
582
        // dbglog ( $result, 'syntax_plugin_openlayersmap_olmap::getStaticOSM: osm image url is:' );
583
        return $result;
584
    }
585
586
    /**
587
     * Create a Bing maps static image url w/ the poi.
588
     *
589
     * @param array $gmap
590
     * @param array $overlay
591
     * @return string
592
     */
593
    private function getBing(array $gmap, array $overlay): string {
594
        switch($gmap ['baselyr']) {
595
            case 've hybrid' :
596
            case 'bing hybrid' :
597
                $maptype = 'AerialWithLabels';
598
                break;
599
            case 've sat' :
600
            case 'bing sat' :
601
                $maptype = 'Aerial';
602
                break;
603
            case 've normal' :
604
            case 've road' :
605
            case 've' :
606
            case 'bing road' :
607
            default :
608
                $maptype = 'Road';
609
                break;
610
        }
611
        $imgUrl = "https://dev.virtualearth.net/REST/v1/Imagery/Map/" . $maptype;// . "/";
612
        if($this->getConf('autoZoomMap')) {
613
            $bbox = $this->calcBBOX($overlay, $gmap ['lat'], $gmap ['lon']);
614
            //$imgUrl .= "?ma=" . $bbox ['minlat'] . "," . $bbox ['minlon'] . ","
615
            //          . $bbox ['maxlat'] . "," . $bbox ['maxlon'];
616
            $imgUrl .= "?ma=" . $bbox ['minlat'] . "%2C" . $bbox ['minlon'] . "%2C" . $bbox ['maxlat']
617
                . "%2C" . $bbox ['maxlon'];
618
            $imgUrl .= "&dcl=1";
619
        }
620
        if(strpos($imgUrl, "?") === false)
621
            $imgUrl .= "?";
622
623
        //$imgUrl .= "&ms=" . str_replace ( "px", "", $gmap ['width'] ) . ","
624
        //          . str_replace ( "px", "", $gmap ['height'] );
625
        $imgUrl .= "&ms=" . str_replace("px", "", $gmap ['width']) . "%2C"
626
            . str_replace("px", "", $gmap ['height']);
627
        $imgUrl .= "&key=" . $this->getConf('bingAPIKey');
628
        if(!empty ($overlay)) {
629
            $rowId = 0;
630
            foreach($overlay as $data) {
631
                list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
632
                // TODO icon style lookup, see: http://msdn.microsoft.com/en-us/library/ff701719.aspx for iconStyle
633
                $iconStyle = 32;
634
                $rowId++;
635
                // NOTE: the max number of pushpins is 18! or we have to use POST
636
                //  (http://msdn.microsoft.com/en-us/library/ff701724.aspx)
637
                if($rowId == 18) {
638
                    break;
639
                }
640
                //$imgUrl .= "&pp=$lat,$lon;$iconStyle;$rowId";
641
                $imgUrl .= "&pp=$lat%2C$lon%3B$iconStyle%3B$rowId";
642
643
            }
644
        }
645
        global $conf;
646
        $imgUrl .= "&fmt=png";
647
        $imgUrl .= "&c=" . $conf ['lang'];
648
        // dbglog($imgUrl,'syntax_plugin_openlayersmap_olmap::getBing: bing image url is:');
649
        return $imgUrl;
650
    }
651
652
    /**
653
     * Calculate the minimum bbox for a start location + poi.
654
     *
655
     * @param array $overlay
656
     *            multi-dimensional array of array($lat, $lon, $text, $angle, $opacity, $img)
657
     * @param float $lat
658
     *            latitude for map center
659
     * @param float $lon
660
     *            longitude for map center
661
     * @return array :float array describing the mbr and center point
662
     */
663
    private function calcBBOX(array $overlay, float $lat, float $lon): array {
664
        $lats = array($lat);
665
        $lons = array($lon);
666
        foreach($overlay as $data) {
667
            list ($lat, $lon, $text, $angle, $opacity, $img) = $data;
668
            $lats [] = $lat;
669
            $lons [] = $lon;
670
        }
671
        sort($lats);
672
        sort($lons);
673
        // TODO: make edge/wrap around cases work
674
        $centerlat = $lats [0] + ($lats [count($lats) - 1] - $lats [0]);
675
        $centerlon = $lons [0] + ($lons [count($lats) - 1] - $lons [0]);
676
        return array(
677
            'minlat'    => $lats [0],
678
            'minlon'    => $lons [0],
679
            'maxlat'    => $lats [count($lats) - 1],
680
            'maxlon'    => $lons [count($lats) - 1],
681
            'centerlat' => $centerlat,
682
            'centerlon' => $centerlon
683
        );
684
    }
685
686
    /**
687
     * convert latitude in decimal degrees to DMS+hemisphere.
688
     *
689
     * @param float $decimaldegrees
690
     * @return string
691
     * @todo move this into a shared library
692
     */
693
    private function convertLat(float $decimaldegrees): string {
694
        if(strpos($decimaldegrees, '-') !== false) {
695
            $latPos = "S";
696
        } else {
697
            $latPos = "N";
698
        }
699
        $dms = $this->convertDDtoDMS(abs($decimaldegrees));
700
        return hsc($dms . $latPos);
0 ignored issues
show
Bug introduced by
The function hsc was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

700
        return /** @scrutinizer ignore-call */ hsc($dms . $latPos);
Loading history...
701
    }
702
703
    /**
704
     * Convert decimal degrees to degrees, minutes, seconds format
705
     *
706
     * @param float $decimaldegrees
707
     * @return string dms
708
     * @todo move this into a shared library
709
     */
710
    private function convertDDtoDMS(float $decimaldegrees): string {
711
        $dms  = floor($decimaldegrees);
712
        $secs = ($decimaldegrees - $dms) * 3600;
713
        $min  = floor($secs / 60);
714
        $sec  = round($secs - ($min * 60), 3);
715
        $dms  .= 'º' . $min . '\'' . $sec . '"';
716
        return $dms;
717
    }
718
719
    /**
720
     * convert longitude in decimal degrees to DMS+hemisphere.
721
     *
722
     * @param float $decimaldegrees
723
     * @return string
724
     * @todo move this into a shared library
725
     */
726
    private function convertLon(float $decimaldegrees): string {
727
        if(strpos($decimaldegrees, '-') !== false) {
728
            $lonPos = "W";
729
        } else {
730
            $lonPos = "E";
731
        }
732
        $dms = $this->convertDDtoDMS(abs($decimaldegrees));
733
        return hsc($dms . $lonPos);
0 ignored issues
show
Bug introduced by
The function hsc was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

733
        return /** @scrutinizer ignore-call */ hsc($dms . $lonPos);
Loading history...
734
    }
735
736
    /**
737
     * Figures out the base filename of a media path.
738
     *
739
     * @param string $mediaLink
740
     * @return string
741
     */
742
    private function getFileName(string $mediaLink): string {
743
        $mediaLink = str_replace('[[', '', $mediaLink);
744
        $mediaLink = str_replace(']]', '', $mediaLink);
745
        $mediaLink = substr($mediaLink, 0, -4);
746
        $parts     = explode(':', $mediaLink);
747
        $mediaLink = end($parts);
748
        return str_replace('_', ' ', $mediaLink);
749
    }
750
751
    /**
752
     *
753
     * @see DokuWiki_Syntax_Plugin::render()
754
     */
755
    public function render($format, Doku_Renderer $renderer, $data): bool {
0 ignored issues
show
Bug introduced by
The type Doku_Renderer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
756
        // set to true after external scripts tags are written
757
        static $initialised = false;
758
        // incremented for each map tag in the page source so we can keep track of each map in this page
759
        static $mapnumber = 0;
760
761
        // dbglog($data, 'olmap::render() data.');
762
        list ($mapid, $param, $mainLat, $mainLon, $poitable, $poitabledesc, $staticImgUrl, $_firstimage) = $data;
763
764
        if($format == 'xhtml') {
765
            $olscript     = '';
766
            $olEnable     = false;
0 ignored issues
show
Unused Code introduced by
The assignment to $olEnable is dead and can be removed.
Loading history...
767
            $gscript      = '';
768
            $gEnable      = $this->getConf('enableGoogle');
769
            $stamenEnable = $this->getConf('enableStamen');
770
            $osmEnable    = $this->getConf('enableOSM');
771
            $enableBing   = $this->getConf('enableBing');
772
773
            $scriptEnable = '';
774
            if(!$initialised) {
775
                $initialised = true;
776
                // render necessary script tags
777
                if($gEnable) {
778
                    $gscript = '<script defer="defer" src="//maps.google.com/maps/api/js?v=3.29&amp;key='
779
                        . $this->getConf('googleAPIkey') . '"></script>';
780
                }
781
                $olscript = '<script defer="defer" src="' . DOKU_BASE
0 ignored issues
show
Bug introduced by
The constant DOKU_BASE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
782
                    . 'lib/plugins/openlayersmap/lib/OpenLayers.js"></script>';
783
784
                $scriptEnable = '<script defer="defer" src="data:text/javascript;base64,';
785
                $scriptSrc    = $olscript ? 'olEnable = true;' : 'olEnable = false;';
786
                $scriptSrc    .= 'gEnable = ' . ($gEnable ? 'true' : 'false') . ';';
787
                $scriptSrc    .= 'osmEnable = ' . ($osmEnable ? 'true' : 'false') . ';';
788
                $scriptSrc    .= 'stamenEnable = ' . ($stamenEnable ? 'true' : 'false') . ';';
789
                $scriptSrc    .= 'bEnable = ' . ($enableBing ? 'true' : 'false') . ';';
790
                $scriptSrc    .= 'bApiKey="' . $this->getConf('bingAPIKey') . '";';
791
                $scriptSrc    .= 'tfApiKey="' . $this->getConf('tfApiKey') . '";';
792
                $scriptSrc    .= 'gApiKey="' . $this->getConf('googleAPIkey') . '";';
793
                $scriptEnable .= base64_encode($scriptSrc);
794
                $scriptEnable .= '"></script>';
795
            }
796
            $renderer->doc .= "$gscript\n$olscript\n$scriptEnable";
797
            $renderer->doc .= '<div class="olMapHelp">' . $this->locale_xhtml("help") . '</div>';
798
            if($this->getConf('enableA11y')) {
799
                $renderer->doc .= '<div id="' . $mapid . '-static" class="olStaticMap">'
800
                    . p_render($format, p_get_instructions($staticImgUrl), $info) . '</div>';
0 ignored issues
show
Bug introduced by
The function p_get_instructions was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

800
                    . p_render($format, /** @scrutinizer ignore-call */ p_get_instructions($staticImgUrl), $info) . '</div>';
Loading history...
Comprehensibility Best Practice introduced by
The variable $info seems to be never defined.
Loading history...
Bug introduced by
The function p_render was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

800
                    . /** @scrutinizer ignore-call */ p_render($format, p_get_instructions($staticImgUrl), $info) . '</div>';
Loading history...
801
            }
802
            $renderer->doc .= '<div id="' . $mapid . '-clearer" class="clearer"><p>&nbsp;</p></div>';
803
            if($this->getConf('enableA11y')) {
804
                // render a table of the POI for the print and a11y presentation, it is hidden using javascript
805
                $renderer->doc .= '<div class="olPOItableSpan" id="' . $mapid . '-table-span">
806
                    <table class="olPOItable" id="' . $mapid . '-table">
807
                    <caption class="olPOITblCaption">' . $this->getLang('olmapPOItitle') . '</caption>
808
                    <thead class="olPOITblHeader">
809
                    <tr>
810
                    <th class="rowId" scope="col">id</th>
811
                    <th class="icon" scope="col">' . $this->getLang('olmapPOIicon') . '</th>
812
                    <th class="lat" scope="col" title="' . $this->getLang('olmapPOIlatTitle') . '">'
813
                    . $this->getLang('olmapPOIlat') . '</th>
814
                    <th class="lon" scope="col" title="' . $this->getLang('olmapPOIlonTitle') . '">'
815
                    . $this->getLang('olmapPOIlon') . '</th>
816
                    <th class="txt" scope="col">' . $this->getLang('olmapPOItxt') . '</th>
817
                    </tr>
818
                    </thead>';
819
                if($poitabledesc != '') {
820
                    $renderer->doc .= '<tfoot class="olPOITblFooter"><tr><td colspan="5">' . $poitabledesc
821
                        . '</td></tr></tfoot>';
822
                }
823
                $renderer->doc .= '<tbody class="olPOITblBody">' . $poitable . '</tbody>
824
                    </table></div>';
825
            }
826
            // render inline mapscript parts
827
            $renderer->doc .= '<script defer="defer" src="data:text/javascript;base64,';
828
            $renderer->doc .= base64_encode("olMapData[$mapnumber] = $param");
829
            $renderer->doc .= '"></script>';
830
            $mapnumber++;
831
            return true;
832
        } elseif($format == 'metadata') {
833
            if(!(($this->dflt ['lat'] == $mainLat) && ($this->dflt ['lon'] == $mainLon))) {
834
                // render geo metadata, unless they are the default
835
                $renderer->meta ['geo'] ['lat'] = $mainLat;
836
                $renderer->meta ['geo'] ['lon'] = $mainLon;
837
                if($geophp = plugin_load('helper', 'geophp')) {
0 ignored issues
show
Unused Code introduced by
The assignment to $geophp is dead and can be removed.
Loading history...
Bug introduced by
The function plugin_load was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

837
                if($geophp = /** @scrutinizer ignore-call */ plugin_load('helper', 'geophp')) {
Loading history...
838
                    // if we have the geoPHP helper, add the geohash
839
840
                    // fails with older php versions..
841
                    // $renderer->meta['geo']['geohash'] = (new Point($mainLon,$mainLat))->out('geohash');
842
                    $p                                  = new Point ($mainLon, $mainLat);
843
                    $renderer->meta ['geo'] ['geohash'] = $p->out('geohash');
844
                }
845
            }
846
847
            if(($this->getConf('enableA11y')) && (!empty ($_firstimage))) {
848
                // add map local image into relation/firstimage if not already filled and when it is a local image
849
850
                global $ID;
851
                $rel = p_get_metadata($ID, 'relation', METADATA_RENDER_USING_CACHE);
0 ignored issues
show
Bug introduced by
The function p_get_metadata was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

851
                $rel = /** @scrutinizer ignore-call */ p_get_metadata($ID, 'relation', METADATA_RENDER_USING_CACHE);
Loading history...
Bug introduced by
The constant METADATA_RENDER_USING_CACHE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
852
                $img = $rel ['firstimage'];
853
                if(empty ($img) /* || $img == $_firstimage*/) {
854
                    //dbglog ( $_firstimage,
855
                    // 'olmap::render#rendering image relation metadata for _firstimage as $img was empty or same.' );
856
                    // This seems to never work; the firstimage entry in the .meta file is empty
857
                    // $renderer->meta['relation']['firstimage'] = $_firstimage;
858
859
                    // ... and neither does this; the firstimage entry in the .meta file is empty
860
                    // $relation = array('relation'=>array('firstimage'=>$_firstimage));
861
                    // p_set_metadata($ID, $relation, false, false);
862
863
                    // ... this works
864
                    $renderer->internalmedia($_firstimage, $poitabledesc);
865
                }
866
            }
867
            return true;
868
        }
869
        return false;
870
    }
871
}
872