Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.14% covered (warning)
87.14%
61 / 70
20.00% covered (danger)
20.00%
1 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
EntitySchemaFormatter
87.14% covered (warning)
87.14%
61 / 70
20.00% covered (danger)
20.00%
1 / 5
17.61
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 format
72.73% covered (warning)
72.73%
8 / 11
0.00% covered (danger)
0.00%
0 / 1
7.99
 makePlainText
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
3.01
 makeWikiLink
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
3.01
 makeHtmlLink
86.67% covered (warning)
86.67%
26 / 30
0.00% covered (danger)
0.00%
0 / 1
3.02
1<?php
2
3declare( strict_types = 1 );
4
5namespace EntitySchema\Wikibase\Formatters;
6
7use DataValues\StringValue;
8use EntitySchema\DataAccess\LabelLookup;
9use EntitySchema\Domain\Model\EntitySchemaId;
10use EntitySchema\Wikibase\DataValues\EntitySchemaValue;
11use InvalidArgumentException;
12use MediaWiki\Linker\LinkRenderer;
13use MediaWiki\Title\TitleFactory;
14use MediaWiki\Title\TitleValue;
15use ValueFormatters\FormatterOptions;
16use ValueFormatters\ValueFormatter;
17use Wikibase\Lib\Formatters\SnakFormat;
18use Wikibase\Lib\Formatters\SnakFormatter;
19use Wikibase\Lib\LanguageFallbackIndicator;
20use Wikibase\Lib\LanguageNameLookupFactory;
21
22/**
23 * @license GPL-2.0-or-later
24 */
25class EntitySchemaFormatter implements ValueFormatter {
26
27    private string $format;
28    private LinkRenderer $linkRenderer;
29
30    private LabelLookup $labelLookup;
31
32    private FormatterOptions $options;
33    private TitleFactory $titleFactory;
34    private LanguageNameLookupFactory $languageNameLookupFactory;
35
36    public function __construct(
37        string $format,
38        FormatterOptions $options,
39        LinkRenderer $linkRenderer,
40        LabelLookup $labelLookup,
41        TitleFactory $titleFactory,
42        LanguageNameLookupFactory $languageNameLookupFactory
43    ) {
44        $this->format = $format;
45        $this->linkRenderer = $linkRenderer;
46        $this->labelLookup = $labelLookup;
47        $this->options = $options;
48        $this->titleFactory = $titleFactory;
49        $this->languageNameLookupFactory = $languageNameLookupFactory;
50    }
51
52    /**
53     * @inheritDoc
54     */
55    public function format( $value ) {
56        if ( $value instanceof StringValue ) {
57            $value = new EntitySchemaValue( new EntitySchemaId( $value->getValue() ) );
58        }
59        if ( !( $value instanceof EntitySchemaValue ) ) {
60            throw new InvalidArgumentException( '$value must be a EntitySchemaValue' );
61        }
62
63        $entitySchemaId = $value->getSchemaId();
64        $snakFormat = new SnakFormat();
65
66        switch ( $snakFormat->getBaseFormat( $this->format ) ) {
67            case SnakFormatter::FORMAT_HTML:
68                return $this->makeHtmlLink( $entitySchemaId );
69            case SnakFormatter::FORMAT_WIKI:
70                return $this->makeWikiLink( $entitySchemaId );
71            case SnakFormatter::FORMAT_PLAIN:
72                return $this->makePlainText( $entitySchemaId );
73            default:
74                return $entitySchemaId;
75        }
76    }
77
78    private function makePlainText( string $entitySchemaId ): string {
79        $schemaPageIdentity = $this->titleFactory->newFromText( $entitySchemaId, NS_ENTITYSCHEMA_JSON );
80        if ( $schemaPageIdentity === null ) {
81            return $entitySchemaId;
82        }
83        $requestedLanguageCode = $this->options->getOption( ValueFormatter::OPT_LANG );
84        $labelTerm = $this->labelLookup->getLabelForTitle(
85            $schemaPageIdentity,
86            $requestedLanguageCode
87        );
88
89        if ( $labelTerm ) {
90            return $labelTerm->getText();
91        }
92        return $schemaPageIdentity->getText();
93    }
94
95    private function makeWikiLink( string $entitySchemaId ): string {
96        $schemaPageIdentity = $this->titleFactory->newFromText( $entitySchemaId, NS_ENTITYSCHEMA_JSON );
97        if ( $schemaPageIdentity === null ) {
98            return "[[EntitySchema:$entitySchemaId]]";
99        }
100        $requestedLanguageCode = $this->options->getOption( ValueFormatter::OPT_LANG );
101        $labelTerm = $this->labelLookup->getLabelForTitle(
102            $schemaPageIdentity,
103            $requestedLanguageCode
104        );
105
106        $linkTitle = 'EntitySchema:' . $entitySchemaId;
107        if ( $labelTerm ) {
108            return '[[' . $linkTitle . '|' . wfEscapeWikiText( $labelTerm->getText() ) . ']]';
109        }
110        return '[[' . $linkTitle . ']]';
111    }
112
113    private function makeHtmlLink( string $entitySchemaId ): string {
114        $linkTarget = new TitleValue( NS_ENTITYSCHEMA_JSON, $entitySchemaId );
115        $schemaPageIdentity = $this->titleFactory->newFromText( $entitySchemaId, NS_ENTITYSCHEMA_JSON );
116
117        if ( $schemaPageIdentity === null ) {
118            return $this->linkRenderer->makePreloadedLink(
119                $linkTarget,
120                $entitySchemaId
121            );
122        }
123
124        $requestedLanguageCode = $this->options->getOption( ValueFormatter::OPT_LANG );
125        $labelTerm = $this->labelLookup->getLabelForTitle(
126            $schemaPageIdentity,
127            $requestedLanguageCode
128        );
129
130        if ( $labelTerm ) {
131            $linkHtml = $this->linkRenderer->makePreloadedLink(
132                $linkTarget,
133                $labelTerm->getText(),
134                '',
135                [
136                    'lang' => $labelTerm->getActualLanguageCode(),
137                ]
138            );
139            $languageFallbackIndicator = new LanguageFallbackIndicator(
140                $this->languageNameLookupFactory->getForLanguageCode( $requestedLanguageCode )
141            );
142            $fallbackHtml = $languageFallbackIndicator->getHtml( $labelTerm );
143
144            return $linkHtml . $fallbackHtml;
145        }
146
147        return $this->linkRenderer->makePreloadedLink(
148            $linkTarget,
149            $entitySchemaId
150        );
151    }
152}