Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
62 / 62 |
|
100.00% |
5 / 5 |
CRAP | |
100.00% |
1 / 1 |
FormIdHtmlFormatter | |
100.00% |
62 / 62 |
|
100.00% |
5 / 5 |
13 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
formatEntityId | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
6 | |||
getLinkTitle | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
2 | |||
getLabels | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
3 | |||
buildRepresentationMarkupElements | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare( strict_types = 1 ); |
4 | |
5 | namespace Wikibase\Lexeme\Presentation\Formatters; |
6 | |
7 | use InvalidArgumentException; |
8 | use MediaWiki\Html\Html; |
9 | use MediaWiki\Languages\LanguageFactory; |
10 | use Wikibase\DataModel\Entity\EntityId; |
11 | use Wikibase\DataModel\Services\EntityId\EntityIdFormatter; |
12 | use Wikibase\DataModel\Services\Lookup\LabelDescriptionLookup; |
13 | use Wikibase\DataModel\Services\Lookup\UnresolvedEntityRedirectException; |
14 | use Wikibase\DataModel\Term\Term; |
15 | use Wikibase\DataModel\Term\TermList; |
16 | use Wikibase\Lexeme\Domain\Model\Form; |
17 | use Wikibase\Lexeme\Domain\Model\FormId; |
18 | use Wikibase\Lib\Formatters\NonExistingEntityIdHtmlFormatter; |
19 | use Wikibase\Lib\Store\EntityRevisionLookup; |
20 | use Wikibase\Lib\Store\EntityTitleLookup; |
21 | use Wikibase\View\LocalizedTextProvider; |
22 | |
23 | /** |
24 | * @license GPL-2.0-or-later |
25 | */ |
26 | class FormIdHtmlFormatter implements EntityIdFormatter { |
27 | |
28 | private const REPRESENTATION_SEPARATOR_I18N = |
29 | 'wikibaselexeme-formidformatter-separator-multiple-representation'; |
30 | private const GRAMMATICAL_FEATURES_SEPARATOR_I18N = |
31 | 'wikibaselexeme-formidformatter-separator-grammatical-features'; |
32 | |
33 | private EntityRevisionLookup $revisionLookup; |
34 | private EntityTitleLookup $titleLookup; |
35 | private NonExistingEntityIdHtmlFormatter $nonExistingIdFormatter; |
36 | private LocalizedTextProvider $localizedTextProvider; |
37 | private RedirectedLexemeSubEntityIdHtmlFormatter $redirectedLexemeSubEntityIdHtmlFormatter; |
38 | private LabelDescriptionLookup $labelDescriptionLookup; |
39 | private LanguageFactory $languageFactory; |
40 | |
41 | public function __construct( |
42 | EntityRevisionLookup $revisionLookup, |
43 | LabelDescriptionLookup $labelDescriptionLookup, |
44 | EntityTitleLookup $titleLookup, |
45 | LocalizedTextProvider $localizedTextProvider, |
46 | RedirectedLexemeSubEntityIdHtmlFormatter $redirectedLexemeSubEntityIdHtmlFormatter, |
47 | LanguageFactory $languageFactory |
48 | ) { |
49 | $this->revisionLookup = $revisionLookup; |
50 | $this->labelDescriptionLookup = $labelDescriptionLookup; |
51 | $this->titleLookup = $titleLookup; |
52 | $this->localizedTextProvider = $localizedTextProvider; |
53 | $this->redirectedLexemeSubEntityIdHtmlFormatter = $redirectedLexemeSubEntityIdHtmlFormatter; |
54 | $this->nonExistingIdFormatter = new NonExistingEntityIdHtmlFormatter( |
55 | 'wikibaselexeme-deletedentity-' |
56 | ); |
57 | $this->languageFactory = $languageFactory; |
58 | } |
59 | |
60 | public function formatEntityId( EntityId $formId ): string { |
61 | try { |
62 | $formRevision = $this->revisionLookup->getEntityRevision( $formId ); |
63 | $title = $this->titleLookup->getTitleForId( $formId ); |
64 | } catch ( UnresolvedEntityRedirectException $exception ) { |
65 | return $this->redirectedLexemeSubEntityIdHtmlFormatter->formatEntityId( $formId ); |
66 | } |
67 | if ( !( $formId instanceof FormId ) ) { |
68 | throw new InvalidArgumentException( |
69 | 'Attemped to format a non-Form entity as a Form: ' . $formId->getSerialization() ); |
70 | } |
71 | |
72 | if ( $formRevision === null || $title === null ) { |
73 | return $this->nonExistingIdFormatter->formatEntityId( $formId ); |
74 | } |
75 | |
76 | /** @var Form $form */ |
77 | $form = $formRevision->getEntity(); |
78 | '@phan-var Form $form'; |
79 | |
80 | $representationMarkup = implode( |
81 | $this->localizedTextProvider->getEscaped( |
82 | self::REPRESENTATION_SEPARATOR_I18N |
83 | ), |
84 | $this->buildRepresentationMarkupElements( $form->getRepresentations() ) |
85 | ); |
86 | |
87 | return Html::rawElement( |
88 | 'a', |
89 | [ |
90 | 'href' => $title->isLocal() ? $title->getLinkURL() : $title->getFullURL(), |
91 | 'title' => $this->getLinkTitle( $form ), |
92 | ], |
93 | $representationMarkup |
94 | ); |
95 | } |
96 | |
97 | private function getLinkTitle( Form $form ): string { |
98 | $serializedId = $form->getId()->getSerialization(); |
99 | $labels = implode( |
100 | $this->localizedTextProvider->get( self::GRAMMATICAL_FEATURES_SEPARATOR_I18N ), |
101 | $this->getLabels( $form ) |
102 | ); |
103 | |
104 | if ( $labels === '' ) { |
105 | $title = $serializedId; |
106 | } else { |
107 | $title = $this->localizedTextProvider->get( |
108 | 'wikibaselexeme-formidformatter-link-title', |
109 | [ $serializedId, $labels ] |
110 | ); |
111 | } |
112 | |
113 | return $title; |
114 | } |
115 | |
116 | private function getLabels( Form $form ): array { |
117 | $labels = []; |
118 | |
119 | foreach ( $form->getGrammaticalFeatures() as $grammaticalFeaturesId ) { |
120 | $grammaticalFeatureLabel = $this->labelDescriptionLookup->getLabel( $grammaticalFeaturesId ); |
121 | |
122 | if ( $grammaticalFeatureLabel !== null ) { |
123 | $labels[] = $grammaticalFeatureLabel->getText(); |
124 | } |
125 | } |
126 | |
127 | return $labels; |
128 | } |
129 | |
130 | private function buildRepresentationMarkupElements( TermList $representations ): array { |
131 | return array_map( function ( Term $representation ) { |
132 | $language = $this->languageFactory->getLanguage( $representation->getLanguageCode() ); |
133 | return Html::element( |
134 | 'span', |
135 | [ |
136 | 'lang' => $language->getHtmlCode(), |
137 | 'dir' => $language->getDir(), |
138 | ], |
139 | $representation->getText() |
140 | ); |
141 | }, iterator_to_array( $representations->getIterator() ) ); |
142 | } |
143 | |
144 | } |