Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 66 |
|
0.00% |
0 / 7 |
CRAP | |
0.00% |
0 / 1 |
HTMLUsersMultiselectField | |
0.00% |
0 / 65 |
|
0.00% |
0 / 7 |
756 | |
0.00% |
0 / 1 |
loadDataFromRequest | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
30 | |||
validate | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
56 | |||
getInputHTML | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getInputOOUI | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
132 | |||
getInputWidget | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
shouldInfuseOOUI | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getOOUIModules | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\HTMLForm\Field; |
4 | |
5 | use MediaWiki\MediaWikiServices; |
6 | use MediaWiki\User\UserRigorOptions; |
7 | use MediaWiki\Widget\UsersMultiselectWidget; |
8 | use Wikimedia\IPUtils; |
9 | |
10 | /** |
11 | * Implements a tag multiselect input field for user names. |
12 | * |
13 | * Besides the parameters recognized by HTMLUserTextField, additional recognized |
14 | * parameters are: |
15 | * default - (optional) String, newline-separated list of usernames to use as preset data |
16 | * placeholder - (optional) Custom placeholder message for input |
17 | * |
18 | * The result is the array of usernames |
19 | * |
20 | * @stable to extend |
21 | * @note This widget is not likely to remain functional in non-OOUI forms. |
22 | */ |
23 | class HTMLUsersMultiselectField extends HTMLUserTextField { |
24 | public function loadDataFromRequest( $request ) { |
25 | $value = $request->getText( $this->mName, $this->getDefault() ?? '' ); |
26 | |
27 | $usersArray = explode( "\n", $value ); |
28 | // Remove empty lines |
29 | $usersArray = array_values( array_filter( $usersArray, static function ( $username ) { |
30 | return trim( $username ) !== ''; |
31 | } ) ); |
32 | |
33 | // Normalize usernames |
34 | $normalizedUsers = []; |
35 | $userNameUtils = MediaWikiServices::getInstance()->getUserNameUtils(); |
36 | $listOfIps = []; |
37 | foreach ( $usersArray as $user ) { |
38 | $canonicalUser = false; |
39 | if ( IPUtils::isIPAddress( $user ) ) { |
40 | $parsedIPRange = IPUtils::parseRange( $user ); |
41 | if ( !in_array( $parsedIPRange, $listOfIps ) ) { |
42 | $canonicalUser = IPUtils::sanitizeRange( $user ); |
43 | $listOfIps[] = $parsedIPRange; |
44 | } |
45 | } else { |
46 | $canonicalUser = $userNameUtils->getCanonical( |
47 | $user, UserRigorOptions::RIGOR_NONE ); |
48 | } |
49 | if ( $canonicalUser !== false ) { |
50 | $normalizedUsers[] = $canonicalUser; |
51 | } |
52 | } |
53 | // Remove any duplicate usernames |
54 | $uniqueUsers = array_unique( $normalizedUsers ); |
55 | |
56 | // This function is expected to return a string |
57 | return implode( "\n", $uniqueUsers ); |
58 | } |
59 | |
60 | public function validate( $value, $alldata ) { |
61 | if ( !$this->mParams['exists'] ) { |
62 | return true; |
63 | } |
64 | |
65 | if ( $value === null ) { |
66 | return false; |
67 | } |
68 | |
69 | // $value is a string, because HTMLForm fields store their values as strings |
70 | $usersArray = explode( "\n", $value ); |
71 | |
72 | if ( isset( $this->mParams['max'] ) && ( count( $usersArray ) > $this->mParams['max'] ) ) { |
73 | return $this->msg( 'htmlform-multiselect-toomany', $this->mParams['max'] ); |
74 | } |
75 | |
76 | foreach ( $usersArray as $username ) { |
77 | $result = parent::validate( $username, $alldata ); |
78 | if ( $result !== true ) { |
79 | return $result; |
80 | } |
81 | } |
82 | |
83 | return true; |
84 | } |
85 | |
86 | public function getInputHTML( $value ) { |
87 | $this->mParent->getOutput()->enableOOUI(); |
88 | return $this->getInputOOUI( $value ); |
89 | } |
90 | |
91 | public function getInputOOUI( $value ) { |
92 | $this->mParent->getOutput()->addModuleStyles( 'mediawiki.widgets.TagMultiselectWidget.styles' ); |
93 | |
94 | $params = [ 'name' => $this->mName ]; |
95 | |
96 | if ( isset( $this->mParams['id'] ) ) { |
97 | $params['id'] = $this->mParams['id']; |
98 | } |
99 | |
100 | if ( isset( $this->mParams['disabled'] ) ) { |
101 | $params['disabled'] = $this->mParams['disabled']; |
102 | } |
103 | |
104 | if ( isset( $this->mParams['default'] ) ) { |
105 | $params['default'] = $this->mParams['default']; |
106 | } |
107 | |
108 | $params['placeholder'] = $this->mParams['placeholder'] ?? |
109 | $this->msg( 'mw-widgets-usersmultiselect-placeholder' )->plain(); |
110 | |
111 | if ( isset( $this->mParams['max'] ) ) { |
112 | $params['tagLimit'] = $this->mParams['max']; |
113 | } |
114 | |
115 | if ( isset( $this->mParams['ipallowed'] ) ) { |
116 | $params['ipAllowed'] = $this->mParams['ipallowed']; |
117 | } |
118 | |
119 | if ( isset( $this->mParams['iprange'] ) ) { |
120 | $params['ipRangeAllowed'] = $this->mParams['iprange']; |
121 | } |
122 | |
123 | if ( isset( $this->mParams['iprangelimits'] ) ) { |
124 | $params['ipRangeLimits'] = $this->mParams['iprangelimits']; |
125 | } |
126 | |
127 | if ( isset( $this->mParams['input'] ) ) { |
128 | $params['input'] = $this->mParams['input']; |
129 | } |
130 | |
131 | if ( $value !== null ) { |
132 | // $value is a string, but the widget expects an array |
133 | $params['default'] = $value === '' ? [] : explode( "\n", $value ); |
134 | } |
135 | |
136 | // Make the field auto-infusable when it's used inside a legacy HTMLForm rather than OOUIHTMLForm |
137 | $params['infusable'] = true; |
138 | $params['classes'] = [ 'mw-htmlform-autoinfuse' ]; |
139 | |
140 | return $this->getInputWidget( $params ); |
141 | } |
142 | |
143 | /** |
144 | * @inheritDoc |
145 | */ |
146 | protected function getInputWidget( $params ) { |
147 | $widget = new UsersMultiselectWidget( $params ); |
148 | $widget->setAttributes( [ 'data-mw-modules' => implode( ',', $this->getOOUIModules() ) ] ); |
149 | return $widget; |
150 | } |
151 | |
152 | protected function shouldInfuseOOUI() { |
153 | return true; |
154 | } |
155 | |
156 | protected function getOOUIModules() { |
157 | return [ 'mediawiki.widgets.UsersMultiselectWidget' ]; |
158 | } |
159 | |
160 | } |
161 | |
162 | /** @deprecated class alias since 1.42 */ |
163 | class_alias( HTMLUsersMultiselectField::class, 'HTMLUsersMultiselectField' ); |