25 $expectedKeywords = UnicodePlural::getPluralKeywords( $targetLanguage );
29 $definitionHasPlural = UnicodePlural::hasPlural( $definition );
30 $translationHasPlural = UnicodePlural::hasPlural( $translation );
32 $presence = $this->pluralPresenceCheck(
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 )
51 $actualExample = UnicodePlural::flattenList(
52 array_map( $formatter, $actualKeywords )
58 'translate-checks-unicode-plural-invalid',
60 [
'PLAIN', $expectedExample ],
61 [
'PLAIN', $actualExample ],
64 $issues->add( $issue );
72 private function pluralPresenceCheck(
73 bool $definitionHasPlural,
74 bool $translationHasPlural
76 if ( !$definitionHasPlural && $translationHasPlural ) {
78 } elseif ( $definitionHasPlural && !$translationHasPlural ) {
80 } elseif ( !$definitionHasPlural && !$translationHasPlural ) {
81 return 'not-applicable';
88 private function pluralFormCheck(
string $text, ?array $expectedKeywords ): array {
89 [ , $instanceMap ] = UnicodePlural::parsePluralForms( $text );
91 foreach ( $instanceMap as $forms ) {
93 foreach ( $forms as [ $keyword, ] ) {
94 $actualKeywords[] = $keyword;
97 if ( $expectedKeywords !==
null ) {
98 if ( $actualKeywords !== $expectedKeywords ) {
99 return [
'invalid', $actualKeywords ];
101 } elseif ( array_diff( $actualKeywords, UnicodePlural::KEYWORDS ) !== [] ) {
104 return [
'invalid', $actualKeywords ];