xref: /dokuwiki/inc/Parsing/Helpers/Link.php (revision b73ece99c18919754d993a1d1f5cb27140555705)
11e28e406SAndreas Gohr<?php
21e28e406SAndreas Gohr
31e28e406SAndreas Gohrnamespace dokuwiki\Parsing\Helpers;
41e28e406SAndreas Gohr
5*b73ece99SAndreas Gohruse dokuwiki\MailUtils;
6*b73ece99SAndreas Gohr
71e28e406SAndreas Gohr/**
81e28e406SAndreas Gohr * Pure helper for classifying link targets.
91e28e406SAndreas Gohr *
101e28e406SAndreas Gohr * Side-effect-free: returns data and leaves handler emission to the
111e28e406SAndreas Gohr * caller. Shared by DokuWiki's Internallink mode and GfmLink.
121e28e406SAndreas Gohr */
131e28e406SAndreas Gohrclass Link
141e28e406SAndreas Gohr{
151e28e406SAndreas Gohr    /**
161e28e406SAndreas Gohr     * Classify a link target and return the handler call that would emit it.
171e28e406SAndreas Gohr     *
181e28e406SAndreas Gohr     * Classification order: interwiki prefix, then Windows share, then
191e28e406SAndreas Gohr     * protocol scheme, then email, then local anchor, then internal page
201e28e406SAndreas Gohr     * as the default. The order is load-bearing — e.g. a URL with an
211e28e406SAndreas Gohr     * interwiki prefix that also matches an email pattern is still
221e28e406SAndreas Gohr     * dispatched as interwiki.
231e28e406SAndreas Gohr     *
241e28e406SAndreas Gohr     * @param string $url raw link target
251e28e406SAndreas Gohr     * @param string|array|null $label display label, or null; for
261e28e406SAndreas Gohr     *     Internallink this may be a parsed media array
271e28e406SAndreas Gohr     * @return array{0: string, 1: array} tuple of [handler call name, args]
281e28e406SAndreas Gohr     *     — caller invokes $handler->addCall($name, $args, $pos)
291e28e406SAndreas Gohr     */
301e28e406SAndreas Gohr    public static function classify(string $url, $label): array
311e28e406SAndreas Gohr    {
321e28e406SAndreas Gohr        if (link_isinterwiki($url)) {
331e28e406SAndreas Gohr            $iw = sexplode('>', $url, 2, '');
341e28e406SAndreas Gohr            return ['interwikilink', [$url, $label, strtolower($iw[0]), $iw[1]]];
351e28e406SAndreas Gohr        }
361e28e406SAndreas Gohr        if (preg_match('/^\\\\\\\\[^\\\\]+?\\\\/u', $url)) {
371e28e406SAndreas Gohr            return ['windowssharelink', [$url, $label]];
381e28e406SAndreas Gohr        }
391e28e406SAndreas Gohr        if (preg_match('#^([a-z0-9\-\.+]+?)://#i', $url)) {
401e28e406SAndreas Gohr            return ['externallink', [$url, $label]];
411e28e406SAndreas Gohr        }
42*b73ece99SAndreas Gohr        if (preg_match('<' . MailUtils::PREG_PATTERN_VALID_EMAIL . '>', $url)) {
431e28e406SAndreas Gohr            return ['emaillink', [$url, $label]];
441e28e406SAndreas Gohr        }
451e28e406SAndreas Gohr        if (preg_match('!^#.+!', $url)) {
461e28e406SAndreas Gohr            return ['locallink', [substr($url, 1), $label]];
471e28e406SAndreas Gohr        }
481e28e406SAndreas Gohr        return ['internallink', [$url, $label]];
491e28e406SAndreas Gohr    }
501e28e406SAndreas Gohr}
51