Completed
Push — master ( e2534c...bdfa10 )
by Mark
14s
created
action.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -262,11 +262,11 @@
 block discarded – undo
262 262
      */
263 263
     private function printHTML(array $searchresults, bool $showMedia = true): void
264 264
     {
265
-        $pages = (array)($searchresults ['pages']);
266
-        $media = (array)$searchresults ['media'];
267
-        $lat = (float)$searchresults ['lat'];
268
-        $lon = (float)$searchresults ['lon'];
269
-        $geohash = (string)$searchresults ['geohash'];
265
+        $pages = ( array ) ($searchresults ['pages']);
266
+        $media = ( array ) $searchresults ['media'];
267
+        $lat = ( float ) $searchresults ['lat'];
268
+        $lon = ( float ) $searchresults ['lon'];
269
+        $geohash = ( string ) $searchresults ['geohash'];
270 270
 
271 271
         if (isset ($searchresults ['error'])) {
272 272
             print '<div class="level1"><p>' . hsc($searchresults ['error']) . '</p></div>';
Please login to merge, or discard this patch.
Indentation   +422 added lines, -422 removed lines patch added patch discarded remove patch
@@ -26,426 +26,426 @@
 block discarded – undo
26 26
 class action_plugin_spatialhelper extends DokuWiki_Action_Plugin
27 27
 {
28 28
 
29
-    /**
30
-     * Register for events.
31
-     *
32
-     * @param Doku_Event_Handler $controller
33
-     *          DokuWiki's event controller object. Also available as global $EVENT_HANDLER
34
-     */
35
-    public function register(Doku_Event_Handler $controller): void
36
-    {
37
-        // listen for page add / delete events
38
-        // http://www.dokuwiki.org/devel:event:indexer_page_add
39
-        $controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'handleIndexerPageAdd');
40
-        $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'removeFromIndex');
41
-
42
-        // http://www.dokuwiki.org/devel:event:sitemap_generate
43
-        $controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSitemapGenerateBefore');
44
-        // using after will only trigger us if a sitemap was actually created
45
-        $controller->register_hook('SITEMAP_GENERATE', 'AFTER', $this, 'handleSitemapGenerateAfter');
46
-
47
-        // handle actions we know of
48
-        $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleActionActPreprocess', array());
49
-        // handle HTML eg. /dokuwiki/doku.php?id=start&do=findnearby&geohash=u15vk4
50
-        $controller->register_hook(
51
-            'TPL_ACT_UNKNOWN', 'BEFORE', $this, 'findnearby', array(
52
-                'format' => 'HTML'
53
-            )
54
-        );
55
-        // handles AJAX/json eg: jQuery.post("/dokuwiki/lib/exe/ajax.php?id=start&call=findnearby&geohash=u15vk4");
56
-        $controller->register_hook(
57
-            'AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'findnearby', array(
58
-                'format' => 'JSON'
59
-            )
60
-        );
61
-
62
-        // listen for media uploads and deletes
63
-        $controller->register_hook('MEDIA_UPLOAD_FINISH', 'BEFORE', $this, 'handleMediaUploaded', array());
64
-        $controller->register_hook('MEDIA_DELETE_FILE', 'BEFORE', $this, 'handleMediaDeleted', array());
65
-
66
-        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleMetaheaderOutput');
67
-        $controller->register_hook('PLUGIN_POPULARITY_DATA_SETUP', 'AFTER', $this, 'popularity');
68
-    }
69
-
70
-    /**
71
-     * Update the spatial index for the page.
72
-     *
73
-     * @param Doku_Event $event
74
-     *          event object
75
-     * @param mixed $param
76
-     *          the parameters passed to register_hook when this handler was registered
77
-     */
78
-    public function handleIndexerPageAdd(Doku_Event $event, $param): void
79
-    {
80
-        // $event→data['page'] – the page id
81
-        // $event→data['body'] – empty, can be filled by additional content to index by your plugin
82
-        // $event→data['metadata'] – the metadata that shall be indexed. This is an array where the keys are the
83
-        //    metadata indexes and the value a string or an array of strings with the values.
84
-        //    title and relation_references will already be set.
85
-        $id = $event->data ['page'];
86
-        $indexer = plugin_load('helper', 'spatialhelper_index');
87
-        $entries = $indexer->updateSpatialIndex($id);
88
-    }
89
-
90
-    /**
91
-     * Update the spatial index, removing the page.
92
-     *
93
-     * @param Doku_Event $event
94
-     *          event object
95
-     * @param mixed $param
96
-     *          the parameters passed to register_hook when this handler was registered
97
-     */
98
-    public function removeFromIndex(Doku_Event $event, $param): void
99
-    {
100
-        // event data:
101
-        // $data[0] – The raw arguments for io_saveFile as an array. Do not change file path.
102
-        // $data[0][0] – the file path.
103
-        // $data[0][1] – the content to be saved, and may be modified.
104
-        // $data[1] – ns: The colon separated namespace path minus the trailing page name. (false if root ns)
105
-        // $data[2] – page_name: The wiki page name.
106
-        // $data[3] – rev: The page revision, false for current wiki pages.
107
-
108
-        dbglog($event->data, "Event data in removeFromIndex.");
109
-        if (@file_exists($event->data [0] [0])) {
110
-            // file not new
111
-            if (!$event->data [0] [1]) {
112
-                // file is empty, page is being deleted
113
-                if (empty ($event->data [1])) {
114
-                    // root namespace
115
-                    $id = $event->data [2];
116
-                } else {
117
-                    $id = $event->data [1] . ":" . $event->data [2];
118
-                }
119
-                $indexer = plugin_load('helper', 'spatialhelper_index');
120
-                if ($indexer) {
121
-                    $indexer->deleteFromIndex($id);
122
-                }
123
-            }
124
-        }
125
-    }
126
-
127
-    /**
128
-     * Add a new SitemapItem object that points to the KML of public geocoded pages.
129
-     *
130
-     * @param Doku_Event $event
131
-     * @param mixed $param
132
-     */
133
-    public function handleSitemapGenerateBefore(Doku_Event $event, $param): void
134
-    {
135
-        $path = mediaFN($this->getConf('media_kml'));
136
-        $lastmod = @filemtime($path);
137
-        $event->data ['items'] [] = new Item(ml($this->getConf('media_kml'), '', true, '&amp;', true), $lastmod);
138
-    }
139
-
140
-    /**
141
-     * Create a spatial sitemap or attach the geo/kml map to the sitemap.
142
-     *
143
-     * @param Doku_Event $event
144
-     *          event object, not used
145
-     * @param mixed $param
146
-     *          parameter array, not used
147
-     */
148
-    public function handleSitemapGenerateAfter(Doku_Event $event, $param): bool
149
-    {
150
-        // $event→data['items']: Array of SitemapItem instances, the array of sitemap items that already
151
-        //      contains all public pages of the wiki
152
-        // $event→data['sitemap']: The path of the file the sitemap will be saved to.
153
-        if ($helper = plugin_load('helper', 'spatialhelper_sitemap')) {
154
-            // dbglog($helper, "createSpatialSitemap loaded helper.");
155
-
156
-            $kml = $helper->createKMLSitemap($this->getConf('media_kml'));
157
-            $rss = $helper->createGeoRSSSitemap($this->getConf('media_georss'));
158
-
159
-            if (!empty ($this->getConf('sitemap_namespaces'))) {
160
-                $namespaces = array_map('trim', explode("\n", $this->getConf('sitemap_namespaces')));
161
-                foreach ($namespaces as $namespace) {
162
-                    $kmlN = $helper->createKMLSitemap($namespace . $this->getConf('media_kml'));
163
-                    $rssN = $helper->createGeoRSSSitemap($namespace . $this->getConf('media_georss'));
164
-                    dbglog(
165
-                        $kmlN && $rssN,
166
-                        "handleSitemapGenerateAfter, created KML / GeoRSS sitemap in $namespace, succes: "
167
-                    );
168
-                }
169
-            }
170
-            return $kml && $rss;
171
-        }
172
-    }
173
-
174
-    /**
175
-     * trap findnearby action.
176
-     * This addional handler is required as described at: https://www.dokuwiki.org/devel:event:tpl_act_unknown
177
-     *
178
-     * @param Doku_Event $event
179
-     *          event object
180
-     * @param mixed $param
181
-     *          not used
182
-     */
183
-    public function handleActionActPreprocess(Doku_Event $event, $param): void
184
-    {
185
-        if ($event->data !== 'findnearby') {
186
-            return;
187
-        }
188
-        $event->preventDefault();
189
-    }
190
-
191
-    /**
192
-     * handle findnearby action.
193
-     *
194
-     * @param Doku_Event $event
195
-     *          event object
196
-     * @param mixed $param
197
-     *          associative array with keys
198
-     *          'format'=> HTML | JSON
199
-     */
200
-    public function findnearby(Doku_Event $event, $param): void
201
-    {
202
-        if ($event->data !== 'findnearby') {
203
-            return;
204
-        }
205
-        $event->preventDefault();
206
-        $results = array();
207
-        global $INPUT;
208
-        if ($helper = plugin_load('helper', 'spatialhelper_search')) {
209
-            if ($INPUT->has('lat') && $INPUT->has('lon')) {
210
-                $results = $helper->findNearbyLatLon($INPUT->param('lat'), $INPUT->param('lon'));
211
-            } elseif ($INPUT->has('geohash')) {
212
-                $results = $helper->findNearby($INPUT->str('geohash'));
213
-            } else {
214
-                $results = array(
215
-                    'error' => hsc($this->getLang('invalidinput'))
216
-                );
217
-            }
218
-        }
219
-
220
-        $showMedia = $INPUT->bool('showMedia', true);
221
-
222
-        switch ($param['format']) {
223
-            case 'JSON' :
224
-                $this->printJSON($results);
225
-                break;
226
-            case 'HTML' :
227
-                // fall through to default
228
-            default :
229
-                $this->printHTML($results, $showMedia);
230
-                break;
231
-        }
232
-    }
233
-
234
-    /**
235
-     * Print seachresults as HTML lists.
236
-     *
237
-     * @param array $searchresults
238
-     */
239
-    private function printJSON(array $searchresults): void
240
-    {
241
-        require_once DOKU_INC . 'inc/JSON.php';
242
-        $json = new JSON();
243
-        header('Content-Type: application/json');
244
-        print $json->encode($searchresults);
245
-    }
246
-
247
-    /**
248
-     * Print seachresults as HTML lists.
249
-     *
250
-     * @param array $searchresults
251
-     * @param bool $showMedia
252
-     */
253
-    private function printHTML(array $searchresults, bool $showMedia = true): void
254
-    {
255
-        $pages = (array)($searchresults ['pages']);
256
-        $media = (array)$searchresults ['media'];
257
-        $lat = (float)$searchresults ['lat'];
258
-        $lon = (float)$searchresults ['lon'];
259
-        $geohash = (string)$searchresults ['geohash'];
260
-
261
-        if (isset ($searchresults ['error'])) {
262
-            print '<div class="level1"><p>' . hsc($searchresults ['error']) . '</p></div>';
263
-            return;
264
-        }
265
-
266
-        // print a HTML list
267
-        print '<h1>' . $this->getLang('results_header') . '</h1>' . DOKU_LF;
268
-        print '<div class="level1">' . DOKU_LF;
269
-        if (!empty ($pages)) {
270
-            $pagelist = '<ol>' . DOKU_LF;
271
-            foreach ($pages as $page) {
272
-                $pagelist .= '<li>' . html_wikilink(
273
-                        ':' . $page ['id'], useHeading('navigation') ? null :
274
-                        noNS($page ['id'])
275
-                    ) . ' (' . $this->getLang('results_distance_prefix')
276
-                    . $page ['distance'] . '&nbsp;m) ' . $page ['description'] . '</li>' . DOKU_LF;
277
-            }
278
-            $pagelist .= '</ol>' . DOKU_LF;
279
-
280
-            print '<h2>' . $this->getLang('results_pages') . hsc(
281
-                    ' lat;lon: ' . $lat . ';' . $lon
282
-                    . ' (geohash: ' . $geohash . ')'
283
-                ) . '</h2>';
284
-            print '<div class="level2">' . DOKU_LF;
285
-            print $pagelist;
286
-            print '</div>' . DOKU_LF;
287
-        } else {
288
-            print '<p>' . hsc($this->getLang('nothingfound')) . '</p>';
289
-        }
290
-
291
-        if (!empty ($media) && $showMedia) {
292
-            $pagelist = '<ol>' . DOKU_LF;
293
-            foreach ($media as $m) {
294
-                $opts = array();
295
-                $link = ml($m ['id'], $opts, false, '&amp;', false);
296
-                $opts ['w'] = '100';
297
-                $src = ml($m ['id'], $opts);
298
-                $pagelist .= '<li><a href="' . $link . '"><img src="' . $src . '"></a> ('
299
-                    . $this->getLang('results_distance_prefix') . $page ['distance'] . '&nbsp;m) ' . hsc($desc)
300
-                    . '</li>' . DOKU_LF;
301
-            }
302
-            $pagelist .= '</ol>' . DOKU_LF;
303
-
304
-            print '<h2>' . $this->getLang('results_media') . hsc(
305
-                    ' lat;lon: ' . $lat . ';' . $lon
306
-                    . ' (geohash: ' . $geohash . ')'
307
-                ) . '</h2>' . DOKU_LF;
308
-            print '<div class="level2">' . DOKU_LF;
309
-            print $pagelist;
310
-            print '</div>' . DOKU_LF;
311
-        }
312
-        print '<p>' . $this->getLang('results_precision') . $searchresults ['precision'] . ' m. ';
313
-        if (strlen($geohash) > 1) {
314
-            $url = wl(
315
-                getID(), array(
316
-                    'do' => 'findnearby',
317
-                    'geohash' => substr($geohash, 0, -1)
318
-                )
319
-            );
320
-            print '<a href="' . $url . '" class="findnearby">' . $this->getLang('search_largerarea') . '</a>.</p>'
321
-                . DOKU_LF;
322
-        }
323
-        print '</div>' . DOKU_LF;
324
-    }
325
-
326
-    /**
327
-     * add media to spatial index.
328
-     *
329
-     * @param Doku_Event $event
330
-     * @param mixed $param
331
-     */
332
-    public function handleMediaUploaded(Doku_Event $event, $param): void
333
-    {
334
-        // data[0] temporary file name (read from $_FILES)
335
-        // data[1] file name of the file being uploaded
336
-        // data[2] future directory id of the file being uploaded
337
-        // data[3] the mime type of the file being uploaded
338
-        // data[4] true if the uploaded file exists already
339
-        // data[5] (since 2011-02-06) the PHP function used to move the file to the correct location
340
-
341
-        dbglog($event->data, "handleMediaUploaded::event data");
342
-
343
-        // check the list of mimetypes
344
-        // if it's a supported type call appropriate index function
345
-        if (substr_compare($event->data [3], 'image/jpeg', 0)) {
346
-            $indexer = plugin_load('helper', 'spatialhelper_index');
347
-            if ($indexer) {
348
-                $indexer->indexImage($event->data [2]);
349
-            }
350
-        }
351
-        // TODO add image/tiff
352
-        // TODO kml, gpx, geojson...
353
-    }
354
-
355
-    /**
356
-     * removes the media from the index.
357
-     */
358
-    public function handleMediaDeleted(Doku_Event $event, $param): void
359
-    {
360
-        // data['id'] ID data['unl'] unlink return code
361
-        // data['del'] Namespace directory unlink return code
362
-        // data['name'] file name data['path'] full path to the file
363
-        // data['size'] file size
364
-
365
-        // remove the media id from the index
366
-        $indexer = plugin_load('helper', 'spatialhelper_index');
367
-        if ($indexer) {
368
-            $indexer->deleteFromIndex('media__' . $event->data ['id']);
369
-        }
370
-    }
371
-
372
-    /**
373
-     * add a link to the spatial sitemap files in the header.
374
-     *
375
-     * @param Doku_Event $event
376
-     *          the DokuWiki event. $event->data is a two-dimensional
377
-     *          array of all meta headers. The keys are meta, link and script.
378
-     * @param mixed $param
379
-     *
380
-     * @see http://www.dokuwiki.org/devel:event:tpl_metaheader_output
381
-     */
382
-    public function handleMetaheaderOutput(Doku_Event $event, $param): void
383
-    {
384
-        // TODO maybe test for exist
385
-        $event->data ["link"] [] = array(
386
-            "type" => "application/atom+xml",
387
-            "rel" => "alternate",
388
-            "href" => ml($this->getConf('media_georss')),
389
-            "title" => "Spatial ATOM Feed"
390
-        );
391
-        $event->data ["link"] [] = array(
392
-            "type" => "application/vnd.google-earth.kml+xml",
393
-            "rel" => "alternate",
394
-            "href" => ml($this->getConf('media_kml')),
395
-            "title" => "KML Sitemap"
396
-        );
397
-    }
398
-
399
-    /**
400
-     * Add spatialhelper popularity data.
401
-     *
402
-     * @param Doku_Event $event
403
-     *          the DokuWiki event
404
-     */
405
-    final public function popularity(Doku_Event $event): void
406
-    {
407
-        $versionInfo = getVersionData();
408
-        $plugin_info = $this->getInfo();
409
-        $event->data['spatialhelper']['version'] = $plugin_info['date'];
410
-        $event->data['spatialhelper']['dwversion'] = $versionInfo['date'];
411
-        $event->data['spatialhelper']['combinedversion'] = $versionInfo['date'] . '_' . $plugin_info['date'];
412
-    }
413
-
414
-    /**
415
-     * Calculate a new coordinate based on start, distance and bearing
416
-     *
417
-     * @param $start array
418
-     *               - start coordinate as decimal lat/lon pair
419
-     * @param $dist  float
420
-     *               - distance in kilometers
421
-     * @param $brng  float
422
-     *               - bearing in degrees (compass direction)
423
-     */
424
-    private function geoDestination(array $start, float $dist, float $brng): array
425
-    {
426
-        $lat1 = $this->toRad($start [0]);
427
-        $lon1 = $this->toRad($start [1]);
428
-        // http://en.wikipedia.org/wiki/Earth_radius
429
-        // average earth radius in km
430
-        $dist = $dist / 6371.01;
431
-        $brng = $this->toRad($brng);
432
-
433
-        $lon2 = $lon1 + atan2(sin($brng) * sin($dist) * cos($lat1), cos($dist) - sin($lat1) * sin($lat2));
434
-        $lon2 = fmod(($lon2 + 3 * M_PI), (2 * M_PI)) - M_PI;
435
-
436
-        return array(
437
-            $this->toDeg($lat2),
438
-            $this->toDeg($lon2)
439
-        );
440
-    }
441
-
442
-    private function toRad(float $deg): float
443
-    {
444
-        return $deg * M_PI / 180;
445
-    }
446
-
447
-    private function toDeg(float $rad): float
448
-    {
449
-        return $rad * 180 / M_PI;
450
-    }
29
+	/**
30
+	 * Register for events.
31
+	 *
32
+	 * @param Doku_Event_Handler $controller
33
+	 *          DokuWiki's event controller object. Also available as global $EVENT_HANDLER
34
+	 */
35
+	public function register(Doku_Event_Handler $controller): void
36
+	{
37
+		// listen for page add / delete events
38
+		// http://www.dokuwiki.org/devel:event:indexer_page_add
39
+		$controller->register_hook('INDEXER_PAGE_ADD', 'BEFORE', $this, 'handleIndexerPageAdd');
40
+		$controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'removeFromIndex');
41
+
42
+		// http://www.dokuwiki.org/devel:event:sitemap_generate
43
+		$controller->register_hook('SITEMAP_GENERATE', 'BEFORE', $this, 'handleSitemapGenerateBefore');
44
+		// using after will only trigger us if a sitemap was actually created
45
+		$controller->register_hook('SITEMAP_GENERATE', 'AFTER', $this, 'handleSitemapGenerateAfter');
46
+
47
+		// handle actions we know of
48
+		$controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handleActionActPreprocess', array());
49
+		// handle HTML eg. /dokuwiki/doku.php?id=start&do=findnearby&geohash=u15vk4
50
+		$controller->register_hook(
51
+			'TPL_ACT_UNKNOWN', 'BEFORE', $this, 'findnearby', array(
52
+				'format' => 'HTML'
53
+			)
54
+		);
55
+		// handles AJAX/json eg: jQuery.post("/dokuwiki/lib/exe/ajax.php?id=start&call=findnearby&geohash=u15vk4");
56
+		$controller->register_hook(
57
+			'AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'findnearby', array(
58
+				'format' => 'JSON'
59
+			)
60
+		);
61
+
62
+		// listen for media uploads and deletes
63
+		$controller->register_hook('MEDIA_UPLOAD_FINISH', 'BEFORE', $this, 'handleMediaUploaded', array());
64
+		$controller->register_hook('MEDIA_DELETE_FILE', 'BEFORE', $this, 'handleMediaDeleted', array());
65
+
66
+		$controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'handleMetaheaderOutput');
67
+		$controller->register_hook('PLUGIN_POPULARITY_DATA_SETUP', 'AFTER', $this, 'popularity');
68
+	}
69
+
70
+	/**
71
+	 * Update the spatial index for the page.
72
+	 *
73
+	 * @param Doku_Event $event
74
+	 *          event object
75
+	 * @param mixed $param
76
+	 *          the parameters passed to register_hook when this handler was registered
77
+	 */
78
+	public function handleIndexerPageAdd(Doku_Event $event, $param): void
79
+	{
80
+		// $event→data['page'] – the page id
81
+		// $event→data['body'] – empty, can be filled by additional content to index by your plugin
82
+		// $event→data['metadata'] – the metadata that shall be indexed. This is an array where the keys are the
83
+		//    metadata indexes and the value a string or an array of strings with the values.
84
+		//    title and relation_references will already be set.
85
+		$id = $event->data ['page'];
86
+		$indexer = plugin_load('helper', 'spatialhelper_index');
87
+		$entries = $indexer->updateSpatialIndex($id);
88
+	}
89
+
90
+	/**
91
+	 * Update the spatial index, removing the page.
92
+	 *
93
+	 * @param Doku_Event $event
94
+	 *          event object
95
+	 * @param mixed $param
96
+	 *          the parameters passed to register_hook when this handler was registered
97
+	 */
98
+	public function removeFromIndex(Doku_Event $event, $param): void
99
+	{
100
+		// event data:
101
+		// $data[0] – The raw arguments for io_saveFile as an array. Do not change file path.
102
+		// $data[0][0] – the file path.
103
+		// $data[0][1] – the content to be saved, and may be modified.
104
+		// $data[1] – ns: The colon separated namespace path minus the trailing page name. (false if root ns)
105
+		// $data[2] – page_name: The wiki page name.
106
+		// $data[3] – rev: The page revision, false for current wiki pages.
107
+
108
+		dbglog($event->data, "Event data in removeFromIndex.");
109
+		if (@file_exists($event->data [0] [0])) {
110
+			// file not new
111
+			if (!$event->data [0] [1]) {
112
+				// file is empty, page is being deleted
113
+				if (empty ($event->data [1])) {
114
+					// root namespace
115
+					$id = $event->data [2];
116
+				} else {
117
+					$id = $event->data [1] . ":" . $event->data [2];
118
+				}
119
+				$indexer = plugin_load('helper', 'spatialhelper_index');
120
+				if ($indexer) {
121
+					$indexer->deleteFromIndex($id);
122
+				}
123
+			}
124
+		}
125
+	}
126
+
127
+	/**
128
+	 * Add a new SitemapItem object that points to the KML of public geocoded pages.
129
+	 *
130
+	 * @param Doku_Event $event
131
+	 * @param mixed $param
132
+	 */
133
+	public function handleSitemapGenerateBefore(Doku_Event $event, $param): void
134
+	{
135
+		$path = mediaFN($this->getConf('media_kml'));
136
+		$lastmod = @filemtime($path);
137
+		$event->data ['items'] [] = new Item(ml($this->getConf('media_kml'), '', true, '&amp;', true), $lastmod);
138
+	}
139
+
140
+	/**
141
+	 * Create a spatial sitemap or attach the geo/kml map to the sitemap.
142
+	 *
143
+	 * @param Doku_Event $event
144
+	 *          event object, not used
145
+	 * @param mixed $param
146
+	 *          parameter array, not used
147
+	 */
148
+	public function handleSitemapGenerateAfter(Doku_Event $event, $param): bool
149
+	{
150
+		// $event→data['items']: Array of SitemapItem instances, the array of sitemap items that already
151
+		//      contains all public pages of the wiki
152
+		// $event→data['sitemap']: The path of the file the sitemap will be saved to.
153
+		if ($helper = plugin_load('helper', 'spatialhelper_sitemap')) {
154
+			// dbglog($helper, "createSpatialSitemap loaded helper.");
155
+
156
+			$kml = $helper->createKMLSitemap($this->getConf('media_kml'));
157
+			$rss = $helper->createGeoRSSSitemap($this->getConf('media_georss'));
158
+
159
+			if (!empty ($this->getConf('sitemap_namespaces'))) {
160
+				$namespaces = array_map('trim', explode("\n", $this->getConf('sitemap_namespaces')));
161
+				foreach ($namespaces as $namespace) {
162
+					$kmlN = $helper->createKMLSitemap($namespace . $this->getConf('media_kml'));
163
+					$rssN = $helper->createGeoRSSSitemap($namespace . $this->getConf('media_georss'));
164
+					dbglog(
165
+						$kmlN && $rssN,
166
+						"handleSitemapGenerateAfter, created KML / GeoRSS sitemap in $namespace, succes: "
167
+					);
168
+				}
169
+			}
170
+			return $kml && $rss;
171
+		}
172
+	}
173
+
174
+	/**
175
+	 * trap findnearby action.
176
+	 * This addional handler is required as described at: https://www.dokuwiki.org/devel:event:tpl_act_unknown
177
+	 *
178
+	 * @param Doku_Event $event
179
+	 *          event object
180
+	 * @param mixed $param
181
+	 *          not used
182
+	 */
183
+	public function handleActionActPreprocess(Doku_Event $event, $param): void
184
+	{
185
+		if ($event->data !== 'findnearby') {
186
+			return;
187
+		}
188
+		$event->preventDefault();
189
+	}
190
+
191
+	/**
192
+	 * handle findnearby action.
193
+	 *
194
+	 * @param Doku_Event $event
195
+	 *          event object
196
+	 * @param mixed $param
197
+	 *          associative array with keys
198
+	 *          'format'=> HTML | JSON
199
+	 */
200
+	public function findnearby(Doku_Event $event, $param): void
201
+	{
202
+		if ($event->data !== 'findnearby') {
203
+			return;
204
+		}
205
+		$event->preventDefault();
206
+		$results = array();
207
+		global $INPUT;
208
+		if ($helper = plugin_load('helper', 'spatialhelper_search')) {
209
+			if ($INPUT->has('lat') && $INPUT->has('lon')) {
210
+				$results = $helper->findNearbyLatLon($INPUT->param('lat'), $INPUT->param('lon'));
211
+			} elseif ($INPUT->has('geohash')) {
212
+				$results = $helper->findNearby($INPUT->str('geohash'));
213
+			} else {
214
+				$results = array(
215
+					'error' => hsc($this->getLang('invalidinput'))
216
+				);
217
+			}
218
+		}
219
+
220
+		$showMedia = $INPUT->bool('showMedia', true);
221
+
222
+		switch ($param['format']) {
223
+			case 'JSON' :
224
+				$this->printJSON($results);
225
+				break;
226
+			case 'HTML' :
227
+				// fall through to default
228
+			default :
229
+				$this->printHTML($results, $showMedia);
230
+				break;
231
+		}
232
+	}
233
+
234
+	/**
235
+	 * Print seachresults as HTML lists.
236
+	 *
237
+	 * @param array $searchresults
238
+	 */
239
+	private function printJSON(array $searchresults): void
240
+	{
241
+		require_once DOKU_INC . 'inc/JSON.php';
242
+		$json = new JSON();
243
+		header('Content-Type: application/json');
244
+		print $json->encode($searchresults);
245
+	}
246
+
247
+	/**
248
+	 * Print seachresults as HTML lists.
249
+	 *
250
+	 * @param array $searchresults
251
+	 * @param bool $showMedia
252
+	 */
253
+	private function printHTML(array $searchresults, bool $showMedia = true): void
254
+	{
255
+		$pages = (array)($searchresults ['pages']);
256
+		$media = (array)$searchresults ['media'];
257
+		$lat = (float)$searchresults ['lat'];
258
+		$lon = (float)$searchresults ['lon'];
259
+		$geohash = (string)$searchresults ['geohash'];
260
+
261
+		if (isset ($searchresults ['error'])) {
262
+			print '<div class="level1"><p>' . hsc($searchresults ['error']) . '</p></div>';
263
+			return;
264
+		}
265
+
266
+		// print a HTML list
267
+		print '<h1>' . $this->getLang('results_header') . '</h1>' . DOKU_LF;
268
+		print '<div class="level1">' . DOKU_LF;
269
+		if (!empty ($pages)) {
270
+			$pagelist = '<ol>' . DOKU_LF;
271
+			foreach ($pages as $page) {
272
+				$pagelist .= '<li>' . html_wikilink(
273
+						':' . $page ['id'], useHeading('navigation') ? null :
274
+						noNS($page ['id'])
275
+					) . ' (' . $this->getLang('results_distance_prefix')
276
+					. $page ['distance'] . '&nbsp;m) ' . $page ['description'] . '</li>' . DOKU_LF;
277
+			}
278
+			$pagelist .= '</ol>' . DOKU_LF;
279
+
280
+			print '<h2>' . $this->getLang('results_pages') . hsc(
281
+					' lat;lon: ' . $lat . ';' . $lon
282
+					. ' (geohash: ' . $geohash . ')'
283
+				) . '</h2>';
284
+			print '<div class="level2">' . DOKU_LF;
285
+			print $pagelist;
286
+			print '</div>' . DOKU_LF;
287
+		} else {
288
+			print '<p>' . hsc($this->getLang('nothingfound')) . '</p>';
289
+		}
290
+
291
+		if (!empty ($media) && $showMedia) {
292
+			$pagelist = '<ol>' . DOKU_LF;
293
+			foreach ($media as $m) {
294
+				$opts = array();
295
+				$link = ml($m ['id'], $opts, false, '&amp;', false);
296
+				$opts ['w'] = '100';
297
+				$src = ml($m ['id'], $opts);
298
+				$pagelist .= '<li><a href="' . $link . '"><img src="' . $src . '"></a> ('
299
+					. $this->getLang('results_distance_prefix') . $page ['distance'] . '&nbsp;m) ' . hsc($desc)
300
+					. '</li>' . DOKU_LF;
301
+			}
302
+			$pagelist .= '</ol>' . DOKU_LF;
303
+
304
+			print '<h2>' . $this->getLang('results_media') . hsc(
305
+					' lat;lon: ' . $lat . ';' . $lon
306
+					. ' (geohash: ' . $geohash . ')'
307
+				) . '</h2>' . DOKU_LF;
308
+			print '<div class="level2">' . DOKU_LF;
309
+			print $pagelist;
310
+			print '</div>' . DOKU_LF;
311
+		}
312
+		print '<p>' . $this->getLang('results_precision') . $searchresults ['precision'] . ' m. ';
313
+		if (strlen($geohash) > 1) {
314
+			$url = wl(
315
+				getID(), array(
316
+					'do' => 'findnearby',
317
+					'geohash' => substr($geohash, 0, -1)
318
+				)
319
+			);
320
+			print '<a href="' . $url . '" class="findnearby">' . $this->getLang('search_largerarea') . '</a>.</p>'
321
+				. DOKU_LF;
322
+		}
323
+		print '</div>' . DOKU_LF;
324
+	}
325
+
326
+	/**
327
+	 * add media to spatial index.
328
+	 *
329
+	 * @param Doku_Event $event
330
+	 * @param mixed $param
331
+	 */
332
+	public function handleMediaUploaded(Doku_Event $event, $param): void
333
+	{
334
+		// data[0] temporary file name (read from $_FILES)
335
+		// data[1] file name of the file being uploaded
336
+		// data[2] future directory id of the file being uploaded
337
+		// data[3] the mime type of the file being uploaded
338
+		// data[4] true if the uploaded file exists already
339
+		// data[5] (since 2011-02-06) the PHP function used to move the file to the correct location
340
+
341
+		dbglog($event->data, "handleMediaUploaded::event data");
342
+
343
+		// check the list of mimetypes
344
+		// if it's a supported type call appropriate index function
345
+		if (substr_compare($event->data [3], 'image/jpeg', 0)) {
346
+			$indexer = plugin_load('helper', 'spatialhelper_index');
347
+			if ($indexer) {
348
+				$indexer->indexImage($event->data [2]);
349
+			}
350
+		}
351
+		// TODO add image/tiff
352
+		// TODO kml, gpx, geojson...
353
+	}
354
+
355
+	/**
356
+	 * removes the media from the index.
357
+	 */
358
+	public function handleMediaDeleted(Doku_Event $event, $param): void
359
+	{
360
+		// data['id'] ID data['unl'] unlink return code
361
+		// data['del'] Namespace directory unlink return code
362
+		// data['name'] file name data['path'] full path to the file
363
+		// data['size'] file size
364
+
365
+		// remove the media id from the index
366
+		$indexer = plugin_load('helper', 'spatialhelper_index');
367
+		if ($indexer) {
368
+			$indexer->deleteFromIndex('media__' . $event->data ['id']);
369
+		}
370
+	}
371
+
372
+	/**
373
+	 * add a link to the spatial sitemap files in the header.
374
+	 *
375
+	 * @param Doku_Event $event
376
+	 *          the DokuWiki event. $event->data is a two-dimensional
377
+	 *          array of all meta headers. The keys are meta, link and script.
378
+	 * @param mixed $param
379
+	 *
380
+	 * @see http://www.dokuwiki.org/devel:event:tpl_metaheader_output
381
+	 */
382
+	public function handleMetaheaderOutput(Doku_Event $event, $param): void
383
+	{
384
+		// TODO maybe test for exist
385
+		$event->data ["link"] [] = array(
386
+			"type" => "application/atom+xml",
387
+			"rel" => "alternate",
388
+			"href" => ml($this->getConf('media_georss')),
389
+			"title" => "Spatial ATOM Feed"
390
+		);
391
+		$event->data ["link"] [] = array(
392
+			"type" => "application/vnd.google-earth.kml+xml",
393
+			"rel" => "alternate",
394
+			"href" => ml($this->getConf('media_kml')),
395
+			"title" => "KML Sitemap"
396
+		);
397
+	}
398
+
399
+	/**
400
+	 * Add spatialhelper popularity data.
401
+	 *
402
+	 * @param Doku_Event $event
403
+	 *          the DokuWiki event
404
+	 */
405
+	final public function popularity(Doku_Event $event): void
406
+	{
407
+		$versionInfo = getVersionData();
408
+		$plugin_info = $this->getInfo();
409
+		$event->data['spatialhelper']['version'] = $plugin_info['date'];
410
+		$event->data['spatialhelper']['dwversion'] = $versionInfo['date'];
411
+		$event->data['spatialhelper']['combinedversion'] = $versionInfo['date'] . '_' . $plugin_info['date'];
412
+	}
413
+
414
+	/**
415
+	 * Calculate a new coordinate based on start, distance and bearing
416
+	 *
417
+	 * @param $start array
418
+	 *               - start coordinate as decimal lat/lon pair
419
+	 * @param $dist  float
420
+	 *               - distance in kilometers
421
+	 * @param $brng  float
422
+	 *               - bearing in degrees (compass direction)
423
+	 */
424
+	private function geoDestination(array $start, float $dist, float $brng): array
425
+	{
426
+		$lat1 = $this->toRad($start [0]);
427
+		$lon1 = $this->toRad($start [1]);
428
+		// http://en.wikipedia.org/wiki/Earth_radius
429
+		// average earth radius in km
430
+		$dist = $dist / 6371.01;
431
+		$brng = $this->toRad($brng);
432
+
433
+		$lon2 = $lon1 + atan2(sin($brng) * sin($dist) * cos($lat1), cos($dist) - sin($lat1) * sin($lat2));
434
+		$lon2 = fmod(($lon2 + 3 * M_PI), (2 * M_PI)) - M_PI;
435
+
436
+		return array(
437
+			$this->toDeg($lat2),
438
+			$this->toDeg($lon2)
439
+		);
440
+	}
441
+
442
+	private function toRad(float $deg): float
443
+	{
444
+		return $deg * M_PI / 180;
445
+	}
446
+
447
+	private function toDeg(float $rad): float
448
+	{
449
+		return $rad * 180 / M_PI;
450
+	}
451 451
 }
Please login to merge, or discard this patch.