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