MediaWiki master
HTMLUserTextField.php
Go to the documentation of this file.
1<?php
2
4
10use Wikimedia\IPUtils;
11
35 public function __construct( $params ) {
36 $params = ArrayUtils::arrayPlus2d( $params, [
37 'exists' => false,
38 'external' => false,
39 'ipallowed' => false,
40 'usemodwiki-ipallowed' => false,
41 'iprange' => false,
42 'iprangelimits' => [
43 'IPv4' => 0,
44 'IPv6' => 0,
45 ],
46 'excludenamed' => false,
47 'excludetemp' => false,
48 ]
49 );
50
51 parent::__construct( $params );
52 }
53
55 public function validate( $value, $alldata ) {
56 // If the value is null, reset it to an empty string which is what is expected by the parent.
57 $value ??= '';
58
59 // If the value is empty, there are no additional checks that can be performed.
60 if ( $value === '' ) {
61 return parent::validate( $value, $alldata );
62 }
63
64 // check if the input is a valid username
65 $user = MediaWikiServices::getInstance()->getUserFactory()->newFromName( $value );
66 if ( $user ) {
67 // check if the user exists, if requested
68 if ( $this->mParams['exists'] && !(
69 $user->isRegistered() &&
70 // Treat hidden users as unregistered if current user can't view them (T309894)
71 !( $user->isHidden() && !( $this->mParent && $this->mParent->getUser()->isAllowed( 'hideuser' ) ) )
72 ) ) {
73 return $this->msg( 'htmlform-user-not-exists', wfEscapeWikiText( $user->getName() ) );
74 }
75
76 // check if the user account type matches the account type filter
77 $excludeNamed = $this->mParams['excludenamed'] ?? null;
78 $excludeTemp = $this->mParams['excludetemp'] ?? null;
79 if ( ( $excludeTemp && $user->isTemp() ) || ( $excludeNamed && $user->isNamed() ) ) {
80 return $this->msg( 'htmlform-user-not-valid', wfEscapeWikiText( $user->getName() ) );
81 }
82 } else {
83 // not a valid username
84 $valid = false;
85 // check if the input is a valid external user
86 if ( $this->mParams['external'] && ExternalUserNames::isExternal( $value ) ) {
87 $valid = true;
88 }
89 // check if the input is a valid IP address, optionally also checking for usemod wiki IPs
90 if ( $this->mParams['ipallowed'] ) {
91 $b = IPUtils::RE_IP_BYTE;
92 if ( IPUtils::isValid( $value ) ) {
93 $valid = true;
94 } elseif ( $this->mParams['usemodwiki-ipallowed'] && preg_match( "/^$b\.$b\.$b\.xxx$/", $value ) ) {
95 $valid = true;
96 }
97 }
98 // check if the input is a valid IP range
99 if ( $this->mParams['iprange'] ) {
100 $rangeError = $this->isValidIPRange( $value );
101 if ( $rangeError === true ) {
102 $valid = true;
103 } elseif ( $rangeError !== false ) {
104 return $rangeError;
105 }
106 }
107 if ( !$valid ) {
108 return $this->msg( 'htmlform-user-not-valid', wfEscapeWikiText( $value ) );
109 }
110 }
111
112 return parent::validate( $value, $alldata );
113 }
114
119 protected function isValidIPRange( $value ) {
120 $cidrIPRanges = $this->mParams['iprangelimits'];
121
122 if ( !IPUtils::isValidRange( $value ) ) {
123 return false;
124 }
125
126 [ $ip, $range ] = explode( '/', $value, 2 );
127
128 if (
129 ( IPUtils::isIPv4( $ip ) && $cidrIPRanges['IPv4'] == 32 ) ||
130 ( IPUtils::isIPv6( $ip ) && $cidrIPRanges['IPv6'] == 128 )
131 ) {
132 // Range block effectively disabled
133 return $this->msg( 'ip_range_toolow' );
134 }
135
136 if (
137 ( IPUtils::isIPv4( $ip ) && $range > 32 ) ||
138 ( IPUtils::isIPv6( $ip ) && $range > 128 )
139 ) {
140 // Dodgy range
141 return $this->msg( 'ip_range_invalid' );
142 }
143
144 if ( IPUtils::isIPv4( $ip ) && $range < $cidrIPRanges['IPv4'] ) {
145 return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv4'] );
146 }
147
148 if ( IPUtils::isIPv6( $ip ) && $range < $cidrIPRanges['IPv6'] ) {
149 return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv6'] );
150 }
151
152 return true;
153 }
154
156 protected function getInputWidget( $params ) {
157 if ( isset( $this->mParams['excludenamed'] ) ) {
158 $params['excludenamed'] = $this->mParams['excludenamed'];
159 }
160
161 if ( isset( $this->mParams['excludetemp'] ) ) {
162 $params['excludetemp'] = $this->mParams['excludetemp'];
163 }
164
165 return new UserInputWidget( $params );
166 }
167
169 protected function shouldInfuseOOUI() {
170 return true;
171 }
172
174 protected function getOOUIModules() {
175 return [ 'mediawiki.widgets.UserInputWidget' ];
176 }
177
179 public function getInputHtml( $value ) {
180 // add the required module and css class for user suggestions in non-OOUI mode
181 $this->mParent->getOutput()->addModules( 'mediawiki.userSuggest' );
182 $this->mClass .= ' mw-autocomplete-user';
183
184 // return parent html
185 return parent::getInputHTML( $value );
186 }
187}
188
190class_alias( HTMLUserTextField::class, 'HTMLUserTextField' );
wfEscapeWikiText( $input)
Escapes the given text so that it may be output using addWikiText() without any linking,...
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.
A collection of static methods to play with arrays.