Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
37 / 37 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
MediaWikiLinkValidator | |
100.00% |
37 / 37 |
|
100.00% |
2 / 2 |
6 | |
100.00% |
1 / 1 |
getIssues | |
100.00% |
28 / 28 |
|
100.00% |
1 / 1 |
3 | |||
getLinksMissingInTarget | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace MediaWiki\Extension\Translate\Validation\Validators; |
5 | |
6 | use MediaWiki\Extension\Translate\MessageLoading\Message; |
7 | use MediaWiki\Extension\Translate\Validation\MessageValidator; |
8 | use MediaWiki\Extension\Translate\Validation\ValidationIssue; |
9 | use MediaWiki\Extension\Translate\Validation\ValidationIssues; |
10 | |
11 | /** |
12 | * Checks if the translation uses links that are discouraged. Valid links are those that link |
13 | * to Special: or {{ns:special}}: or project pages trough MediaWiki messages like |
14 | * {{MediaWiki:helppage-url}}:. Also links in the definition are allowed. |
15 | * @license GPL-2.0-or-later |
16 | * @since 2020.02 |
17 | */ |
18 | class MediaWikiLinkValidator implements MessageValidator { |
19 | public function getIssues( Message $message, string $targetLanguage ): ValidationIssues { |
20 | $issues = new ValidationIssues(); |
21 | |
22 | $definition = $message->definition(); |
23 | $translation = $message->translation(); |
24 | |
25 | $links = $this->getLinksMissingInTarget( $definition, $translation ); |
26 | if ( $links !== [] ) { |
27 | $issue = new ValidationIssue( |
28 | 'links', |
29 | 'missing', |
30 | 'translate-checks-links-missing', |
31 | [ |
32 | [ 'PARAMS', $links ], |
33 | [ 'COUNT', count( $links ) ], |
34 | ] |
35 | ); |
36 | $issues->add( $issue ); |
37 | } |
38 | |
39 | $links = $this->getLinksMissingInTarget( $translation, $definition ); |
40 | if ( $links !== [] ) { |
41 | $issue = new ValidationIssue( |
42 | 'links', |
43 | 'extra', |
44 | 'translate-checks-links', |
45 | [ |
46 | [ 'PARAMS', $links ], |
47 | [ 'COUNT', count( $links ) ], |
48 | ] |
49 | ); |
50 | $issues->add( $issue ); |
51 | } |
52 | |
53 | return $issues; |
54 | } |
55 | |
56 | private function getLinksMissingInTarget( string $source, string $target ): array { |
57 | global $wgLegalTitleChars; |
58 | $tc = $wgLegalTitleChars . '#%{}'; |
59 | $matches = $links = []; |
60 | |
61 | preg_match_all( "/\[\[([{$tc}]+)(\\|(.+?))?]]/sDu", $source, $matches ); |
62 | $count = count( $matches[0] ); |
63 | for ( $i = 0; $i < $count; $i++ ) { |
64 | $backMatch = preg_quote( $matches[1][$i], '/' ); |
65 | if ( preg_match( "/\[\[$backMatch/", $target ) !== 1 ) { |
66 | $links[] = "[[{$matches[1][$i]}{$matches[2][$i]}]]"; |
67 | } |
68 | } |
69 | |
70 | return $links; |
71 | } |
72 | } |