xref: /dokuwiki/inc/Parsing/Helpers/Link.php (revision 1e28e406b358f79221c515b2a56520d5dbbfb6c8)
1*1e28e406SAndreas Gohr<?php
2*1e28e406SAndreas Gohr
3*1e28e406SAndreas Gohrnamespace dokuwiki\Parsing\Helpers;
4*1e28e406SAndreas Gohr
5*1e28e406SAndreas Gohr/**
6*1e28e406SAndreas Gohr * Pure helper for classifying link targets.
7*1e28e406SAndreas Gohr *
8*1e28e406SAndreas Gohr * Side-effect-free: returns data and leaves handler emission to the
9*1e28e406SAndreas Gohr * caller. Shared by DokuWiki's Internallink mode and GfmLink.
10*1e28e406SAndreas Gohr */
11*1e28e406SAndreas Gohrclass Link
12*1e28e406SAndreas Gohr{
13*1e28e406SAndreas Gohr    /**
14*1e28e406SAndreas Gohr     * Classify a link target and return the handler call that would emit it.
15*1e28e406SAndreas Gohr     *
16*1e28e406SAndreas Gohr     * Classification order: interwiki prefix, then Windows share, then
17*1e28e406SAndreas Gohr     * protocol scheme, then email, then local anchor, then internal page
18*1e28e406SAndreas Gohr     * as the default. The order is load-bearing — e.g. a URL with an
19*1e28e406SAndreas Gohr     * interwiki prefix that also matches an email pattern is still
20*1e28e406SAndreas Gohr     * dispatched as interwiki.
21*1e28e406SAndreas Gohr     *
22*1e28e406SAndreas Gohr     * @param string $url raw link target
23*1e28e406SAndreas Gohr     * @param string|array|null $label display label, or null; for
24*1e28e406SAndreas Gohr     *     Internallink this may be a parsed media array
25*1e28e406SAndreas Gohr     * @return array{0: string, 1: array} tuple of [handler call name, args]
26*1e28e406SAndreas Gohr     *     — caller invokes $handler->addCall($name, $args, $pos)
27*1e28e406SAndreas Gohr     */
28*1e28e406SAndreas Gohr    public static function classify(string $url, $label): array
29*1e28e406SAndreas Gohr    {
30*1e28e406SAndreas Gohr        if (link_isinterwiki($url)) {
31*1e28e406SAndreas Gohr            $iw = sexplode('>', $url, 2, '');
32*1e28e406SAndreas Gohr            return ['interwikilink', [$url, $label, strtolower($iw[0]), $iw[1]]];
33*1e28e406SAndreas Gohr        }
34*1e28e406SAndreas Gohr        if (preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u', $url)) {
35*1e28e406SAndreas Gohr            return ['windowssharelink', [$url, $label]];
36*1e28e406SAndreas Gohr        }
37*1e28e406SAndreas Gohr        if (preg_match('#^([a-z0-9\-\.+]+?)://#i', $url)) {
38*1e28e406SAndreas Gohr            return ['externallink', [$url, $label]];
39*1e28e406SAndreas Gohr        }
40*1e28e406SAndreas Gohr        if (preg_match('<' . PREG_PATTERN_VALID_EMAIL . '>', $url)) {
41*1e28e406SAndreas Gohr            return ['emaillink', [$url, $label]];
42*1e28e406SAndreas Gohr        }
43*1e28e406SAndreas Gohr        if (preg_match('!^#.+!', $url)) {
44*1e28e406SAndreas Gohr            return ['locallink', [substr($url, 1), $label]];
45*1e28e406SAndreas Gohr        }
46*1e28e406SAndreas Gohr        return ['internallink', [$url, $label]];
47*1e28e406SAndreas Gohr    }
48*1e28e406SAndreas Gohr}
49