xref: /plugin/backlinks/syntax.php (revision c271718a35f646c00ae56b1d41d7d66ea9a2cfb7)
1df3d88adSMichael Klier<?php
2fe957bb7Sgithub-actions[bot]
3fe957bb7Sgithub-actions[bot]use dokuwiki\Extension\SyntaxPlugin;
4*c271718aSMark Prinsuse dokuwiki\Logger;
5fe957bb7Sgithub-actions[bot]
6df3d88adSMichael Klier/**
752fa4f27SMark Prins * DokuWiki Syntax Plugin Backlinks.
8df3d88adSMichael Klier *
9e70bf163SMichael Klier * Shows a list of pages that link back to a given page.
10e70bf163SMichael Klier *
1152fa4f27SMark Prins * Syntax:  {{backlinks>[pagename][#filterNS|!#filterNS]}}
12e70bf163SMichael Klier *
1352fa4f27SMark Prins *   [pagename] - a valid wiki pagename or a . for the current page
1439718802SMark Prins *   [filterNS] - a valid,absolute namespace name, optionally prepended with ! to exclude
15e70bf163SMichael Klier *
16df3d88adSMichael Klier * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
17df3d88adSMichael Klier * @author  Michael Klier <chi@chimeric.de>
182287a730SMark Prins * @author  Mark C. Prins <mprins@users.sf.net>
19df3d88adSMichael Klier */
20*c271718aSMark Prins
21df3d88adSMichael Klier/**
22df3d88adSMichael Klier * All DokuWiki plugins to extend the parser/rendering mechanism
23d2570a6cSMark Prins * need to inherit from this class.
24df3d88adSMichael Klier */
25fe957bb7Sgithub-actions[bot]class syntax_plugin_backlinks extends SyntaxPlugin
26fe957bb7Sgithub-actions[bot]{
27df3d88adSMichael Klier    /**
282287a730SMark Prins     * Syntax Type.
29df3d88adSMichael Klier     *
30d2570a6cSMark Prins     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php.
31d2570a6cSMark Prins     *
322287a730SMark Prins     * @see DokuWiki_Syntax_Plugin::getType()
33df3d88adSMichael Klier     */
34*c271718aSMark Prins    public function getType(): string
35fe957bb7Sgithub-actions[bot]    {
36d2570a6cSMark Prins        return 'substition';
37d2570a6cSMark Prins    }
382287a730SMark Prins
392287a730SMark Prins    /**
402287a730SMark Prins     * @see DokuWiki_Syntax_Plugin::getPType()
412287a730SMark Prins     */
42*c271718aSMark Prins    public function getPType(): string
43fe957bb7Sgithub-actions[bot]    {
44d2570a6cSMark Prins        return 'block';
45d2570a6cSMark Prins    }
462287a730SMark Prins
472287a730SMark Prins    /**
482287a730SMark Prins     * @see Doku_Parser_Mode::getSort()
492287a730SMark Prins     */
50*c271718aSMark Prins    public function getSort(): int
51fe957bb7Sgithub-actions[bot]    {
52d2570a6cSMark Prins        return 304;
53d2570a6cSMark Prins    }
54df3d88adSMichael Klier
55df3d88adSMichael Klier    /**
562287a730SMark Prins     * Connect pattern to lexer.
57d2570a6cSMark Prins     *
582287a730SMark Prins     * @see Doku_Parser_Mode::connectTo()
59df3d88adSMichael Klier     */
60*c271718aSMark Prins    public function connectTo($mode): void
61fe957bb7Sgithub-actions[bot]    {
62df3d88adSMichael Klier        $this->Lexer->addSpecialPattern('\{\{backlinks>.+?\}\}', $mode, 'plugin_backlinks');
63df3d88adSMichael Klier    }
64df3d88adSMichael Klier
65df3d88adSMichael Klier    /**
662287a730SMark Prins     * Handler to prepare matched data for the rendering process.
67d2570a6cSMark Prins     *
682287a730SMark Prins     * @see DokuWiki_Syntax_Plugin::handle()
69df3d88adSMichael Klier     */
70*c271718aSMark Prins    public function handle($match, $state, $pos, Doku_Handler $handler): array
71fe957bb7Sgithub-actions[bot]    {
72b3014541SMark Prins        // strip {{backlinks> from start and }} from end
73b3014541SMark Prins        $match = substr($match, 12, -2);
7439718802SMark Prins
75d2570a6cSMark Prins        $includeNS = '';
7639718802SMark Prins        if (strstr($match, "#")) {
771ed0f63eSMark Prins            $includeNS = substr(strstr($match, "#", false), 1);
781ed0f63eSMark Prins            $match     = strstr($match, "#", true);
7939718802SMark Prins        }
8039718802SMark Prins
81fe957bb7Sgithub-actions[bot]        return ([$match, $includeNS]);
82df3d88adSMichael Klier    }
83df3d88adSMichael Klier
84df3d88adSMichael Klier    /**
85df3d88adSMichael Klier     * Handles the actual output creation.
86d2570a6cSMark Prins     *
872287a730SMark Prins     * @see DokuWiki_Syntax_Plugin::render()
88df3d88adSMichael Klier     */
89*c271718aSMark Prins    public function render($format, Doku_Renderer $renderer, $data): bool
90fe957bb7Sgithub-actions[bot]    {
91154ef50cSMichael Klier        global $lang;
927a3c4628SDirk Melchers        global $INFO;
937a3c4628SDirk Melchers        global $ID;
947a3c4628SDirk Melchers
957a3c4628SDirk Melchers        $id = $ID;
967a3c4628SDirk Melchers        // If it's a sidebar, get the original id.
977a3c4628SDirk Melchers        if ($INFO != null) {
987a3c4628SDirk Melchers            $id = $INFO['id'];
997a3c4628SDirk Melchers        }
1007a3c4628SDirk Melchers        $match = $data[0];
1017a3c4628SDirk Melchers        $match = ($match == '.') ? $id : $match;
1027a3c4628SDirk Melchers        if (strstr($match, ".:")) {
1037a3c4628SDirk Melchers            resolve_pageid(getNS($id), $match, $exists);
1047a3c4628SDirk Melchers        }
105df3d88adSMichael Klier
106d5c4cf25SMark Prins        if ($format == 'xhtml') {
107df3d88adSMichael Klier            $renderer->info['cache'] = false;
108df3d88adSMichael Klier
1097a3c4628SDirk Melchers            $backlinks = ft_backlinks($match);
110af390d34SMichael Klier
111*c271718aSMark Prins            Logger::debug("backlinks: all backlinks to: $match", $backlinks);
11252fa4f27SMark Prins
113d2570a6cSMark Prins            $renderer->doc .= '<div id="plugin__backlinks">' . "\n";
114154ef50cSMichael Klier
11539718802SMark Prins            $filterNS = $data[1];
11639718802SMark Prins            if (!empty($backlinks) && !empty($filterNS)) {
11739718802SMark Prins                if (stripos($filterNS, "!", 0) === 0) {
11839718802SMark Prins                    $filterNS = substr($filterNS, 1);
119*c271718aSMark Prins                    Logger::debug("backlinks: excluding all of namespace: $filterNS");
1201ed0f63eSMark Prins                    $backlinks = array_filter(
121fe957bb7Sgithub-actions[bot]                        $backlinks,
122fe957bb7Sgithub-actions[bot]                        static fn($ns) => stripos($ns, $filterNS, 0) !== 0
1231ed0f63eSMark Prins                    );
12439718802SMark Prins                } else {
125*c271718aSMark Prins                    Logger::debug("backlinks: including namespace: $filterNS only");
1261ed0f63eSMark Prins                    $backlinks = array_filter(
127fe957bb7Sgithub-actions[bot]                        $backlinks,
128fe957bb7Sgithub-actions[bot]                        static fn($ns) => stripos($ns, (string) $filterNS, 0) === 0
1291ed0f63eSMark Prins                    );
13039718802SMark Prins                }
13139718802SMark Prins            }
13239718802SMark Prins
133*c271718aSMark Prins            Logger::debug("backlinks: all backlinks to be rendered", $backlinks);
13452fa4f27SMark Prins
135df3d88adSMichael Klier            if (!empty($backlinks)) {
136df3d88adSMichael Klier                $renderer->doc .= '<ul class="idx">';
137df3d88adSMichael Klier
138df3d88adSMichael Klier                foreach ($backlinks as $backlink) {
139cef58d31SMichael Klier                    $name = p_get_metadata($backlink, 'title');
1407ce29d5aSScrutinizer Auto-Fixer                    if (empty($name)) {
1417ce29d5aSScrutinizer Auto-Fixer                        $name = $backlink;
1427ce29d5aSScrutinizer Auto-Fixer                    }
143df3d88adSMichael Klier                    $renderer->doc .= '<li><div class="li">';
144b3014541SMark Prins                    $renderer->doc .= html_wikilink(':' . $backlink, $name);
145d2570a6cSMark Prins                    $renderer->doc .= '</div></li>' . "\n";
146df3d88adSMichael Klier                }
147df3d88adSMichael Klier
148d2570a6cSMark Prins                $renderer->doc .= '</ul>' . "\n";
149154ef50cSMichael Klier            } else {
150d2570a6cSMark Prins                $renderer->doc .= "<strong>Plugin Backlinks: " . $lang['nothingfound'] . "</strong>" . "\n";
151df3d88adSMichael Klier            }
152df3d88adSMichael Klier
153d2570a6cSMark Prins            $renderer->doc .= '</div>' . "\n";
154154ef50cSMichael Klier
155df3d88adSMichael Klier            return true;
156df3d88adSMichael Klier        }
157df3d88adSMichael Klier        return false;
158df3d88adSMichael Klier    }
159df3d88adSMichael Klier}
160