xref: /dokuwiki/inc/Parsing/ParserMode/Externallink.php (revision 71096e46fcbfaeaa808667aba794e77fe2780169)
1be906b56SAndreas Gohr<?php
2be906b56SAndreas Gohr
3be906b56SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode;
4be906b56SAndreas Gohr
5*71096e46SAndreas Gohruse dokuwiki\Parsing\Handler;
6*71096e46SAndreas Gohr
7be906b56SAndreas Gohrclass Externallink extends AbstractMode
8be906b56SAndreas Gohr{
9bcaec9f4SAndreas Gohr    protected $schemes = [];
10bcaec9f4SAndreas Gohr    protected $patterns = [];
11be906b56SAndreas Gohr
12be906b56SAndreas Gohr    /** @inheritdoc */
13*71096e46SAndreas Gohr    public function getSort()
14*71096e46SAndreas Gohr    {
15*71096e46SAndreas Gohr        return 330;
16*71096e46SAndreas Gohr    }
17*71096e46SAndreas Gohr
18*71096e46SAndreas Gohr    /** @inheritdoc */
19be906b56SAndreas Gohr    public function preConnect()
20be906b56SAndreas Gohr    {
21be906b56SAndreas Gohr        if (count($this->patterns)) return;
22be906b56SAndreas Gohr
23be906b56SAndreas Gohr        $ltrs = '\w';
24be906b56SAndreas Gohr        $gunk = '/\#~:.?+=&%@!\-\[\]';
25be906b56SAndreas Gohr        $punc = '.:?\-;,';
26be906b56SAndreas Gohr        $host = $ltrs . $punc;
27be906b56SAndreas Gohr        $any  = $ltrs . $gunk . $punc;
28be906b56SAndreas Gohr
29be906b56SAndreas Gohr        $this->schemes = getSchemes();
30be906b56SAndreas Gohr        foreach ($this->schemes as $scheme) {
31be906b56SAndreas Gohr            $this->patterns[] = '\b(?i)' . $scheme . '(?-i)://[' . $any . ']+?(?=[' . $punc . ']*[^' . $any . '])';
32be906b56SAndreas Gohr        }
33be906b56SAndreas Gohr
344da6a3ceSPhy        $this->patterns[] = '(?<![/\\\\])\b(?i)www?(?-i)\.[' . $host . ']+?\.' .
354da6a3ceSPhy                            '[' . $host . ']+?[' . $any . ']+?(?=[' . $punc . ']*[^' . $any . '])';
364da6a3ceSPhy        $this->patterns[] = '(?<![/\\\\])\b(?i)ftp?(?-i)\.[' . $host . ']+?\.' .
374da6a3ceSPhy                            '[' . $host . ']+?[' . $any . ']+?(?=[' . $punc . ']*[^' . $any . '])';
38be906b56SAndreas Gohr    }
39be906b56SAndreas Gohr
40be906b56SAndreas Gohr    /** @inheritdoc */
41be906b56SAndreas Gohr    public function connectTo($mode)
42be906b56SAndreas Gohr    {
43be906b56SAndreas Gohr
44be906b56SAndreas Gohr        foreach ($this->patterns as $pattern) {
45be906b56SAndreas Gohr            $this->Lexer->addSpecialPattern($pattern, $mode, 'externallink');
46be906b56SAndreas Gohr        }
47be906b56SAndreas Gohr    }
48be906b56SAndreas Gohr
49be906b56SAndreas Gohr    /** @inheritdoc */
50*71096e46SAndreas Gohr    public function handle($match, $state, $pos, Handler $handler)
51be906b56SAndreas Gohr    {
52*71096e46SAndreas Gohr        $url = $match;
53*71096e46SAndreas Gohr        $title = null;
54*71096e46SAndreas Gohr
55*71096e46SAndreas Gohr        // add protocol on simple short URLs
56*71096e46SAndreas Gohr        if (str_starts_with($url, 'ftp') && !str_starts_with($url, 'ftp://')) {
57*71096e46SAndreas Gohr            $title = $url;
58*71096e46SAndreas Gohr            $url = 'ftp://' . $url;
59*71096e46SAndreas Gohr        }
60*71096e46SAndreas Gohr        if (str_starts_with($url, 'www')) {
61*71096e46SAndreas Gohr            $title = $url;
62*71096e46SAndreas Gohr            $url = 'http://' . $url;
63*71096e46SAndreas Gohr        }
64*71096e46SAndreas Gohr
65*71096e46SAndreas Gohr        $handler->addCall('externallink', [$url, $title], $pos);
66*71096e46SAndreas Gohr        return true;
67be906b56SAndreas Gohr    }
685c99934fSAnna Dabrowska
695c99934fSAnna Dabrowska    /**
705c99934fSAnna Dabrowska     * @return array
715c99934fSAnna Dabrowska     */
725c99934fSAnna Dabrowska    public function getPatterns()
735c99934fSAnna Dabrowska    {
745c99934fSAnna Dabrowska        return $this->patterns;
755c99934fSAnna Dabrowska    }
76be906b56SAndreas Gohr}
77