Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 157 |
|
0.00% |
0 / 11 |
CRAP | |
0.00% |
0 / 1 |
PFTextAreaInput | |
0.00% |
0 / 157 |
|
0.00% |
0 / 11 |
3192 | |
0.00% |
0 / 1 |
getName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultCargoTypes | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultCargoTypeLists | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
__construct | |
0.00% |
0 / 24 |
|
0.00% |
0 / 1 |
240 | |||
getDefaultPropTypes | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getOtherPropTypesHandled | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getOtherPropTypeListsHandled | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getParameters | |
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
2 | |||
getResourceModuleNames | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
getTextAreaAttributes | |
0.00% |
0 / 53 |
|
0.00% |
0 / 1 |
342 | |||
getHtmlText | |
0.00% |
0 / 29 |
|
0.00% |
0 / 1 |
156 |
1 | <?php |
2 | |
3 | /** |
4 | * @file |
5 | * @ingroup PF |
6 | */ |
7 | |
8 | /** |
9 | * @ingroup PFFormInput |
10 | */ |
11 | class PFTextAreaInput extends PFFormInput { |
12 | |
13 | protected $mEditor = null; |
14 | |
15 | public static function getName(): string { |
16 | return 'textarea'; |
17 | } |
18 | |
19 | public static function getDefaultCargoTypes() { |
20 | return [ |
21 | 'Text' => [], |
22 | 'Searchtext' => [] |
23 | ]; |
24 | } |
25 | |
26 | public static function getDefaultCargoTypeLists() { |
27 | return [ |
28 | 'Text' => [ 'field_type' => 'text', 'is_list' => 'true' ], |
29 | 'Searchtext' => [ 'field_type' => 'text', 'is_list' => 'true' ] |
30 | ]; |
31 | } |
32 | |
33 | /** |
34 | * @param string $input_number The number of the input in the form. For a simple HTML input |
35 | * element this should end up in the id attribute in the format 'input_<number>'. |
36 | * @param string $cur_value The current value of the input field. For a simple HTML input |
37 | * element this should end up in the value attribute. |
38 | * @param string $input_name The name of the input. For a simple HTML input element this should |
39 | * end up in the name attribute. |
40 | * @param bool $disabled Is this input disabled? |
41 | * @param array $other_args An associative array of other parameters that were present in the |
42 | * input definition. |
43 | */ |
44 | public function __construct( $input_number, $cur_value, $input_name, $disabled, array $other_args ) { |
45 | global $wgOut; |
46 | |
47 | parent::__construct( $input_number, $cur_value, $input_name, $disabled, $other_args ); |
48 | |
49 | $newClasses = null; |
50 | |
51 | // WikiEditor |
52 | if ( |
53 | array_key_exists( 'editor', $this->mOtherArgs ) && |
54 | $this->mOtherArgs['editor'] == 'wikieditor' && |
55 | in_array( 'ext.wikiEditor', $wgOut->getResourceLoader()->getModuleNames() ) |
56 | ) { |
57 | $this->mEditor = 'wikieditor'; |
58 | $this->addJsInitFunctionData( 'window.ext.wikieditor.init' ); |
59 | } |
60 | |
61 | // VisualEditor (plus VEForAll) |
62 | if ( |
63 | array_key_exists( 'editor', $this->mOtherArgs ) && |
64 | $this->mOtherArgs['editor'] == 'visualeditor' && |
65 | ExtensionRegistry::getInstance()->isLoaded( 'VisualEditor' ) |
66 | ) { |
67 | $this->mEditor = 'visualeditor'; |
68 | if ( $input_name != 'pf_free_text' && !array_key_exists( 'isSection', $this->mOtherArgs ) ) { |
69 | $newClasses = 'vePartOfTemplate'; |
70 | } |
71 | } |
72 | |
73 | // TinyMCE |
74 | if ( |
75 | array_key_exists( 'editor', $this->mOtherArgs ) && |
76 | $this->mOtherArgs['editor'] == 'tinymce' |
77 | ) { |
78 | $this->mEditor = 'tinymce'; |
79 | global $wgTinyMCEEnabled; |
80 | $wgTinyMCEEnabled = true; |
81 | $newClasses = 'mceMinimizeOnBlur'; |
82 | if ( $input_name != 'pf_free_text' && !array_key_exists( 'isSection', $this->mOtherArgs ) ) { |
83 | $newClasses .= ' mcePartOfTemplate'; |
84 | } |
85 | } |
86 | |
87 | if ( $newClasses == null ) { |
88 | // Do nothing. |
89 | } elseif ( array_key_exists( 'class', $this->mOtherArgs ) ) { |
90 | $this->mOtherArgs['class'] .= ' ' . $newClasses; |
91 | } else { |
92 | $this->mOtherArgs['class'] = $newClasses; |
93 | } |
94 | } |
95 | |
96 | public static function getDefaultPropTypes() { |
97 | return [ '_cod' => [] ]; |
98 | } |
99 | |
100 | public static function getOtherPropTypesHandled() { |
101 | return [ '_txt', '_wpg' ]; |
102 | } |
103 | |
104 | public static function getOtherPropTypeListsHandled() { |
105 | return [ '_txt', '_wpg' ]; |
106 | } |
107 | |
108 | public static function getParameters() { |
109 | $params = parent::getParameters(); |
110 | |
111 | $params['preload'] = [ |
112 | 'name' => 'preload', |
113 | 'type' => 'string', |
114 | 'description' => wfMessage( 'pf_forminputs_preload' )->text() |
115 | ]; |
116 | $params['rows'] = [ |
117 | 'name' => 'rows', |
118 | 'type' => 'int', |
119 | 'description' => wfMessage( 'pf_forminputs_rows' )->text() |
120 | ]; |
121 | $params['cols'] = [ |
122 | 'name' => 'cols', |
123 | 'type' => 'int', |
124 | 'description' => wfMessage( 'pf_forminputs_cols' )->text() |
125 | ]; |
126 | $params['maxlength'] = [ |
127 | 'name' => 'maxlength', |
128 | 'type' => 'int', |
129 | 'description' => wfMessage( 'pf_forminputs_maxlength' )->text() |
130 | ]; |
131 | $params['placeholder'] = [ |
132 | 'name' => 'placeholder', |
133 | 'type' => 'string', |
134 | 'description' => wfMessage( 'pf_forminputs_placeholder' )->text() |
135 | ]; |
136 | $params['autogrow'] = [ |
137 | 'name' => 'autogrow', |
138 | 'type' => 'boolean', |
139 | 'description' => wfMessage( 'pf_forminputs_autogrow' )->text() |
140 | ]; |
141 | return $params; |
142 | } |
143 | |
144 | /** |
145 | * Returns the names of the resource modules this input type uses. |
146 | * |
147 | * Returns the names of the modules as an array or - if there is only one |
148 | * module - as a string. |
149 | * |
150 | * @return null|string|array |
151 | */ |
152 | public function getResourceModuleNames() { |
153 | if ( $this->mEditor == 'wikieditor' ) { |
154 | return 'ext.pageforms.wikieditor'; |
155 | } elseif ( $this->mEditor == 'visualeditor' ) { |
156 | return 'ext.veforall.main'; |
157 | } elseif ( $this->mEditor == 'tinymce' ) { |
158 | return 'ext.tinymce'; |
159 | } else { |
160 | return null; |
161 | } |
162 | } |
163 | |
164 | protected function getTextAreaAttributes() { |
165 | global $wgPageFormsTabIndex, $wgPageFormsFieldNum; |
166 | |
167 | // Use a special ID for the free text field - |
168 | // this was originally done for FCKeditor, but maybe it's |
169 | // useful for other stuff too. |
170 | $input_id = $this->mInputName == 'pf_free_text' ? 'pf_free_text' : "input_$wgPageFormsFieldNum"; |
171 | |
172 | if ( $this->mEditor == 'wikieditor' ) { |
173 | global $wgOut; |
174 | $wgOut->addModuleStyles( 'ext.wikiEditor.styles' ); |
175 | $wgOut->addModules( 'ext.wikiEditor' ); |
176 | $className = 'wikieditor '; |
177 | } elseif ( $this->mEditor == 'visualeditor' ) { |
178 | $className = 'visualeditor '; |
179 | } elseif ( $this->mEditor == 'tinymce' ) { |
180 | $className = 'tinymce '; |
181 | } else { |
182 | $className = ''; |
183 | } |
184 | |
185 | $className .= ( $this->mIsMandatory ) ? 'mandatoryField' : 'createboxInput'; |
186 | if ( array_key_exists( 'unique', $this->mOtherArgs ) ) { |
187 | $className .= ' uniqueField'; |
188 | } |
189 | |
190 | if ( array_key_exists( 'class', $this->mOtherArgs ) ) { |
191 | $className .= ' ' . $this->mOtherArgs['class']; |
192 | } |
193 | |
194 | if ( array_key_exists( 'autogrow', $this->mOtherArgs ) ) { |
195 | $className .= ' autoGrow'; |
196 | } |
197 | |
198 | if ( array_key_exists( 'rows', $this->mOtherArgs ) ) { |
199 | $rows = $this->mOtherArgs['rows']; |
200 | } else { |
201 | $rows = 5; |
202 | } |
203 | |
204 | $textarea_attrs = [ |
205 | 'tabindex' => $wgPageFormsTabIndex, |
206 | 'name' => $this->mInputName, |
207 | 'id' => $input_id, |
208 | 'class' => $className, |
209 | 'rows' => $rows, |
210 | ]; |
211 | |
212 | if ( array_key_exists( 'cols', $this->mOtherArgs ) ) { |
213 | $textarea_attrs['cols'] = $this->mOtherArgs['cols']; |
214 | // Needed to prevent CSS from overriding the manually- |
215 | // set width. |
216 | $textarea_attrs['style'] = 'width: auto'; |
217 | } elseif ( array_key_exists( 'autogrow', $this->mOtherArgs ) ) { |
218 | // If 'autogrow' has been set, automatically set |
219 | // the number of columns - otherwise, the Javascript |
220 | // won't be able to know how many characters there |
221 | // are per line, and thus won't work. |
222 | $textarea_attrs['cols'] = 90; |
223 | $textarea_attrs['style'] = 'width: auto'; |
224 | } else { |
225 | $textarea_attrs['cols'] = 90; |
226 | $textarea_attrs['style'] = 'width: 100%'; |
227 | } |
228 | |
229 | if ( $this->mIsDisabled ) { |
230 | $textarea_attrs['disabled'] = 'disabled'; |
231 | } |
232 | |
233 | if ( array_key_exists( 'maxlength', $this->mOtherArgs ) ) { |
234 | $maxlength = $this->mOtherArgs['maxlength']; |
235 | // For every actual character pressed (i.e., excluding |
236 | // things like the Shift key), reduce the string to its |
237 | // allowed length if it's exceeded that. |
238 | // This JS code is complicated so that it'll work |
239 | // correctly in IE - IE moves the cursor to the end |
240 | // whenever this.value is reset, so we'll make sure to |
241 | // do that only when we need to. |
242 | $maxLengthJSCheck = "if (window.event && window.event.keyCode < 48 && window.event.keyCode != 13) return; if (this.value.length > $maxlength) { this.value = this.value.substring(0, $maxlength); }"; |
243 | $textarea_attrs['onKeyDown'] = $maxLengthJSCheck; |
244 | $textarea_attrs['onKeyUp'] = $maxLengthJSCheck; |
245 | } |
246 | |
247 | if ( array_key_exists( 'placeholder', $this->mOtherArgs ) ) { |
248 | $textarea_attrs['placeholder'] = $this->mOtherArgs['placeholder']; |
249 | } |
250 | if ( array_key_exists( 'autocapitalize', $this->mOtherArgs ) ) { |
251 | $textarea_attrs['autocapitalize'] = $this->mOtherArgs['autocapitalize']; |
252 | } |
253 | if ( array_key_exists( 'feeds to map', $this->mOtherArgs ) ) { |
254 | global $wgPageFormsMapsWithFeeders; |
255 | $targetMapName = $this->mOtherArgs['feeds to map']; |
256 | if ( array_key_exists( 'part_of_multiple', $this->mOtherArgs ) ) { |
257 | $targetMapName = str_replace( '[', '[num][', $targetMapName ); |
258 | } |
259 | $wgPageFormsMapsWithFeeders[$targetMapName] = true; |
260 | $textarea_attrs['data-feeds-to-map'] = $targetMapName; |
261 | } |
262 | |
263 | return $textarea_attrs; |
264 | } |
265 | |
266 | /** |
267 | * Returns the HTML code to be included in the output page for this input. |
268 | * @return string |
269 | */ |
270 | public function getHtmlText(): string { |
271 | $textarea_attrs = $this->getTextAreaAttributes(); |
272 | |
273 | $text = Html::element( 'textarea', $textarea_attrs, $this->mCurrentValue ); |
274 | $spanClass = 'inputSpan'; |
275 | if ( $this->mInputName == 'pf_free_text' ) { |
276 | $spanClass .= ' freeText'; |
277 | } |
278 | if ( array_key_exists( 'isSection', $this->mOtherArgs ) ) { |
279 | $spanClass .= ' pageSection'; |
280 | } |
281 | if ( $this->mIsMandatory ) { |
282 | $spanClass .= ' mandatoryFieldSpan'; |
283 | } |
284 | if ( array_key_exists( 'unique', $this->mOtherArgs ) ) { |
285 | $spanClass .= ' uniqueFieldSpan'; |
286 | } |
287 | if ( $this->mEditor == 'visualeditor' && !$this->mIsDisabled ) { |
288 | $spanClass .= ' ve-area-wrapper'; |
289 | } |
290 | $spanAttrs = [ 'class' => $spanClass ]; |
291 | if ( $this->mEditor == 'visualeditor' ) { |
292 | // VisualEditor, by default, autogrows with no limit - |
293 | // which is fine in a regular edit page, but not good |
294 | // in a form. So we add a "max height" value, which in |
295 | // turn gets processed by VEForAll into true CSS. |
296 | $maxHeightNumOnly = true; |
297 | if ( array_key_exists( 'max height', $this->mOtherArgs ) ) { |
298 | $maxHeightStr = $this->mOtherArgs['max height']; |
299 | if ( substr( $maxHeightStr, -2 ) == 'em' || substr( $maxHeightStr, -2 ) == 'vh' ) { |
300 | $maxHeightNumOnly = false; |
301 | $maxHeight = $maxHeightStr; |
302 | } else { |
303 | $maxHeight = (int)$maxHeightStr; |
304 | } |
305 | } else { |
306 | $config = RequestContext::getMain()->getConfig(); |
307 | $maxHeight = $config->get( 'PageFormsVisualEditorMaxHeight' ); |
308 | } |
309 | if ( $maxHeightNumOnly ) { |
310 | $spanAttrs['data-max-height'] = $maxHeight . 'px'; |
311 | } else { |
312 | $spanAttrs['data-max-height'] = $maxHeight; |
313 | } |
314 | } |
315 | |
316 | $text = Html::rawElement( 'span', $spanAttrs, $text ); |
317 | |
318 | return $text; |
319 | } |
320 | |
321 | } |