xref: /dokuwiki/inc/Parsing/ParserMode/Internallink.php (revision 71096e46fcbfaeaa808667aba794e77fe2780169)
1<?php
2
3namespace dokuwiki\Parsing\ParserMode;
4
5use dokuwiki\Parsing\Handler;
6
7class Internallink extends AbstractMode
8{
9    /** @inheritdoc */
10    public function getSort()
11    {
12        return 300;
13    }
14
15    /** @inheritdoc */
16    public function connectTo($mode)
17    {
18        // Word boundaries?
19        $this->Lexer->addSpecialPattern("\[\[.*?\]\](?!\])", $mode, 'internallink');
20    }
21
22    /** @inheritdoc */
23    public function handle($match, $state, $pos, Handler $handler)
24    {
25        // Strip the opening and closing markup
26        $link = preg_replace(['/^\[\[/', '/\]\]$/u'], '', $match);
27
28        // Split title from URL
29        $link = sexplode('|', $link, 2);
30        if ($link[1] !== null && preg_match('/^\{\{[^\}]+\}\}$/', $link[1])) {
31            // If the title is an image, convert it to an array containing the image details
32            $link[1] = Media::parseMedia($link[1]);
33        }
34        $link[0] = trim($link[0]);
35
36        //decide which kind of link it is
37
38        if (link_isinterwiki($link[0])) {
39            // Interwiki
40            $interwiki = sexplode('>', $link[0], 2, '');
41            $handler->addCall(
42                'interwikilink',
43                [$link[0], $link[1], strtolower($interwiki[0]), $interwiki[1]],
44                $pos
45            );
46        } elseif (preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u', $link[0])) {
47            // Windows Share
48            $handler->addCall(
49                'windowssharelink',
50                [$link[0], $link[1]],
51                $pos
52            );
53        } elseif (preg_match('#^([a-z0-9\-\.+]+?)://#i', $link[0])) {
54            // external link (accepts all protocols)
55            $handler->addCall(
56                'externallink',
57                [$link[0], $link[1]],
58                $pos
59            );
60        } elseif (preg_match('<' . PREG_PATTERN_VALID_EMAIL . '>', $link[0])) {
61            // E-Mail (pattern above is defined in inc/mail.php)
62            $handler->addCall(
63                'emaillink',
64                [$link[0], $link[1]],
65                $pos
66            );
67        } elseif (preg_match('!^#.+!', $link[0])) {
68            // local link
69            $handler->addCall(
70                'locallink',
71                [substr($link[0], 1), $link[1]],
72                $pos
73            );
74        } else {
75            // internal link
76            $handler->addCall(
77                'internallink',
78                [$link[0], $link[1]],
79                $pos
80            );
81        }
82
83        return true;
84    }
85}
86