Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
StringForLanguageBuilder
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
8 / 8
15
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fallbackWithEnglish
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 placeholderWith
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 placeholderNoFallback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 placeholderForTitle
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLanguageProvided
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
4
 getStringAndLanguageCode
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
5
 getString
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3/**
4 * WikiLambda StringForLanguageBuilder
5 *
6 * @file
7 * @ingroup Extensions
8 * @copyright 2020– Abstract Wikipedia team; see AUTHORS.txt
9 * @license MIT
10 */
11
12namespace MediaWiki\Extension\WikiLambda\ZObjects;
13
14use MediaWiki\Language\Language;
15use MediaWiki\Language\LanguageFallbackMode;
16use MediaWiki\MediaWikiServices;
17
18/**
19 * Builder of a string for a certain language.
20 *
21 * Don't instantiate it directly, rather call
22 * MediaWiki\Extension\WikiLambda\ZObjects\ZMultilingualString->buildStringForLanguage( $lang )
23 */
24class StringForLanguageBuilder {
25
26    private LanguageFallbackMode $languageFallback = LanguageFallbackMode::STRICT;
27    private ?string $placeholderText = null;
28
29    /**
30     * @param Language $language The language with build the string for
31     * @param ZMultilingualString $provider Object that provides the localized strings.
32     */
33    public function __construct( private readonly Language $language, private readonly ZMultilingualString $provider ) {
34    }
35
36    /**
37     * If the string for the language passed to the constructor is not available, fallback to English.
38     * @return StringForLanguageBuilder
39     */
40    public function fallbackWithEnglish(): StringForLanguageBuilder {
41        $this->languageFallback = LanguageFallbackMode::MESSAGES;
42        return $this;
43    }
44
45    /**
46     * If we cannot find any string, return the passed placeholder.
47     * @param string $placeholderText Key of the placeholder
48     * @return StringForLanguageBuilder
49     */
50    public function placeholderWith( string $placeholderText ): StringForLanguageBuilder {
51        $this->placeholderText = $placeholderText;
52        return $this;
53    }
54
55    /**
56     * If we cannot find any string, return the default placeholder.
57     * @return StringForLanguageBuilder
58     */
59    public function placeholderNoFallback() {
60        return $this->placeholderWith( 'wikilambda-multilingualstring-nofallback' );
61    }
62
63    /**
64     * If we cannot find any string, return the placeholder for a title.
65     * @return StringForLanguageBuilder
66     */
67    public function placeholderForTitle() {
68        return $this->placeholderWith( 'wikilambda-editor-default-name' );
69    }
70
71    /**
72     * @return ?string The language code for which a string value is provided.
73     */
74    public function getLanguageProvided() {
75        $languageCode = $this->language->getCode();
76        if ( $this->provider->isLanguageProvidedValue( $languageCode ) ) {
77            return $languageCode;
78        }
79
80        // TODO (T362246): Dependency-inject
81        $fallbacks = MediaWikiServices::getInstance()->getLanguageFallback()->getAll(
82            $languageCode,
83            $this->languageFallback
84        );
85
86        foreach ( $fallbacks as $index => $fallbackLanguageCode ) {
87            if ( $this->provider->isLanguageProvidedValue( $fallbackLanguageCode ) ) {
88                return $fallbackLanguageCode;
89            }
90        }
91        return null;
92    }
93
94    /**
95     * Return the string and the language code.
96     *
97     * @return array
98     */
99    public function getStringAndLanguageCode(): array {
100        $languageCodeProvided = $this->getLanguageProvided();
101
102        if ( $languageCodeProvided !== null ) {
103            $title = $this->provider->getStringForLanguageCode( $languageCodeProvided );
104
105            // use 'untitled' placeholder instead of an empty string
106            if ( $title === '' && $this->placeholderText !== null ) {
107                $title = wfMessage( $this->placeholderText )->inLanguage( $this->language )->text();
108            }
109
110            return [
111                'title' => $title,
112                'languageCode' => $languageCodeProvided
113            ];
114        }
115
116        $languageCode = $this->language->getCode();
117
118        if ( $this->placeholderText !== null ) {
119            return [
120                'title' => wfMessage( $this->placeholderText )->inLanguage( $this->language )->text(),
121                'languageCode' => $languageCode
122            ];
123        }
124        return [
125            'title' => null,
126            'languageCode' => $languageCode
127        ];
128    }
129
130    /**
131     * Return the string.
132     *
133     * @return ?string
134     */
135    public function getString(): ?string {
136        return $this->getStringAndLanguageCode()[ 'title' ];
137    }
138}