1<?php
2
3use dokuwiki\Extension\SyntaxPlugin;
4
5/*
6 * Copyright (c) 2014-2023 Mark C. Prins <mprins@users.sf.net>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21/**
22 * DokuWiki Plugin dokuwikispatial (findnearby Syntax Component).
23 *
24 * @license BSD license
25 * @author  Mark C. Prins <mprins@users.sf.net>
26 */
27class syntax_plugin_spatialhelper_findnearby extends SyntaxPlugin
28{
29    /**
30     *
31     * @see DokuWiki_Syntax_Plugin::getType()
32     */
33    final public function getType(): string
34    {
35        return 'substition';
36    }
37
38    /**
39     * Return 'normal' so this syntax can be rendered inline.
40     *
41     * @see DokuWiki_Syntax_Plugin::getPType()
42     */
43    final public function getPType(): string
44    {
45        return 'normal';
46    }
47
48    /**
49     *
50     * @see Doku_Parser_Mode::getSort()
51     */
52    final public function getSort(): int
53    {
54        return 307;
55    }
56
57    /**
58     * define our special pattern: {{findnearby>Some linkt text or nothing}}.
59     *
60     * @see Doku_Parser_Mode::connectTo()
61     */
62    final public function connectTo($mode): void
63    {
64        $this->Lexer->addSpecialPattern('\{\{findnearby>.*?\}\}', $mode, 'plugin_spatialhelper_findnearby');
65    }
66
67    /**
68     * look up the page's geo metadata and pass that on to render.
69     *
70     * @param string $match The text matched by the patterns
71     * @param int $state The lexer state for the match
72     * @param int $pos The character position of the matched text
73     * @param Doku_Handler $handler The Doku_Handler object
74     * @return  bool|array Return an array with all data you want to use in render, false don't add an instruction
75     *
76     * @see DokuWiki_Syntax_Plugin::handle()
77     */
78    final public function handle($match, $state, $pos, Doku_Handler $handler): bool|array
79    {
80        $data = [];
81        $data [0] = trim(substr($match, strlen('{{findnearby>'), -2));
82        if ($data [0] === '') {
83            $data [0] = $this->getLang('search_findnearby');
84        }
85        $meta = p_get_metadata(getID(), 'geo');
86        if ($meta) {
87            if ($meta ['lat'] && $meta ['lon']) {
88                $data [1] = ['do' => 'findnearby', 'lat' => $meta ['lat'], 'lon' => $meta ['lon']];
89            } elseif ($meta ['geohash']) {
90                $data [1] = ['do' => 'findnearby', 'geohash' => $meta ['geohash']];
91            }
92            return $data;
93        }
94        return false;
95    }
96
97    /**
98     * Render a link to a search page.
99     *
100     * @see DokuWiki_Syntax_Plugin::render()
101     */
102    final public function render($format, Doku_Renderer $renderer, $data): bool
103    {
104        if ($data === false) {
105            return false;
106        }
107
108        if ($format === 'xhtml') {
109            $renderer->doc .= '<a href="' . wl(getID(), $data [1]) . '" class="findnearby">' . hsc($data [0]) . '</a>';
110            return true;
111        } elseif ($format === 'metadata') {
112            return false;
113        } elseif ($format === 'odt') {
114            // don't render anything in ODT
115            return false;
116        }
117        return false;
118    }
119}
120