Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
63.64% |
21 / 33 |
|
60.00% |
6 / 10 |
CRAP | |
0.00% |
0 / 1 |
XmlSelect | |
65.62% |
21 / 32 |
|
60.00% |
6 / 10 |
36.25 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
setDefault | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setTagName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setAttribute | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getAttribute | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
addOption | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
addOptions | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
formatOptions | |
75.00% |
6 / 8 |
|
0.00% |
0 / 1 |
4.25 | |||
getHTML | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
parseOptionsMessage | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | /** |
3 | * Class for generating HTML <select> elements. |
4 | * |
5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License along |
16 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
18 | * http://www.gnu.org/copyleft/gpl.html |
19 | * |
20 | * @file |
21 | */ |
22 | |
23 | namespace MediaWiki\Xml; |
24 | |
25 | use MediaWiki\Html\Html; |
26 | |
27 | /** |
28 | * Class for generating HTML <select> or <datalist> elements. |
29 | */ |
30 | class XmlSelect { |
31 | /** @var array[] */ |
32 | protected $options = []; |
33 | /** @var string|array|false */ |
34 | protected $default = false; |
35 | /** @var string|array */ |
36 | protected $tagName = 'select'; |
37 | /** @var (string|int)[] */ |
38 | protected $attributes = []; |
39 | |
40 | public function __construct( $name = false, $id = false, $default = false ) { |
41 | if ( $name ) { |
42 | $this->setAttribute( 'name', $name ); |
43 | } |
44 | |
45 | if ( $id ) { |
46 | $this->setAttribute( 'id', $id ); |
47 | } |
48 | |
49 | if ( $default !== false ) { |
50 | $this->default = $default; |
51 | } |
52 | } |
53 | |
54 | /** |
55 | * @param string|array $default |
56 | */ |
57 | public function setDefault( $default ) { |
58 | $this->default = $default; |
59 | } |
60 | |
61 | /** |
62 | * @param string|array $tagName |
63 | */ |
64 | public function setTagName( $tagName ) { |
65 | $this->tagName = $tagName; |
66 | } |
67 | |
68 | /** |
69 | * @param string $name |
70 | * @param string|int $value |
71 | */ |
72 | public function setAttribute( $name, $value ) { |
73 | $this->attributes[$name] = $value; |
74 | } |
75 | |
76 | /** |
77 | * @param string $name |
78 | * @return string|int|null |
79 | */ |
80 | public function getAttribute( $name ) { |
81 | return $this->attributes[$name] ?? null; |
82 | } |
83 | |
84 | /** |
85 | * @param string $label |
86 | * @param string|int|float|false $value If not given, assumed equal to $label |
87 | */ |
88 | public function addOption( $label, $value = false ) { |
89 | $value = $value !== false ? $value : $label; |
90 | $this->options[] = [ $label => $value ]; |
91 | } |
92 | |
93 | /** |
94 | * This accepts an array of form |
95 | * label => value |
96 | * label => ( label => value, label => value ) |
97 | * |
98 | * @param array $options |
99 | */ |
100 | public function addOptions( $options ) { |
101 | $this->options[] = $options; |
102 | } |
103 | |
104 | /** |
105 | * This accepts an array of form: |
106 | * label => value |
107 | * label => ( label => value, label => value ) |
108 | * |
109 | * @param array $options |
110 | * @param string|array|false $default |
111 | * @return string |
112 | */ |
113 | public static function formatOptions( $options, $default = false ) { |
114 | $data = ''; |
115 | |
116 | foreach ( $options as $label => $value ) { |
117 | if ( is_array( $value ) ) { |
118 | $contents = self::formatOptions( $value, $default ); |
119 | $data .= Html::rawElement( 'optgroup', [ 'label' => $label ], $contents ) . "\n"; |
120 | } else { |
121 | // If $default is an array, then the <select> probably has the multiple attribute, |
122 | // so we should check if each $value is in $default, rather than checking if |
123 | // $value is equal to $default. |
124 | $selected = is_array( $default ) ? in_array( $value, $default ) : $value === $default; |
125 | $data .= Xml::option( $label, $value, $selected ) . "\n"; |
126 | } |
127 | } |
128 | |
129 | return $data; |
130 | } |
131 | |
132 | /** |
133 | * @return string |
134 | */ |
135 | public function getHTML() { |
136 | $contents = ''; |
137 | |
138 | foreach ( $this->options as $options ) { |
139 | $contents .= self::formatOptions( $options, $this->default ); |
140 | } |
141 | |
142 | return Html::rawElement( $this->tagName, $this->attributes, rtrim( $contents ) ); |
143 | } |
144 | |
145 | /** |
146 | * Parse labels and values out of a comma- and colon-separated list of options, such as is used for |
147 | * expiry and duration lists. Documentation of the format is on translatewiki.net. |
148 | * @since 1.35 |
149 | * @link https://translatewiki.net/wiki/Template:Doc-mediawiki-options-list |
150 | * @param string $msg The message to parse. |
151 | * @return string[] The options array, where keys are option labels (i.e. translations) |
152 | * and values are option values (i.e. untranslated). |
153 | */ |
154 | public static function parseOptionsMessage( string $msg ): array { |
155 | $options = []; |
156 | foreach ( explode( ',', $msg ) as $option ) { |
157 | // Normalize options that only have one part. |
158 | if ( strpos( $option, ':' ) === false ) { |
159 | $option = "$option:$option"; |
160 | } |
161 | // Extract the two parts. |
162 | [ $label, $value ] = explode( ':', $option ); |
163 | $options[ trim( $label ) ] = trim( $value ); |
164 | } |
165 | return $options; |
166 | } |
167 | } |
168 | /** @deprecated class alias since 1.43 */ |
169 | class_alias( XmlSelect::class, 'XmlSelect' ); |