Merge "FauxRequest: don’t override getValues()"
[lhc/web/wiklou.git] / includes / htmlform / fields / HTMLUserTextField.php
1 <?php
2
3 use MediaWiki\Widget\UserInputWidget;
4
5 /**
6 * Implements a text input field for user names.
7 * Automatically auto-completes if using the OOUI display format.
8 *
9 * Optional parameters:
10 * 'exists' - Whether to validate that the user already exists
11 * 'ipallowed' - Whether an IP adress is interpreted as "valid"
12 * 'iprange' - Whether an IP adress range is interpreted as "valid"
13 * 'iprangelimits' - Specifies the valid IP ranges for IPv4 and IPv6 in an array.
14 * defaults to IPv4 => 16; IPv6 => 32.
15 *
16 * @since 1.26
17 */
18 class HTMLUserTextField extends HTMLTextField {
19 public function __construct( $params ) {
20 $params = wfArrayPlus2d( $params, [
21 'exists' => false,
22 'ipallowed' => false,
23 'iprange' => false,
24 'iprangelimits' => [
25 'IPv4' => '16',
26 'IPv6' => '32',
27 ],
28 ]
29 );
30
31 parent::__construct( $params );
32 }
33
34 public function validate( $value, $alldata ) {
35 // Default value (from getDefault()) is null, User::newFromName() expects a string
36 if ( $value === null ) {
37 $value = '';
38 }
39
40 // check, if a user exists with the given username
41 $user = User::newFromName( $value, false );
42 $rangeError = null;
43
44 if ( !$user ) {
45 return $this->msg( 'htmlform-user-not-valid', $value );
46 } elseif (
47 // check, if the user exists, if requested
48 ( $this->mParams['exists'] && $user->getId() === 0 ) &&
49 // check, if the username is a valid IP address, otherwise save the error message
50 !( $this->mParams['ipallowed'] && IP::isValid( $value ) ) &&
51 // check, if the username is a valid IP range, otherwise save the error message
52 !( $this->mParams['iprange'] && ( $rangeError = $this->isValidIPRange( $value ) ) === true )
53 ) {
54 if ( is_string( $rangeError ) ) {
55 return $rangeError;
56 }
57 return $this->msg( 'htmlform-user-not-exists', $user->getName() );
58 }
59
60 return parent::validate( $value, $alldata );
61 }
62
63 protected function isValidIPRange( $value ) {
64 $cidrIPRanges = $this->mParams['iprangelimits'];
65
66 if ( !IP::isValidRange( $value ) ) {
67 return false;
68 }
69
70 list( $ip, $range ) = explode( '/', $value, 2 );
71
72 if (
73 ( IP::isIPv4( $ip ) && $cidrIPRanges['IPv4'] == 32 ) ||
74 ( IP::isIPv6( $ip ) && $cidrIPRanges['IPv6'] == 128 )
75 ) {
76 // Range block effectively disabled
77 return $this->msg( 'ip_range_toolow' )->parse();
78 }
79
80 if (
81 ( IP::isIPv4( $ip ) && $range > 32 ) ||
82 ( IP::isIPv6( $ip ) && $range > 128 )
83 ) {
84 // Dodgy range
85 return $this->msg( 'ip_range_invalid' )->parse();
86 }
87
88 if ( IP::isIPv4( $ip ) && $range < $cidrIPRanges['IPv4'] ) {
89 return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv4'] )->parse();
90 }
91
92 if ( IP::isIPv6( $ip ) && $range < $cidrIPRanges['IPv6'] ) {
93 return $this->msg( 'ip_range_exceeded', $cidrIPRanges['IPv6'] )->parse();
94 }
95
96 return true;
97 }
98
99 protected function getInputWidget( $params ) {
100 return new UserInputWidget( $params );
101 }
102
103 protected function shouldInfuseOOUI() {
104 return true;
105 }
106
107 protected function getOOUIModules() {
108 return [ 'mediawiki.widgets.UserInputWidget' ];
109 }
110
111 public function getInputHtml( $value ) {
112 // add the required module and css class for user suggestions in non-OOUI mode
113 $this->mParent->getOutput()->addModules( 'mediawiki.userSuggest' );
114 $this->mClass .= ' mw-autocomplete-user';
115
116 // return parent html
117 return parent::getInputHTML( $value );
118 }
119 }