Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
UnicodePluralValidator.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\Validation\Validators;
5
11
21 public function getIssues( Message $message, string $targetLanguage ): ValidationIssues {
22 $issues = new ValidationIssues();
23
24 // We skip certain validations if we don't know the expected keywords
25 $expectedKeywords = UnicodePlural::getPluralKeywords( $targetLanguage );
26
27 $definition = $message->definition();
28 $translation = $message->translation();
29 $definitionHasPlural = UnicodePlural::hasPlural( $definition );
30 $translationHasPlural = UnicodePlural::hasPlural( $translation );
31
32 $presence = $this->pluralPresenceCheck(
33 $definitionHasPlural,
34 $translationHasPlural
35 );
36
37 // Using same check keys as MediaWikiPluralValidator
38 if ( $presence === 'missing' && $expectedKeywords !== null ) {
39 $issue = new ValidationIssue( 'plural', 'missing', 'translate-checks-unicode-plural-missing' );
40 $issues->add( $issue );
41 } elseif ( $presence === 'unsupported' ) {
42 $issue = new ValidationIssue( 'plural', 'unsupported', 'translate-checks-unicode-plural-unsupported' );
43 $issues->add( $issue );
44 } elseif ( $presence === 'ok' ) {
45 [ $msgcode, $actualKeywords ] = $this->pluralFormCheck( $translation, $expectedKeywords );
46 if ( $msgcode === 'invalid' ) {
47 $formatter = fn ( string $x ) => [ $x, '…' ];
48 $expectedExample = UnicodePlural::flattenList(
49 array_map( $formatter, $expectedKeywords ?? UnicodePlural::KEYWORDS )
50 );
51 $actualExample = UnicodePlural::flattenList(
52 array_map( $formatter, $actualKeywords )
53 );
54
55 $issue = new ValidationIssue(
56 'plural',
57 'forms',
58 'translate-checks-unicode-plural-invalid',
59 [
60 [ 'PLAIN', $expectedExample ],
61 [ 'PLAIN', $actualExample ],
62 ]
63 );
64 $issues->add( $issue );
65 }
66 }
67 // else: not-applicable
68
69 return $issues;
70 }
71
72 private function pluralPresenceCheck(
73 bool $definitionHasPlural,
74 bool $translationHasPlural
75 ): string {
76 if ( !$definitionHasPlural && $translationHasPlural ) {
77 return 'unsupported';
78 } elseif ( $definitionHasPlural && !$translationHasPlural ) {
79 return 'missing';
80 } elseif ( !$definitionHasPlural && !$translationHasPlural ) {
81 return 'not-applicable';
82 }
83
84 // Both have plural
85 return 'ok';
86 }
87
88 private function pluralFormCheck( string $text, ?array $expectedKeywords ): array {
89 [ , $instanceMap ] = UnicodePlural::parsePluralForms( $text );
90
91 foreach ( $instanceMap as $forms ) {
92 $actualKeywords = [];
93 foreach ( $forms as [ $keyword, ] ) {
94 $actualKeywords[] = $keyword;
95 }
96
97 if ( $expectedKeywords !== null ) {
98 if ( $actualKeywords !== $expectedKeywords ) {
99 return [ 'invalid', $actualKeywords ];
100 }
101 } elseif ( array_diff( $actualKeywords, UnicodePlural::KEYWORDS ) !== [] ) {
102 // We don't know the actual forms for the language, but complain about those
103 // that are not valid in any language
104 return [ 'invalid', $actualKeywords ];
105 }
106 }
107
108 return [ 'ok', [] ];
109 }
110}
Interface for message objects used by MessageCollection.
Definition Message.php:13
This is a very strict validator class for Unicode CLDR based plural markup.