Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
36.99% |
27 / 73 |
|
36.36% |
4 / 11 |
CRAP | |
0.00% |
0 / 1 |
Licenses | |
36.99% |
27 / 73 |
|
36.36% |
4 / 11 |
209.40 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getMessageFromParams | |
28.57% |
2 / 7 |
|
0.00% |
0 / 1 |
6.28 | |||
buildLine | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
makeLines | |
86.67% |
13 / 15 |
|
0.00% |
0 / 1 |
7.12 | |||
trimStars | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
stackItem | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
makeHtml | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
12 | |||
outputOption | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
getLines | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getLicenses | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getInputHTML | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
6 |
1 | <?php |
2 | /** |
3 | * License selector for use on Special:Upload. |
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 | * @ingroup SpecialPage |
22 | * @author Ævar Arnfjörð Bjarmason <avarab@gmail.com> |
23 | * @copyright Copyright © 2005, Ævar Arnfjörð Bjarmason |
24 | */ |
25 | |
26 | use MediaWiki\Html\Html; |
27 | use MediaWiki\HTMLForm\HTMLFormField; |
28 | use MediaWiki\MediaWikiServices; |
29 | |
30 | /** |
31 | * A License class for use on Special:Upload |
32 | */ |
33 | class Licenses extends HTMLFormField { |
34 | /** @var string */ |
35 | protected $msg; |
36 | |
37 | /** @var array */ |
38 | protected $lines = []; |
39 | |
40 | /** @var string */ |
41 | protected $html; |
42 | |
43 | /** @var string|null */ |
44 | protected $selected; |
45 | |
46 | /** |
47 | * @param array $params |
48 | */ |
49 | public function __construct( $params ) { |
50 | parent::__construct( $params ); |
51 | |
52 | $this->msg = static::getMessageFromParams( $params ); |
53 | $this->selected = null; |
54 | |
55 | $this->makeLines(); |
56 | } |
57 | |
58 | /** |
59 | * @param array $params |
60 | * @return string |
61 | */ |
62 | protected static function getMessageFromParams( $params ) { |
63 | if ( !empty( $params['licenses'] ) ) { |
64 | return $params['licenses']; |
65 | } |
66 | |
67 | // If the licenses page is in $wgForceUIMsgAsContentMsg (which is the case |
68 | // on Commons), translations will be in the database, in subpages of this |
69 | // message (e.g. MediaWiki:Licenses/<lang>) |
70 | // If there is no such translation, the result will be '-' (the empty default |
71 | // in the i18n files), so we'll need to force it to look up the actual licenses |
72 | // in the default site language (= get the translation from MediaWiki:Licenses) |
73 | // Also see https://phabricator.wikimedia.org/T3495 |
74 | $defaultMsg = wfMessage( 'licenses' )->inContentLanguage(); |
75 | if ( $defaultMsg->isDisabled() ) { |
76 | $defaultMsg = wfMessage( 'licenses' )->inLanguage( |
77 | MediaWikiServices::getInstance()->getContentLanguage() ); |
78 | } |
79 | |
80 | return $defaultMsg->plain(); |
81 | } |
82 | |
83 | /** |
84 | * @param string $line |
85 | * @return License |
86 | */ |
87 | protected function buildLine( $line ) { |
88 | return new License( $line ); |
89 | } |
90 | |
91 | /** |
92 | * @internal |
93 | */ |
94 | protected function makeLines() { |
95 | $levels = []; |
96 | $lines = explode( "\n", $this->msg ); |
97 | |
98 | foreach ( $lines as $line ) { |
99 | if ( !str_starts_with( $line, '*' ) ) { |
100 | continue; |
101 | } |
102 | [ $level, $line ] = $this->trimStars( $line ); |
103 | |
104 | if ( str_contains( $line, '|' ) ) { |
105 | $obj = $this->buildLine( $line ); |
106 | $this->stackItem( $this->lines, $levels, $obj ); |
107 | } else { |
108 | if ( $level < count( $levels ) ) { |
109 | $levels = array_slice( $levels, 0, $level ); |
110 | } |
111 | if ( $level == count( $levels ) ) { |
112 | $levels[$level - 1] = $line; |
113 | } elseif ( $level > count( $levels ) ) { |
114 | $levels[] = $line; |
115 | } |
116 | } |
117 | } |
118 | } |
119 | |
120 | /** |
121 | * @param string $str |
122 | * @return array |
123 | */ |
124 | protected function trimStars( $str ) { |
125 | $numStars = strspn( $str, '*' ); |
126 | return [ $numStars, ltrim( substr( $str, $numStars ), ' ' ) ]; |
127 | } |
128 | |
129 | /** |
130 | * @param array &$list |
131 | * @param array $path |
132 | * @param mixed $item |
133 | */ |
134 | protected function stackItem( &$list, $path, $item ) { |
135 | $position =& $list; |
136 | if ( $path ) { |
137 | foreach ( $path as $key ) { |
138 | $position =& $position[$key]; |
139 | } |
140 | } |
141 | $position[] = $item; |
142 | } |
143 | |
144 | /** |
145 | * @param array $tagset |
146 | * @param int $depth |
147 | * @return string |
148 | */ |
149 | protected function makeHtml( $tagset, $depth = 0 ) { |
150 | $html = ''; |
151 | |
152 | foreach ( $tagset as $key => $val ) { |
153 | if ( is_array( $val ) ) { |
154 | $html .= $this->outputOption( |
155 | $key, '', |
156 | [ |
157 | 'disabled' => 'disabled' |
158 | ], |
159 | $depth |
160 | ); |
161 | $html .= $this->makeHtml( $val, $depth + 1 ); |
162 | } else { |
163 | $html .= $this->outputOption( |
164 | $val->text, $val->template, |
165 | [ 'title' => '{{' . $val->template . '}}' ], |
166 | $depth |
167 | ); |
168 | } |
169 | } |
170 | |
171 | return $html; |
172 | } |
173 | |
174 | /** |
175 | * @param string $message |
176 | * @param string $value |
177 | * @param null|array $attribs |
178 | * @param int $depth |
179 | * @return string |
180 | */ |
181 | protected function outputOption( $message, $value, $attribs = null, $depth = 0 ) { |
182 | $msgObj = $this->msg( $message ); |
183 | $text = $msgObj->exists() ? $msgObj->text() : $message; |
184 | $attribs['value'] = $value; |
185 | if ( $value === $this->selected && !isset( $attribs['disabled'] ) ) { |
186 | $attribs['selected'] = 'selected'; |
187 | } |
188 | |
189 | $val = str_repeat( /*   */ "\u{00A0}", $depth * 2 ) . $text; |
190 | return str_repeat( "\t", $depth ) . Html::element( 'option', $attribs, $val ) . "\n"; |
191 | } |
192 | |
193 | /** |
194 | * Accessor for $this->lines |
195 | * |
196 | * @return array |
197 | */ |
198 | public function getLines() { |
199 | return $this->lines; |
200 | } |
201 | |
202 | /** |
203 | * Accessor for $this->lines |
204 | * |
205 | * @return array |
206 | * |
207 | * @deprecated since 1.31 Use getLines() instead |
208 | */ |
209 | public function getLicenses() { |
210 | return $this->getLines(); |
211 | } |
212 | |
213 | /** |
214 | * @inheritDoc |
215 | */ |
216 | public function getInputHTML( $value ) { |
217 | $this->selected = $value; |
218 | |
219 | // add a default "no license selected" option |
220 | $default = $this->buildLine( '|nolicense' ); |
221 | array_unshift( $this->lines, $default ); |
222 | |
223 | $html = $this->makeHtml( $this->getLines() ); |
224 | |
225 | $attribs = [ |
226 | 'name' => $this->mName, |
227 | 'id' => $this->mID |
228 | ]; |
229 | if ( !empty( $this->mParams['disabled'] ) ) { |
230 | $attribs['disabled'] = 'disabled'; |
231 | } |
232 | |
233 | $html = Html::rawElement( 'select', $attribs, $html ); |
234 | |
235 | // remove default "no license selected" from lines again |
236 | array_shift( $this->lines ); |
237 | |
238 | return $html; |
239 | } |
240 | } |