Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
WikiLinkPrefixer
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
2 / 2
9
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 process
100.00% covered (success)
100.00%
12 / 12
100.00% covered (success)
100.00%
1 / 1
8
1<?php
2
3namespace FileImporter\Services\Wikitext;
4
5use MediaWiki\Title\MalformedTitleException;
6use MediaWiki\Title\TitleParser;
7
8/**
9 * A small parser that adds an interwiki prefix to all links it can't understand. Incoming links are
10 * expected to have canonical English namespace names, or namespace names in the target wikis
11 * content language.
12 *
13 * This class uses MediaWiki's TitleParser to extract known interwiki prefixes and namespaces from
14 * the link, but doesn't use it to do any normalization.
15 *
16 * @license GPL-2.0-or-later
17 */
18class WikiLinkPrefixer implements WikiLinkCleaner {
19
20    /**
21     * @param string $interWikiPrefix E.g. "de" for the German Wikipedia.
22     * @param TitleParser $parser
23     */
24    public function __construct(
25        private readonly string $interWikiPrefix,
26        private readonly TitleParser $parser,
27    ) {
28    }
29
30    public function process( string $link ): string {
31        if ( $this->interWikiPrefix === ''
32            // Bail out early if the prefix is already there; the extra + avoid backtracking
33            || preg_match( '{^\h*+:?\h*+' . preg_quote( $this->interWikiPrefix ) . '\h*+:}iu', $link )
34        ) {
35            return $link;
36        }
37
38        try {
39            $title = $this->parser->parseTitle( $link );
40        } catch ( MalformedTitleException ) {
41            return $link;
42        }
43
44        if ( $title->inNamespace( NS_CATEGORY )
45            // The syntax for thumbnail images would break with a prefix
46            || $title->inNamespace( NS_FILE )
47            || $title->inNamespace( NS_MEDIA )
48            || strcasecmp( $title->getInterwiki(), $this->interWikiPrefix ) === 0
49        ) {
50            return $link;
51        }
52
53        return ':' . $this->interWikiPrefix . ':' . ltrim( ltrim( $link ), ':' );
54    }
55
56}