Added a separate error message for mkdir failures
[lhc/web/wiklou.git] / includes / htmlform / HTMLAutoCompleteSelectField.php
1 <?php
2
3 /**
4 * Text field for selecting a value from a large list of possible values, with
5 * auto-completion and optionally with a select dropdown for selecting common
6 * options.
7 *
8 * HTMLComboboxField implements most of the same functionality and should be
9 * used instead, if possible.
10 *
11 * If one of 'options-messages', 'options', or 'options-message' is provided
12 * and non-empty, the select dropdown will be shown. An 'other' key will be
13 * appended using message 'htmlform-selectorother-other' if not already
14 * present.
15 *
16 * Besides the parameters recognized by HTMLTextField, the following are
17 * recognized:
18 * options-messages - As for HTMLSelectField
19 * options - As for HTMLSelectField
20 * options-message - As for HTMLSelectField
21 * autocomplete - Associative array mapping display text to values.
22 * autocomplete-messages - Like autocomplete, but keys are message names.
23 * require-match - Boolean, if true the value must be in the options or the
24 * autocomplete.
25 * other-message - Message to use instead of htmlform-selectorother-other for
26 * the 'other' message.
27 * other - Raw text to use for the 'other' message
28 */
29 class HTMLAutoCompleteSelectField extends HTMLTextField {
30 protected $autocomplete = array();
31
32 function __construct( $params ) {
33 $params += array(
34 'require-match' => false,
35 );
36
37 parent::__construct( $params );
38
39 if ( array_key_exists( 'autocomplete-messages', $this->mParams ) ) {
40 foreach ( $this->mParams['autocomplete-messages'] as $key => $value ) {
41 $key = $this->msg( $key )->plain();
42 $this->autocomplete[$key] = strval( $value );
43 }
44 } elseif ( array_key_exists( 'autocomplete', $this->mParams ) ) {
45 foreach ( $this->mParams['autocomplete'] as $key => $value ) {
46 $this->autocomplete[$key] = strval( $value );
47 }
48 }
49 if ( !is_array( $this->autocomplete ) || !$this->autocomplete ) {
50 throw new MWException( 'HTMLAutoCompleteSelectField called without any autocompletions' );
51 }
52
53 $this->getOptions();
54 if ( $this->mOptions && !in_array( 'other', $this->mOptions, true ) ) {
55 if ( isset( $params['other-message'] ) ) {
56 $msg = wfMessage( $params['other-message'] )->text();
57 } elseif ( isset( $params['other'] ) ) {
58 $msg = $params['other'];
59 } else {
60 $msg = wfMessage( 'htmlform-selectorother-other' )->text();
61 }
62 $this->mOptions[$msg] = 'other';
63 }
64 }
65
66 function loadDataFromRequest( $request ) {
67 if ( $request->getCheck( $this->mName ) ) {
68 $val = $request->getText( $this->mName . '-select', 'other' );
69
70 if ( $val === 'other' ) {
71 $val = $request->getText( $this->mName );
72 if ( isset( $this->autocomplete[$val] ) ) {
73 $val = $this->autocomplete[$val];
74 }
75 }
76
77 return $val;
78 } else {
79 return $this->getDefault();
80 }
81 }
82
83 function validate( $value, $alldata ) {
84 $p = parent::validate( $value, $alldata );
85
86 if ( $p !== true ) {
87 return $p;
88 }
89
90 $validOptions = HTMLFormField::flattenOptions( $this->getOptions() );
91
92 if ( in_array( strval( $value ), $validOptions, true ) ) {
93 return true;
94 } elseif ( in_array( strval( $value ), $this->autocomplete, true ) ) {
95 return true;
96 } elseif ( $this->mParams['require-match'] ) {
97 return $this->msg( 'htmlform-select-badoption' )->parse();
98 }
99
100 return true;
101 }
102
103 // FIXME Ewww, this shouldn't be adding any attributes not requested in $list :(
104 public function getAttributes( array $list, array $mappings = null ) {
105 $attribs = array(
106 'type' => 'text',
107 'data-autocomplete' => FormatJson::encode( array_keys( $this->autocomplete ) ),
108 ) + parent::getAttributes( $list, $mappings );
109
110 if ( $this->getOptions() ) {
111 $attribs['data-hide-if'] = FormatJson::encode(
112 array( '!==', $this->mName . '-select', 'other' )
113 );
114 }
115
116 return $attribs;
117 }
118
119 function getInputHTML( $value ) {
120 $oldClass = $this->mClass;
121 $this->mClass = (array)$this->mClass;
122
123 $valInSelect = false;
124 $ret = '';
125
126 if ( $this->getOptions() ) {
127 if ( $value !== false ) {
128 $value = strval( $value );
129 $valInSelect = in_array(
130 $value, HTMLFormField::flattenOptions( $this->getOptions() ), true
131 );
132 }
133
134 $selected = $valInSelect ? $value : 'other';
135 $select = new XmlSelect( $this->mName . '-select', $this->mID . '-select', $selected );
136 $select->addOptions( $this->getOptions() );
137 $select->setAttribute( 'class', 'mw-htmlform-select-or-other' );
138
139 if ( !empty( $this->mParams['disabled'] ) ) {
140 $select->setAttribute( 'disabled', 'disabled' );
141 }
142
143 if ( isset( $this->mParams['tabindex'] ) ) {
144 $select->setAttribute( 'tabindex', $this->mParams['tabindex'] );
145 }
146
147 $ret = $select->getHTML() . "<br />\n";
148
149 $this->mClass[] = 'mw-htmlform-hide-if';
150 }
151
152 if ( $valInSelect ) {
153 $value = '';
154 } else {
155 $key = array_search( strval( $value ), $this->autocomplete, true );
156 if ( $key !== false ) {
157 $value = $key;
158 }
159 }
160
161 $this->mClass[] = 'mw-htmlform-autocomplete';
162 $ret .= parent::getInputHTML( $valInSelect ? '' : $value );
163 $this->mClass = $oldClass;
164
165 return $ret;
166 }
167
168 /**
169 * Get the OOUI version of this input.
170 * @param string $value
171 * @return false
172 */
173 function getInputOOUI( $value ) {
174 // To be implemented, for now override the function from HTMLTextField
175 return false;
176 }
177 }