Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
WikiLinkPrefixer
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
2 / 2
9
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
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    private string $interWikiPrefix;
21    private TitleParser $parser;
22
23    /**
24     * @param string $interWikiPrefix E.g. "de" for the German Wikipedia.
25     * @param TitleParser $parser
26     */
27    public function __construct( string $interWikiPrefix, TitleParser $parser ) {
28        $this->interWikiPrefix = $interWikiPrefix;
29        $this->parser = $parser;
30    }
31
32    public function process( string $link ): string {
33        if ( $this->interWikiPrefix === ''
34            // Bail out early if the prefix is already there; the extra + avoid backtracking
35            || preg_match( '{^\h*+:?\h*+' . preg_quote( $this->interWikiPrefix ) . '\h*+:}iu', $link )
36        ) {
37            return $link;
38        }
39
40        try {
41            $title = $this->parser->parseTitle( $link );
42        } catch ( MalformedTitleException $ex ) {
43            return $link;
44        }
45
46        if ( $title->inNamespace( NS_CATEGORY )
47            // The syntax for thumbnail images would break with a prefix
48            || $title->inNamespace( NS_FILE )
49            || $title->inNamespace( NS_MEDIA )
50            || strcasecmp( $title->getInterwiki(), $this->interWikiPrefix ) === 0
51        ) {
52            return $link;
53        }
54
55        return ':' . $this->interWikiPrefix . ':' . ltrim( ltrim( $link ), ':' );
56    }
57
58}