Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
I18nInfo
0.00% covered (danger)
0.00%
0 / 23
0.00% covered (danger)
0.00%
0 / 8
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 __clone
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 createInterfaceI18n
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createPageContentI18n
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createLangI18n
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 toJsonArray
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 newFromJsonArray
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 jsonClassHintFor
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2declare( strict_types = 1 );
3
4namespace Wikimedia\Parsoid\NodeData;
5
6use Wikimedia\Bcp47Code\Bcp47Code;
7use Wikimedia\JsonCodec\Hint;
8use Wikimedia\JsonCodec\JsonCodecable;
9use Wikimedia\JsonCodec\JsonCodecableTrait;
10
11class I18nInfo implements JsonCodecable {
12    use JsonCodecableTrait;
13
14    public const USER_LANG = "x-user";
15    public const PAGE_LANG = "x-page";
16
17    /**
18     * Value for the "lang" parameter. Can be one of USER_LANG or PAGE_LANG, or a fixed language
19     * code (discouraged when USER_LANG or PAGE_LANG could be used instead).
20     */
21    public string $lang;
22
23    /**
24     * Key of the message in localization files
25     */
26    public string $key;
27
28    /**
29     * Ordered list of parameters for the localized message
30     * @var ?list
31     */
32    public ?array $params;
33
34    public function __construct( string $lang, string $key, ?array $params = null ) {
35        $this->lang = $lang;
36        $this->key = $key;
37        $this->params = $params;
38    }
39
40    public function __clone() {
41        // Parameters should generally be immutable, in which case a clone
42        // isn't strictly speaking necessary.  But just in case someone puts
43        // a mutable object in here, deep clone the parameter array.
44        foreach ( $this->params ?? [] as $key => &$value ) {
45            if ( is_object( $value ) ) {
46                $value = clone $value;
47            }
48        }
49    }
50
51    /**
52     * Creates internationalization information for a string or attribute value in the user
53     * interface language.
54     * @param string $key
55     * @param array|null $params
56     * @return I18nInfo
57     */
58    public static function createInterfaceI18n( string $key, ?array $params ): I18nInfo {
59        return new I18nInfo( self::USER_LANG, $key, $params );
60    }
61
62    /**
63     * Creates internationalization information for a string or attribute value in the page
64     * content language.
65     * @param string $key
66     * @param array|null $params
67     * @return I18nInfo
68     */
69    public static function createPageContentI18n( string $key, ?array $params ): I18nInfo {
70        return new I18nInfo( self::PAGE_LANG, $key, $params );
71    }
72
73    /**
74     * Creates internationalization information for a string or attribute value in an arbitrary
75     * language.
76     * The use of this method is discouraged; use ::createPageContentI18n(...) and
77     * ::createInterfaceI18n(...) where possible rather than, respectively,
78     * ::createLangI18n($wgContLang, ...) and ::createLangI18n($wgLang, ...).
79     * @param Bcp47Code $lang
80     * @param string $key
81     * @param array|null $params
82     * @return I18nInfo
83     */
84    public static function createLangI18n( Bcp47Code $lang, string $key, ?array $params ): I18nInfo {
85        return new I18nInfo( $lang->toBcp47Code(), $key, $params );
86    }
87
88    // Rich attribute serialization support.
89
90    /** @inheritDoc */
91    public function toJsonArray(): array {
92        $json = [
93            'lang' => $this->lang,
94            'key' => $this->key,
95        ];
96        // Save some space when there are no params
97        if ( $this->params !== null ) {
98            $json['params'] = $this->params;
99        }
100        return $json;
101    }
102
103    /** @inheritDoc */
104    public static function newFromJsonArray( array $json ) {
105        return new I18nInfo( $json['lang'], $json['key'], $json['params'] ?? null );
106    }
107
108    /** @inheritDoc */
109    public static function jsonClassHintFor( string $keyName ) {
110        if ( $keyName === 'params' ) {
111            // Consistent w/ serialization of MessageValue in core, even
112            // though we don't have direct access to this class type in
113            // Parsoid.
114            // @phan-suppress-next-line PhanUndeclaredClassReference
115            return Hint::build(
116                '\\Wikimedia\\Message\\MessageParam', Hint::INHERITED,
117                Hint::LIST, Hint::USE_SQUARE
118            );
119        }
120        return null;
121    }
122}