MediaWiki master
HTMLUserTextField.php
Go to the documentation of this file.
1<?php
2
4
9use Wikimedia\IPUtils;
10
34 public function __construct( $params ) {
35 $params = wfArrayPlus2d( $params, [
36 'exists' => false,
37 'external' => false,
38 'ipallowed' => false,
39 'usemodwiki-ipallowed' => false,
40 'iprange' => false,
41 'iprangelimits' => [
42 'IPv4' => 0,
43 'IPv6' => 0,
44 ],
45 'excludenamed' => false,
46 'excludetemp' => false,
47 ]
48 );
49
50 parent::__construct( $params );
51 }
52
54 public function validate( $value, $alldata ) {
55 // If the value is null, reset it to an empty string which is what is expected by the parent.
56 $value ??= '';
57
58 // If the value is empty, there are no additional checks that can be performed.
59 if ( $value === '' ) {
60 return parent::validate( $value, $alldata );
61 }
62
63 // check if the input is a valid username
64 $user = MediaWikiServices::getInstance()->getUserFactory()->newFromName( $value );
65 if ( $user ) {
66 // check if the user exists, if requested
67 if ( $this->mParams['exists'] && !(
68 $user->isRegistered() &&
69 // Treat hidden users as unregistered if current user can't view them (T309894)
70 !( $user->isHidden() && !( $this->mParent && $this->mParent->getUser()->isAllowed( 'hideuser' ) ) )
71 ) ) {
72 return $this->msg( 'htmlform-user-not-exists', wfEscapeWikiText( $user->getName() ) );
73 }
74
75 // check if the user account type matches the account type filter
76 $excludeNamed = $this->mParams['excludenamed'] ?? null;
77 $excludeTemp = $this->mParams['excludetemp'] ?? null;
78 if ( ( $excludeTemp && $user->isTemp() ) || ( $excludeNamed && $user->isNamed() ) ) {
79 return $this->msg( 'htmlform-user-not-valid', wfEscapeWikiText( $user->getName() ) );
80 }
81 } else {
82 // not a valid username
83 $valid = false;
84 // check if the input is a valid external user
85 if ( $this->mParams['external'] && ExternalUserNames::isExternal( $value ) ) {
86 $valid = true;
87 }
88 // check if the input is a valid IP address, optionally also checking for usemod wiki IPs
89 if ( $this->mParams['ipallowed'] ) {
90 $b = IPUtils::RE_IP_BYTE;
91 if ( IPUtils::isValid( $value ) ) {
92 $valid = true;
93 } elseif ( $this->mParams['usemodwiki-ipallowed'] && preg_match( "/^$b\.$b\.$b\.xxx$/", $value ) ) {
94 $valid = true;
95 }
96 }
97 // check if the input is a valid IP range
98 if ( $this->mParams['iprange'] ) {
99 $rangeError = $this->isValidIPRange( $value );
100 if ( $rangeError === true ) {
101 $valid = true;
102 } elseif ( $rangeError !== false ) {
103 return $rangeError;
104 }
105 }
106 if ( !$valid ) {
107 return $this->msg( 'htmlform-user-not-valid', wfEscapeWikiText( $value ) );
108 }
109 }
110
111 return parent::validate( $value, $alldata );
112 }
113
118 protected function isValidIPRange( $value ) {
119 $cidrIPRanges = $this->mParams['iprangelimits'];
120
121 if ( !IPUtils::isValidRange( $value ) ) {
122 return false;
123 }
124
125 [ $ip, $range ] = explode( '/', $value, 2 );
126
127 if (
128 ( IPUtils::isIPv4( $ip ) && $cidrIPRanges['IPv4'] == 32 ) ||
129 ( IPUtils::isIPv6( $ip ) && $cidrIPRanges['IPv6'] == 128 )
130 ) {
131 // Range block effectively disabled
132 return $this->msg( 'ip_range_toolow' );
133 }
134
135 if (
136 ( IPUtils::isIPv4( $ip ) && $range > 32 ) ||
137 ( IPUtils::isIPv6( $ip ) && $range > 128 )
138 ) {
139 // Dodgy range
140 return $this->msg( 'ip_range_invalid' );
141 }
142
143 if ( IPUtils::isIPv4( $ip ) && $range < $cidrIPRanges['IPv4'] ) {
144 return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv4'] );
145 }
146
147 if ( IPUtils::isIPv6( $ip ) && $range < $cidrIPRanges['IPv6'] ) {
148 return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv6'] );
149 }
150
151 return true;
152 }
153
155 protected function getInputWidget( $params ) {
156 if ( isset( $this->mParams['excludenamed'] ) ) {
157 $params['excludenamed'] = $this->mParams['excludenamed'];
158 }
159
160 if ( isset( $this->mParams['excludetemp'] ) ) {
161 $params['excludetemp'] = $this->mParams['excludetemp'];
162 }
163
164 return new UserInputWidget( $params );
165 }
166
168 protected function shouldInfuseOOUI() {
169 return true;
170 }
171
173 protected function getOOUIModules() {
174 return [ 'mediawiki.widgets.UserInputWidget' ];
175 }
176
178 public function getInputHtml( $value ) {
179 // add the required module and css class for user suggestions in non-OOUI mode
180 $this->mParent->getOutput()->addModules( 'mediawiki.userSuggest' );
181 $this->mClass .= ' mw-autocomplete-user';
182
183 // return parent html
184 return parent::getInputHTML( $value );
185 }
186}
187
189class_alias( HTMLUserTextField::class, 'HTMLUserTextField' );
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
wfArrayPlus2d(array $baseArray, array $newValues)
Merges two (possibly) 2 dimensional arrays into the target array ($baseArray).
Implements a text input field for user names.
validate( $value, $alldata)
Override this function to add specific validation checks on the field input.Don't forget to call pare...
shouldInfuseOOUI()
Whether the field should be automatically infused.Note that all OOUI HTMLForm fields are infusable (y...
getOOUIModules()
Get the list of extra ResourceLoader modules which must be loaded client-side before it's possible to...
msg( $key,... $params)
Get a translated interface message.
Service locator for MediaWiki core services.
static getInstance()
Returns the global default instance of the top level service locator.
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition Message.php:144
Class to parse and build external user names.