xref: /plugin/backlinks/syntax.php (revision fe957bb77085fa5123aa131d5d16d51490b98806)
1<?php
2
3use dokuwiki\Extension\SyntaxPlugin;
4
5/**
6 * DokuWiki Syntax Plugin Backlinks.
7 *
8 * Shows a list of pages that link back to a given page.
9 *
10 * Syntax:  {{backlinks>[pagename][#filterNS|!#filterNS]}}
11 *
12 *   [pagename] - a valid wiki pagename or a . for the current page
13 *   [filterNS] - a valid,absolute namespace name, optionally prepended with ! to exclude
14 *
15 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
16 * @author  Michael Klier <chi@chimeric.de>
17 * @author  Mark C. Prins <mprins@users.sf.net>
18 */
19/**
20 * All DokuWiki plugins to extend the parser/rendering mechanism
21 * need to inherit from this class.
22 */
23class syntax_plugin_backlinks extends SyntaxPlugin
24{
25    /**
26     * Syntax Type.
27     *
28     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php.
29     *
30     * @see DokuWiki_Syntax_Plugin::getType()
31     */
32    public function getType()
33    {
34        return 'substition';
35    }
36
37    /**
38     * @see DokuWiki_Syntax_Plugin::getPType()
39     */
40    public function getPType()
41    {
42        return 'block';
43    }
44
45    /**
46     * @see Doku_Parser_Mode::getSort()
47     */
48    public function getSort()
49    {
50        return 304;
51    }
52
53    /**
54     * Connect pattern to lexer.
55     *
56     * @see Doku_Parser_Mode::connectTo()
57     */
58    public function connectTo($mode)
59    {
60        $this->Lexer->addSpecialPattern('\{\{backlinks>.+?\}\}', $mode, 'plugin_backlinks');
61    }
62
63    /**
64     * Handler to prepare matched data for the rendering process.
65     *
66     * @see DokuWiki_Syntax_Plugin::handle()
67     */
68    public function handle($match, $state, $pos, Doku_Handler $handler)
69    {
70        // strip {{backlinks> from start and }} from end
71        $match = substr($match, 12, -2);
72
73        $includeNS = '';
74        if (strstr($match, "#")) {
75            $includeNS = substr(strstr($match, "#", false), 1);
76            $match     = strstr($match, "#", true);
77        }
78
79        return ([$match, $includeNS]);
80    }
81
82    /**
83     * Handles the actual output creation.
84     *
85     * @see DokuWiki_Syntax_Plugin::render()
86     */
87    public function render($format, Doku_Renderer $renderer, $data)
88    {
89        global $lang;
90        global $INFO;
91        global $ID;
92
93        $id = $ID;
94        // If it's a sidebar, get the original id.
95        if ($INFO != null) {
96            $id = $INFO['id'];
97        }
98        $match = $data[0];
99        $match = ($match == '.') ? $id : $match;
100        if (strstr($match, ".:")) {
101            resolve_pageid(getNS($id), $match, $exists);
102        }
103
104        if ($format == 'xhtml') {
105            $renderer->info['cache'] = false;
106
107            $backlinks = ft_backlinks($match);
108
109            dbglog($backlinks, "backlinks: all backlinks to: $match");
110
111            $renderer->doc .= '<div id="plugin__backlinks">' . "\n";
112
113            $filterNS = $data[1];
114            if (!empty($backlinks) && !empty($filterNS)) {
115                if (stripos($filterNS, "!", 0) === 0) {
116                    $filterNS = substr($filterNS, 1);
117                    dbglog($filterNS, "backlinks: exluding all of namespace: $filterNS");
118                    $backlinks = array_filter(
119                        $backlinks,
120                        static fn($ns) => stripos($ns, $filterNS, 0) !== 0
121                    );
122                } else {
123                    dbglog($filterNS, "backlinks: including namespace: $filterNS only");
124                    $backlinks = array_filter(
125                        $backlinks,
126                        static fn($ns) => stripos($ns, (string) $filterNS, 0) === 0
127                    );
128                }
129            }
130
131            dbglog($backlinks, "backlinks: all backlinks to be rendered");
132
133            if (!empty($backlinks)) {
134                $renderer->doc .= '<ul class="idx">';
135
136                foreach ($backlinks as $backlink) {
137                    $name = p_get_metadata($backlink, 'title');
138                    if (empty($name)) {
139                        $name = $backlink;
140                    }
141                    $renderer->doc .= '<li><div class="li">';
142                    $renderer->doc .= html_wikilink(':' . $backlink, $name);
143                    $renderer->doc .= '</div></li>' . "\n";
144                }
145
146                $renderer->doc .= '</ul>' . "\n";
147            } else {
148                $renderer->doc .= "<strong>Plugin Backlinks: " . $lang['nothingfound'] . "</strong>" . "\n";
149            }
150
151            $renderer->doc .= '</div>' . "\n";
152
153            return true;
154        }
155        return false;
156    }
157}
158