Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 493 |
|
0.00% |
0 / 35 |
CRAP | |
0.00% |
0 / 1 |
PFFormField | |
0.00% |
0 / 493 |
|
0.00% |
0 / 35 |
61256 | |
0.00% |
0 / 1 |
create | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
getTemplateField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setTemplateField | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getInputType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setInputType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
hasFieldArg | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFieldArgs | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFieldArg | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setFieldArg | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDefaultValue | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isMandatory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setIsMandatory | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isHidden | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setIsHidden | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isRestricted | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setIsRestricted | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
holdsTemplate | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isList | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getPossibleValues | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getUseDisplayTitle | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getInputName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getLabel | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getLabelMsg | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
isDisabled | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setDescriptionArg | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
newFromFormFieldTag | |
0.00% |
0 / 175 |
|
0.00% |
0 / 1 |
4970 | |||
setPossibleValues | |
0.00% |
0 / 27 |
|
0.00% |
0 / 1 |
240 | |||
cleanupTranslateTags | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
56 | |||
getCurrentValue | |
0.00% |
0 / 68 |
|
0.00% |
0 / 1 |
1640 | |||
valueStringToLabels | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
110 | |||
additionalHTMLForInput | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
342 | |||
createMarkup | |
0.00% |
0 / 63 |
|
0.00% |
0 / 1 |
992 | |||
getArgumentsForInputCallSMW | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
56 | |||
getArgumentsForInputCallCargo | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
156 | |||
getArgumentsForInputCall | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
132 |
1 | <?php |
2 | /** |
3 | * |
4 | * @file |
5 | * @ingroup PF |
6 | */ |
7 | |
8 | use MediaWiki\MediaWikiServices; |
9 | |
10 | /** |
11 | * This class is distinct from PFTemplateField in that it represents a template |
12 | * field defined in a form definition - it contains an PFTemplateField object |
13 | * within it (the $template_field variable), along with the other properties |
14 | * for that field that are set within the form. |
15 | * @ingroup PF |
16 | */ |
17 | class PFFormField { |
18 | |
19 | /** |
20 | * @var PFTemplateField |
21 | */ |
22 | public $template_field; |
23 | /** |
24 | * @var array |
25 | */ |
26 | public static $mappedValuesCache = []; |
27 | private $mInputType; |
28 | private $mIsMandatory; |
29 | private $mIsHidden; |
30 | private $mIsRestricted; |
31 | private $mPossibleValues; |
32 | private $mUseDisplayTitle; |
33 | private $mIsList; |
34 | /** |
35 | * The following fields are not set by the form-creation page |
36 | * (though they could be). |
37 | */ |
38 | private $mDefaultValue; |
39 | private $mPreloadPage; |
40 | private $mHoldsTemplate; |
41 | private $mIsUploadable; |
42 | private $mFieldArgs; |
43 | private $mDescriptionArgs; |
44 | private $mLabel; |
45 | private $mLabelMsg; |
46 | /** |
47 | * somewhat of a hack - these two fields are for a field in a specific |
48 | * representation of a form, not the form definition; ideally these |
49 | * should be contained in a third 'field' class, called something like |
50 | * PFFormInstanceField, which holds these fields plus an instance of |
51 | * PFFormField. Too much work? |
52 | */ |
53 | private $mInputName; |
54 | private $mIsDisabled; |
55 | |
56 | /** |
57 | * @param PFTemplateField $template_field |
58 | * |
59 | * @return self |
60 | */ |
61 | static function create( PFTemplateField $template_field ) { |
62 | $f = new PFFormField(); |
63 | $f->template_field = $template_field; |
64 | $f->mInputType = null; |
65 | $f->mIsMandatory = false; |
66 | $f->mIsHidden = false; |
67 | $f->mIsRestricted = false; |
68 | $f->mIsUploadable = false; |
69 | $f->mPossibleValues = null; |
70 | $f->mUseDisplayTitle = false; |
71 | $f->mFieldArgs = []; |
72 | $f->mDescriptionArgs = []; |
73 | return $f; |
74 | } |
75 | |
76 | /** |
77 | * @return PFTemplateField |
78 | */ |
79 | public function getTemplateField() { |
80 | return $this->template_field; |
81 | } |
82 | |
83 | /** |
84 | * @param PFTemplateField $templateField |
85 | */ |
86 | public function setTemplateField( $templateField ) { |
87 | $this->template_field = $templateField; |
88 | } |
89 | |
90 | public function getInputType() { |
91 | return $this->mInputType; |
92 | } |
93 | |
94 | public function setInputType( $inputType ) { |
95 | $this->mInputType = $inputType; |
96 | } |
97 | |
98 | public function hasFieldArg( $key ) { |
99 | return array_key_exists( $key, $this->mFieldArgs ); |
100 | } |
101 | |
102 | public function getFieldArgs() { |
103 | return $this->mFieldArgs; |
104 | } |
105 | |
106 | public function getFieldArg( $key ) { |
107 | return $this->mFieldArgs[$key]; |
108 | } |
109 | |
110 | public function setFieldArg( $key, $value ) { |
111 | $this->mFieldArgs[$key] = $value; |
112 | } |
113 | |
114 | public function getDefaultValue() { |
115 | return $this->mDefaultValue; |
116 | } |
117 | |
118 | public function isMandatory() { |
119 | return $this->mIsMandatory; |
120 | } |
121 | |
122 | public function setIsMandatory( $isMandatory ) { |
123 | $this->mIsMandatory = $isMandatory; |
124 | } |
125 | |
126 | public function isHidden() { |
127 | return $this->mIsHidden; |
128 | } |
129 | |
130 | public function setIsHidden( $isHidden ) { |
131 | $this->mIsHidden = $isHidden; |
132 | } |
133 | |
134 | public function isRestricted() { |
135 | return $this->mIsRestricted; |
136 | } |
137 | |
138 | public function setIsRestricted( $isRestricted ) { |
139 | $this->mIsRestricted = $isRestricted; |
140 | } |
141 | |
142 | public function holdsTemplate() { |
143 | return $this->mHoldsTemplate; |
144 | } |
145 | |
146 | public function isList() { |
147 | return $this->mIsList; |
148 | } |
149 | |
150 | public function getPossibleValues() { |
151 | if ( $this->mPossibleValues != null ) { |
152 | return $this->mPossibleValues; |
153 | } else { |
154 | return $this->template_field->getPossibleValues(); |
155 | } |
156 | } |
157 | |
158 | public function getUseDisplayTitle() { |
159 | return $this->mUseDisplayTitle; |
160 | } |
161 | |
162 | public function getInputName() { |
163 | return $this->mInputName; |
164 | } |
165 | |
166 | public function getLabel() { |
167 | return $this->mLabel; |
168 | } |
169 | |
170 | public function getLabelMsg() { |
171 | return $this->mLabelMsg; |
172 | } |
173 | |
174 | public function isDisabled() { |
175 | return $this->mIsDisabled; |
176 | } |
177 | |
178 | public function setDescriptionArg( $key, $value ) { |
179 | $this->mDescriptionArgs[$key] = $value; |
180 | } |
181 | |
182 | static function newFromFormFieldTag( |
183 | $tag_components, |
184 | $template, |
185 | $template_in_form, |
186 | $form_is_disabled, |
187 | User $user |
188 | ) { |
189 | global $wgPageFormsEmbeddedTemplates; |
190 | |
191 | $parser = PFUtils::getParser(); |
192 | |
193 | $f = new PFFormField(); |
194 | $f->mFieldArgs = []; |
195 | |
196 | $field_name = trim( $tag_components[1] ); |
197 | $template_name = $template_in_form->getTemplateName(); |
198 | |
199 | // See if this field matches one of the fields defined for this |
200 | // template - if it does, use all available information about |
201 | // that field; if it doesn't, either include it in the form or |
202 | // not, depending on whether the template has a 'strict' |
203 | // setting in the form definition. |
204 | $template_field = $template->getFieldNamed( $field_name ); |
205 | |
206 | if ( $template_field != null ) { |
207 | $f->template_field = $template_field; |
208 | } else { |
209 | if ( $template_in_form->strictParsing() ) { |
210 | $f->template_field = new PFTemplateField(); |
211 | $f->mIsList = false; |
212 | return $f; |
213 | } |
214 | $f->template_field = PFTemplateField::create( $field_name, null ); |
215 | } |
216 | |
217 | $embeddedTemplate = $f->template_field->getHoldsTemplate(); |
218 | if ( $embeddedTemplate != '' ) { |
219 | $f->mIsHidden = true; |
220 | $f->mHoldsTemplate = true; |
221 | // Store this information so that the embedded/"held" |
222 | // template - which is hopefully after this one in the |
223 | // form definition - can be handled correctly. In forms, |
224 | // both the embedding field and the embedded template are |
225 | // specified as such, but in templates (i.e., with |
226 | // #template_params), it's only the embedding field. |
227 | $wgPageFormsEmbeddedTemplates[$embeddedTemplate] = [ $template_name, $field_name ]; |
228 | } |
229 | |
230 | $semantic_property = null; |
231 | $cargo_table = $cargo_field = $cargo_where = null; |
232 | $show_on_select = []; |
233 | $fullFieldName = $template_name . '[' . $field_name . ']'; |
234 | $values = $valuesSourceType = $valuesSource = null; |
235 | |
236 | // We set "values from ..." params if there are corresponding |
237 | // values set in #template_params - this is a bit of a @hack, |
238 | // since we should really just use these values directly, but |
239 | // there are various places in the code that check for "values |
240 | // from ...", so it's easier to just pretend that these params |
241 | // were set. |
242 | $categoryFromTemplate = $f->getTemplateField()->getCategory(); |
243 | if ( $categoryFromTemplate !== null ) { |
244 | $f->mFieldArgs['values from category'] = $categoryFromTemplate; |
245 | } |
246 | $namespaceFromTemplate = $f->getTemplateField()->getNSText(); |
247 | if ( $namespaceFromTemplate !== null ) { |
248 | $f->mFieldArgs['values from namespace'] = $namespaceFromTemplate; |
249 | } |
250 | |
251 | // Cycle through the other components. |
252 | for ( $i = 2; $i < count( $tag_components ); $i++ ) { |
253 | $component = trim( $tag_components[$i] ); |
254 | |
255 | if ( $component == 'mandatory' ) { |
256 | $f->mIsMandatory = true; |
257 | } elseif ( $component == 'hidden' ) { |
258 | $f->mIsHidden = true; |
259 | } elseif ( $component == 'restricted' ) { |
260 | $f->mIsRestricted = ( !$user || !$user->isAllowed( 'editrestrictedfields' ) ); |
261 | } elseif ( $component == 'list' ) { |
262 | $f->mIsList = true; |
263 | } elseif ( $component == 'unique' ) { |
264 | $f->mFieldArgs['unique'] = true; |
265 | } elseif ( $component == 'edittools' ) { |
266 | // free text only |
267 | $f->mFieldArgs['edittools'] = true; |
268 | } |
269 | |
270 | $sub_components = array_map( 'trim', explode( '=', $component, 2 ) ); |
271 | |
272 | if ( count( $sub_components ) == 1 ) { |
273 | // add handling for single-value params, for custom input types |
274 | $f->mFieldArgs[$sub_components[0]] = true; |
275 | |
276 | if ( $component == 'holds template' ) { |
277 | $f->mIsHidden = true; |
278 | $f->mHoldsTemplate = true; |
279 | } |
280 | } elseif ( count( $sub_components ) == 2 ) { |
281 | // First, set each value as its own entry in $this->mFieldArgs. |
282 | $f->mFieldArgs[$sub_components[0]] = $sub_components[1]; |
283 | |
284 | // Then, do all special handling. |
285 | if ( $sub_components[0] == 'input type' ) { |
286 | $f->mInputType = $sub_components[1]; |
287 | } elseif ( $sub_components[0] == 'default' ) { |
288 | // We call recursivePreprocess() here, |
289 | // and not the more standard |
290 | // recursiveTagParse(), so that |
291 | // wikitext in the value, and bare URLs, |
292 | // will not get turned into HTML. |
293 | $f->mDefaultValue = $parser->recursivePreprocess( $sub_components[1] ); |
294 | } elseif ( $sub_components[0] == 'preload' ) { |
295 | $f->mPreloadPage = $sub_components[1]; |
296 | } elseif ( $sub_components[0] == 'label' ) { |
297 | $f->mLabel = $sub_components[1]; |
298 | } elseif ( $sub_components[0] == 'label msg' ) { |
299 | $f->mLabelMsg = $sub_components[1]; |
300 | } elseif ( $sub_components[0] == 'show on select' ) { |
301 | // html_entity_decode() is needed to turn '>' to '>' |
302 | $vals = explode( ';', html_entity_decode( $sub_components[1] ) ); |
303 | foreach ( $vals as $val ) { |
304 | $val = trim( $val ); |
305 | if ( empty( $val ) ) { |
306 | continue; |
307 | } |
308 | $option_div_pair = explode( '=>', $val, 2 ); |
309 | if ( count( $option_div_pair ) > 1 ) { |
310 | $option = PFFormPrinter::getParsedValue( $parser, trim( $option_div_pair[0] ) ); |
311 | $div_id = $option_div_pair[1]; |
312 | if ( array_key_exists( $div_id, $show_on_select ) ) { |
313 | $show_on_select[$div_id][] = $option; |
314 | } else { |
315 | $show_on_select[$div_id] = [ $option ]; |
316 | } |
317 | } else { |
318 | $show_on_select[$val] = []; |
319 | } |
320 | } |
321 | } elseif ( $sub_components[0] == 'values' ) { |
322 | // Handle this one only after |
323 | // 'delimiter' has also been set. |
324 | $values = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
325 | } elseif ( $sub_components[0] == 'values from property' ) { |
326 | $valuesSourceType = 'property'; |
327 | $valuesSource = $sub_components[1]; |
328 | } elseif ( $sub_components[0] == 'values from wikidata' ) { |
329 | $valuesSourceType = 'wikidata'; |
330 | $valuesSource = urlencode( $sub_components[1] ); |
331 | } elseif ( $sub_components[0] == 'values from query' ) { |
332 | $valuesSourceType = 'query'; |
333 | $valuesSource = $sub_components[1]; |
334 | } elseif ( $sub_components[0] == 'values from category' ) { |
335 | $valuesSource = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
336 | global $wgCapitalLinks; |
337 | if ( $wgCapitalLinks ) { |
338 | $valuesSource = ucfirst( $valuesSource ); |
339 | } |
340 | $valuesSourceType = 'category'; |
341 | } elseif ( $sub_components[0] == 'values from concept' ) { |
342 | $valuesSourceType = 'concept'; |
343 | $valuesSource = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
344 | } elseif ( $sub_components[0] == 'values from namespace' ) { |
345 | $valuesSourceType = 'namespace'; |
346 | $valuesSource = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
347 | } elseif ( $sub_components[0] == 'values dependent on' ) { |
348 | global $wgPageFormsDependentFields; |
349 | $wgPageFormsDependentFields[] = [ $sub_components[1], $fullFieldName ]; |
350 | } elseif ( $sub_components[0] == 'unique for category' ) { |
351 | $f->mFieldArgs['unique'] = true; |
352 | $f->mFieldArgs['unique_for_category'] = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
353 | } elseif ( $sub_components[0] == 'unique for namespace' ) { |
354 | $f->mFieldArgs['unique'] = true; |
355 | $f->mFieldArgs['unique_for_namespace'] = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
356 | } elseif ( $sub_components[0] == 'unique for concept' ) { |
357 | $f->mFieldArgs['unique'] = true; |
358 | $f->mFieldArgs['unique_for_concept'] = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
359 | } elseif ( $sub_components[0] == 'property' ) { |
360 | $semantic_property = $sub_components[1]; |
361 | } elseif ( $sub_components[0] == 'cargo table' ) { |
362 | $cargo_table = $sub_components[1]; |
363 | } elseif ( $sub_components[0] == 'cargo field' ) { |
364 | $cargo_field = $sub_components[1]; |
365 | } elseif ( $sub_components[0] == 'cargo where' ) { |
366 | $cargo_where = PFFormPrinter::getParsedValue( $parser, $sub_components[1] ); |
367 | } elseif ( $sub_components[0] == 'default filename' ) { |
368 | global $wgTitle; |
369 | $page_name = $wgTitle->getText(); |
370 | if ( $wgTitle->isSpecialPage() ) { |
371 | // If it's of the form |
372 | // Special:FormEdit/form/target, |
373 | // get just the target. |
374 | $pageNameComponents = explode( '/', $page_name, 3 ); |
375 | if ( count( $pageNameComponents ) == 3 ) { |
376 | $page_name = $pageNameComponents[2]; |
377 | } |
378 | } |
379 | $default_filename = str_replace( '<page name>', $page_name, $sub_components[1] ); |
380 | // Parse value, so default filename can |
381 | // include parser functions. |
382 | $default_filename = PFFormPrinter::getParsedValue( $parser, $default_filename ); |
383 | $f->mFieldArgs['default filename'] = $default_filename; |
384 | } elseif ( $sub_components[0] == 'restricted' ) { |
385 | $effectiveGroups = MediaWikiServices::getInstance()->getUserGroupManager()->getUserEffectiveGroups( $user ); |
386 | $f->mIsRestricted = !array_intersect( |
387 | $effectiveGroups, array_map( 'trim', explode( ',', $sub_components[1] ) ) |
388 | ); |
389 | } |
390 | } |
391 | } |
392 | // end for |
393 | |
394 | if ( in_array( $valuesSourceType, [ 'category', 'namespace', 'concept' ] ) ) { |
395 | global $wgPageFormsUseDisplayTitle; |
396 | $f->mUseDisplayTitle = $wgPageFormsUseDisplayTitle; |
397 | } else { |
398 | $f->mUseDisplayTitle = false; |
399 | } |
400 | |
401 | if ( !array_key_exists( 'delimiter', $f->mFieldArgs ) ) { |
402 | $delimiterFromTemplate = $f->getTemplateField()->getDelimiter(); |
403 | if ( $delimiterFromTemplate == '' ) { |
404 | $f->mFieldArgs['delimiter'] = ','; |
405 | } else { |
406 | $f->mFieldArgs['delimiter'] = $delimiterFromTemplate; |
407 | $f->mIsList = true; |
408 | } |
409 | } |
410 | |
411 | // Do some data storage specific to the Semantic MediaWiki and |
412 | // Cargo extensions. |
413 | if ( defined( 'SMW_VERSION' ) ) { |
414 | // If a property was set in the form definition, |
415 | // overwrite whatever is set in the template field - |
416 | // this is somewhat of a hack, since parameters set in |
417 | // the form definition are meant to go into the |
418 | // PFFormField object, not the PFTemplateField object |
419 | // it contains; |
420 | // it seemed like too much work, though, to create an |
421 | // PFFormField::setSemanticProperty() function just for |
422 | // this call. |
423 | if ( $semantic_property !== null ) { |
424 | $f->template_field->setSemanticProperty( $semantic_property ); |
425 | } else { |
426 | $semantic_property = $f->template_field->getSemanticProperty(); |
427 | } |
428 | if ( $semantic_property !== null ) { |
429 | global $wgPageFormsFieldProperties; |
430 | $wgPageFormsFieldProperties[$fullFieldName] = $semantic_property; |
431 | } |
432 | } |
433 | if ( defined( 'CARGO_VERSION' ) ) { |
434 | if ( $cargo_table != null && $cargo_field != null ) { |
435 | $f->template_field->setCargoFieldData( $cargo_table, $cargo_field ); |
436 | } |
437 | $fullCargoField = $f->template_field->getFullCargoField(); |
438 | if ( $fullCargoField !== null ) { |
439 | global $wgPageFormsCargoFields; |
440 | $wgPageFormsCargoFields[$fullFieldName] = $fullCargoField; |
441 | } |
442 | } |
443 | |
444 | $f->setPossibleValues( $valuesSourceType, $valuesSource, $values, $cargo_table, $cargo_field, $cargo_where ); |
445 | |
446 | $mappingType = PFMappingUtils::getMappingType( $f->mFieldArgs, $f->mUseDisplayTitle ); |
447 | if ( $mappingType !== null && !empty( $f->mPossibleValues ) ) { |
448 | // If we're going to be mapping values, we need to have |
449 | // the exact page name - and if these values come from |
450 | // "values from namespace", the namespace prefix was |
451 | // not included, so we need to add it now. |
452 | if ( $valuesSourceType == 'namespace' && $valuesSource != '' && $valuesSource != 'Main' ) { |
453 | foreach ( $f->mPossibleValues as $index => &$value ) { |
454 | $value = $valuesSource . ':' . $value; |
455 | } |
456 | // Has to be set to false to not mess up the |
457 | // handling. |
458 | $f->mUseDisplayTitle = false; |
459 | } |
460 | |
461 | $mappedValuesKey = json_encode( $f->mFieldArgs ) . $mappingType; |
462 | if ( array_key_exists( $mappedValuesKey, self::$mappedValuesCache ) ) { |
463 | $f->mPossibleValues = self::$mappedValuesCache[$mappedValuesKey]; |
464 | } else { |
465 | $f->mPossibleValues = PFMappingUtils::getMappedValuesForInput( $f->mPossibleValues, $f->mFieldArgs ); |
466 | self::$mappedValuesCache[$mappedValuesKey] = $f->mPossibleValues; |
467 | } |
468 | } |
469 | |
470 | if ( $template_in_form->allowsMultiple() ) { |
471 | $f->mFieldArgs['part_of_multiple'] = true; |
472 | } |
473 | if ( count( $show_on_select ) > 0 ) { |
474 | $f->mFieldArgs['show on select'] = $show_on_select; |
475 | } |
476 | |
477 | // Disable this field if either the whole form is disabled, or |
478 | // it's a restricted field and user doesn't have sysop privileges. |
479 | $f->mIsDisabled = ( $form_is_disabled || $f->mIsRestricted ); |
480 | |
481 | if ( $template_name === null || $template_name === '' ) { |
482 | $f->mInputName = $field_name; |
483 | } elseif ( $template_in_form->allowsMultiple() ) { |
484 | // 'num' will get replaced by an actual index, either in PHP |
485 | // or in Javascript, later on |
486 | $f->mInputName = $template_name . '[num][' . $field_name . ']'; |
487 | $f->setFieldArg( 'origName', $fullFieldName ); |
488 | } else { |
489 | $f->mInputName = $fullFieldName; |
490 | } |
491 | |
492 | return $f; |
493 | } |
494 | |
495 | private function setPossibleValues( $valuesSourceType, $valuesSource, $values, $cargo_table, $cargo_field, $cargo_where ) { |
496 | // Set the $mPossibleValues field, using the following logic: |
497 | // - If "values" was set in the form definition, use that. |
498 | // - If any "values from ..." parameter was set, use that. |
499 | // - If "cargo where" was set, use it, if a Cargo table and field have also been defined. |
500 | // - If "cargo table" and "cargo field" were set, then: |
501 | // - If there are "allowed values" for that field use those. |
502 | // - Otherwise, use that field's existing values. |
503 | // - Otherwise, use the possible values defined within the corresponding template field, if any. |
504 | |
505 | if ( $values != null ) { |
506 | $delimiter = $this->mFieldArgs['delimiter']; |
507 | // Remove whitespaces, and un-escape characters |
508 | $valuesArray = array_map( 'trim', explode( $delimiter, $values ) ); |
509 | $this->mPossibleValues = array_map( 'htmlspecialchars_decode', $valuesArray ); |
510 | return; |
511 | } |
512 | |
513 | if ( $valuesSourceType !== null && ( $valuesSourceType !== 'wikidata' || ( $this->mInputType !== 'combobox' && |
514 | $this->mInputType !== 'tokens' ) ) ) { |
515 | $this->mPossibleValues = PFValuesUtils::getAutocompleteValues( $valuesSource, $valuesSourceType ); |
516 | return; |
517 | } |
518 | |
519 | if ( defined( 'CARGO_VERSION' ) && $cargo_where != null ) { |
520 | if ( $cargo_table == null || $cargo_field == null ) { |
521 | $fullCargoField = $this->template_field->getFullCargoField(); |
522 | $table_and_field = explode( '|', $fullCargoField ); |
523 | $cargo_table = $table_and_field[0]; |
524 | $cargo_field = $table_and_field[1]; |
525 | } |
526 | $cargoValues = PFValuesUtils::getValuesForCargoField( $cargo_table, $cargo_field, $cargo_where ); |
527 | $this->mPossibleValues = array_filter( $cargoValues, 'strlen' ); |
528 | return; |
529 | } |
530 | |
531 | // If we're using Cargo, there's no equivalent for "values from |
532 | // property" - instead, we just always get the values if a |
533 | // field and table have been specified. |
534 | if ( defined( 'CARGO_VERSION' ) && $cargo_table != null && $cargo_field != null ) { |
535 | // If there are "allowed values" defined, use those. |
536 | $fieldDesc = PFUtils::getCargoFieldDescription( $cargo_table, $cargo_field ); |
537 | if ( $fieldDesc !== null && $fieldDesc->mAllowedValues !== null ) { |
538 | $this->mPossibleValues = $fieldDesc->mAllowedValues; |
539 | return; |
540 | } |
541 | // We only want the non-null values. Ideally this could |
542 | // be done by calling getValuesForCargoField() with |
543 | // an "IS NOT NULL" clause, but unfortunately that fails |
544 | // for array/list fields. |
545 | // Instead of getting involved with all that, we'll just |
546 | // remove the null/blank values afterward. |
547 | $cargoValues = PFValuesUtils::getAllValuesForCargoField( $cargo_table, $cargo_field ); |
548 | $this->mPossibleValues = array_filter( $cargoValues, 'strlen' ); |
549 | return; |
550 | } |
551 | |
552 | $this->mPossibleValues = $this->template_field->getPossibleValues(); |
553 | } |
554 | |
555 | function cleanupTranslateTags( &$value ) { |
556 | $i = 0; |
557 | // If there are two tags ("<!--T:X-->") with no content between them, remove the first one. |
558 | while ( preg_match( '/(<!--T:[0-9]+-->\s*)(<!--T:[0-9]+-->)/', $value, $matches ) ) { |
559 | $value = str_replace( $matches[1], '', $value ); |
560 | if ( $i++ > 200 ) { |
561 | // Is this necessary? |
562 | break; |
563 | } |
564 | } |
565 | |
566 | $i = 0; |
567 | // If there is a tag ("<!--T:X-->") at the end, with nothing after, remove it. |
568 | while ( preg_match( '#(<!--T:[0-9]+-->\s*)(</translate>)#', $value, $matches ) ) { |
569 | $value = str_replace( $matches[1], '', $value ); |
570 | if ( $i++ > 200 ) { |
571 | // Is this necessary? |
572 | break; |
573 | } |
574 | } |
575 | |
576 | $i = 0; |
577 | // If there is a tag ("<!--T:X-->") not separated from a template call ("{{ ..."), |
578 | // add a new line between them. |
579 | while ( preg_match( '/(<!--T:[0-9]+-->)({{[^}]+}}\s*)/', $value, $matches ) ) { |
580 | $value = str_replace( $matches[1], $matches[1] . "\n", $value ); |
581 | if ( $i++ > 200 ) { |
582 | // Is this necessary? |
583 | break; |
584 | } |
585 | } |
586 | } |
587 | |
588 | function getCurrentValue( $template_instance_query_values, $form_submitted, $source_is_page, $all_instances_printed, &$val_modifier = null ) { |
589 | // Get the value from the request, if |
590 | // it's there, and if it's not an array. |
591 | $field_name = $this->template_field->getFieldName(); |
592 | $delimiter = $this->mFieldArgs['delimiter']; |
593 | $escaped_field_name = str_replace( "'", "\'", $field_name ); |
594 | |
595 | if ( PFUtils::isTranslateEnabled() && $this->hasFieldArg( 'translatable' ) && $this->getFieldArg( 'translatable' ) ) { |
596 | // If this is a translatable field, and both it and its corresponding translate ID tag are passed in, we add it. |
597 | $fieldName = $this->getTemplateField()->getFieldName(); |
598 | $fieldNameTag = $fieldName . '_translate_number_tag'; |
599 | if ( isset( $template_instance_query_values[$fieldName] ) && isset( $template_instance_query_values[$fieldNameTag] ) ) { |
600 | $tag = $template_instance_query_values[$fieldNameTag]; |
601 | if ( !preg_match( '/( |\n)$/', $tag ) ) { |
602 | $tag .= "\n"; |
603 | } |
604 | if ( trim( $template_instance_query_values[$fieldName] ) ) { |
605 | // Don't add the tag if field content has been removed. |
606 | $template_instance_query_values[$fieldName] = $tag . $template_instance_query_values[$fieldName]; |
607 | } |
608 | } |
609 | // If user has deleted some content, and there is some translate tag ("<!--T:X-->") with no content, remove the tag. |
610 | if ( isset( $template_instance_query_values[$fieldName] ) ) { |
611 | $this->cleanupTranslateTags( $template_instance_query_values[$fieldName] ); |
612 | } |
613 | } |
614 | |
615 | if ( isset( $template_instance_query_values ) && |
616 | $template_instance_query_values != null && |
617 | is_array( $template_instance_query_values ) |
618 | ) { |
619 | // If the field name contains an apostrophe, the array |
620 | // sometimes has the apostrophe escaped, and sometimes |
621 | // not. For now, just check for both versions. |
622 | // @TODO - figure this out. |
623 | $field_query_val = null; |
624 | if ( array_key_exists( $escaped_field_name, $template_instance_query_values ) ) { |
625 | $field_query_val = $template_instance_query_values[$escaped_field_name]; |
626 | } elseif ( array_key_exists( $field_name, $template_instance_query_values ) ) { |
627 | $field_query_val = $template_instance_query_values[$field_name]; |
628 | } else { |
629 | // The next checks are to allow for support for appending/prepending with autoedit. |
630 | if ( array_key_exists( "$field_name+", $template_instance_query_values ) ) { |
631 | $field_query_val = $template_instance_query_values["$field_name+"]; |
632 | $val_modifier = '+'; |
633 | } elseif ( array_key_exists( "$field_name-", $template_instance_query_values ) ) { |
634 | $field_query_val = $template_instance_query_values["$field_name-"]; |
635 | $val_modifier = '-'; |
636 | } |
637 | } |
638 | |
639 | if ( $form_submitted && $field_query_val != '' ) { |
640 | $map_field = false; |
641 | if ( array_key_exists( 'map_field', $template_instance_query_values ) && |
642 | array_key_exists( $field_name, $template_instance_query_values['map_field'] ) ) { |
643 | $map_field = true; |
644 | } |
645 | if ( is_array( $field_query_val ) ) { |
646 | $cur_values = []; |
647 | if ( $map_field && $this->mPossibleValues !== null ) { |
648 | foreach ( $field_query_val as $key => $val ) { |
649 | $val = trim( $val ); |
650 | if ( $key === 'is_list' ) { |
651 | $cur_values[$key] = $val; |
652 | } else { |
653 | $cur_values[] = PFValuesUtils::labelToValue( $val, $this->mPossibleValues ); |
654 | } |
655 | } |
656 | } else { |
657 | foreach ( $field_query_val as $key => $val ) { |
658 | $cur_values[$key] = $val; |
659 | } |
660 | } |
661 | return PFFormPrinter::getStringFromPassedInArray( $cur_values, $delimiter ); |
662 | } else { |
663 | $field_query_val = trim( $field_query_val ); |
664 | if ( $map_field && $this->mPossibleValues !== null ) { |
665 | // this should be replaced with an input type neutral way of |
666 | // figuring out if this scalar input type is a list |
667 | if ( $this->mInputType == "tokens" ) { |
668 | $this->mIsList = true; |
669 | } |
670 | if ( $this->mIsList ) { |
671 | $cur_values = array_map( 'trim', explode( $delimiter, $field_query_val ) ); |
672 | foreach ( $cur_values as $key => $val ) { |
673 | $cur_values[$key] = PFValuesUtils::labelToValue( $val, $this->mPossibleValues ); |
674 | } |
675 | return implode( $delimiter, $cur_values ); |
676 | } |
677 | return PFValuesUtils::labelToValue( $field_query_val, $this->mPossibleValues ); |
678 | } |
679 | return $field_query_val; |
680 | } |
681 | } |
682 | if ( !$form_submitted && $field_query_val != '' ) { |
683 | if ( is_array( $field_query_val ) ) { |
684 | $str = PFFormPrinter::getStringFromPassedInArray( $field_query_val, $delimiter ); |
685 | } else { |
686 | $str = $field_query_val; |
687 | } |
688 | return str_replace( [ '<', '>' ], [ '<', '>' ], $str ); |
689 | |
690 | } |
691 | } |
692 | |
693 | // Default values in new instances of multiple-instance |
694 | // templates should always be set, even for existing pages. |
695 | $part_of_multiple = array_key_exists( 'part_of_multiple', $this->mFieldArgs ); |
696 | $printing_starter_instance = $part_of_multiple && $all_instances_printed; |
697 | if ( ( !$source_is_page || $printing_starter_instance ) && !$form_submitted ) { |
698 | if ( $this->mDefaultValue !== null ) { |
699 | // Set to the default value specified in the form, if it's there. |
700 | return $this->mDefaultValue; |
701 | } elseif ( $this->mPreloadPage ) { |
702 | return PFFormUtils::getPreloadedText( $this->mPreloadPage ); |
703 | } |
704 | } |
705 | |
706 | // We're still here... |
707 | return null; |
708 | } |
709 | |
710 | /** |
711 | * Map a template field value into labels. |
712 | * @param string $valueString |
713 | * @param string $delimiter |
714 | * @param bool $formSubmitted |
715 | * @return string|string[] |
716 | */ |
717 | public function valueStringToLabels( $valueString, $delimiter, $formSubmitted ) { |
718 | if ( $valueString === null || trim( $valueString ) === '' || |
719 | $this->mPossibleValues === null ) { |
720 | return $valueString; |
721 | } |
722 | if ( $delimiter !== null ) { |
723 | $values = array_map( 'trim', explode( $delimiter, $valueString ) ); |
724 | } else { |
725 | $values = [ $valueString ]; |
726 | } |
727 | |
728 | $maxValues = PFValuesUtils::getMaxValuesToRetrieve(); |
729 | if ( $formSubmitted && ( count( $this->mPossibleValues ) >= $maxValues ) ) { |
730 | // Remote autocompletion. |
731 | $mappedValues = PFMappingUtils::getMappedValuesForInput( $values, $this->getFieldArgs() ); |
732 | return array_values( $mappedValues ); |
733 | } |
734 | |
735 | $labels = []; |
736 | foreach ( $values as $value ) { |
737 | if ( $value != '' ) { |
738 | if ( array_key_exists( $value, $this->mPossibleValues ) ) { |
739 | $labels[] = $this->mPossibleValues[$value]; |
740 | } else { |
741 | $labels[] = $value; |
742 | } |
743 | } |
744 | } |
745 | return $labels; |
746 | } |
747 | |
748 | public function additionalHTMLForInput( $cur_value, $field_name, $template_name ) { |
749 | $text = ''; |
750 | |
751 | // Add a field just after the hidden field, within the HTML, to |
752 | // locate where the multiple-templates HTML, stored in |
753 | // $multipleTemplateString, should be inserted. |
754 | if ( $this->mHoldsTemplate ) { |
755 | $text .= PFFormPrinter::makePlaceholderInFormHTML( PFFormPrinter::placeholderFormat( $template_name, $field_name ) ); |
756 | } |
757 | |
758 | // If this field is disabled, add a hidden field holding |
759 | // the value of this field, because disabled inputs for some |
760 | // reason don't submit their value. |
761 | if ( $this->mIsDisabled ) { |
762 | if ( $field_name == 'free text' || $field_name == '#freetext#' ) { |
763 | $text .= Html::hidden( 'pf_free_text', '!free_text!' ); |
764 | } else { |
765 | if ( is_array( $cur_value ) ) { |
766 | $delimiter = $this->mFieldArgs['delimiter']; |
767 | $text .= Html::hidden( $this->mInputName, implode( $delimiter, $cur_value ) ); |
768 | } else { |
769 | $text .= Html::hidden( $this->mInputName, $cur_value ); |
770 | } |
771 | } |
772 | } |
773 | |
774 | if ( $this->hasFieldArg( 'mapping template' ) || |
775 | $this->hasFieldArg( 'mapping property' ) || |
776 | ( $this->hasFieldArg( 'mapping cargo table' ) && |
777 | $this->hasFieldArg( 'mapping cargo field' ) ) || |
778 | $this->mUseDisplayTitle ) { |
779 | if ( $this->hasFieldArg( 'part_of_multiple' ) ) { |
780 | $text .= Html::hidden( $template_name . '[num][map_field][' . $field_name . ']', 'true' ); |
781 | } else { |
782 | $text .= Html::hidden( $template_name . '[map_field][' . $field_name . ']', 'true' ); |
783 | } |
784 | } |
785 | |
786 | if ( $this->hasFieldArg( 'unique' ) ) { |
787 | global $wgPageFormsFieldNum; |
788 | |
789 | $semantic_property = $this->template_field->getSemanticProperty(); |
790 | if ( $semantic_property != null ) { |
791 | $text .= Html::hidden( 'input_' . $wgPageFormsFieldNum . '_unique_property', $semantic_property ); |
792 | } |
793 | $fullCargoField = $this->template_field->getFullCargoField(); |
794 | if ( $fullCargoField != null ) { |
795 | // It's inefficient to get these values via |
796 | // text parsing, but oh well. |
797 | list( $cargo_table, $cargo_field ) = explode( '|', $fullCargoField, 2 ); |
798 | $text .= Html::hidden( 'input_' . $wgPageFormsFieldNum . '_unique_cargo_table', $cargo_table ); |
799 | $text .= Html::hidden( 'input_' . $wgPageFormsFieldNum . '_unique_cargo_field', $cargo_field ); |
800 | } |
801 | if ( $this->hasFieldArg( 'unique_for_category' ) ) { |
802 | $text .= Html::hidden( 'input_' . $wgPageFormsFieldNum . '_unique_for_category', $this->getFieldArg( 'unique_for_category' ) ); |
803 | } |
804 | if ( $this->hasFieldArg( 'unique_for_namespace' ) ) { |
805 | $text .= Html::hidden( 'input_' . $wgPageFormsFieldNum . '_unique_for_namespace', $this->getFieldArg( 'unique_for_namespace' ) ); |
806 | } |
807 | if ( $this->hasFieldArg( 'unique_for_concept' ) ) { |
808 | $text .= Html::hidden( 'input_' . $wgPageFormsFieldNum . '_unique_for_concept', $this->getFieldArg( 'unique_for_concept' ) ); |
809 | } |
810 | } |
811 | return $text; |
812 | } |
813 | |
814 | /** |
815 | * For now, HTML of an individual field depends on whether or not it's |
816 | * part of multiple-instance template; this may change if handling of |
817 | * such templates in form definitions gets more sophisticated. |
818 | * |
819 | * @param bool $part_of_multiple |
820 | * @param bool $is_last_field_in_template |
821 | * @return string |
822 | */ |
823 | function createMarkup( $part_of_multiple, $is_last_field_in_template ) { |
824 | $text = ""; |
825 | $descPlaceholder = ""; |
826 | $textBeforeField = ""; |
827 | |
828 | if ( array_key_exists( "Description", $this->mDescriptionArgs ) ) { |
829 | $fieldDesc = $this->mDescriptionArgs['Description']; |
830 | if ( $fieldDesc != '' ) { |
831 | if ( isset( $this->mDescriptionArgs['DescriptionTooltipMode'] ) ) { |
832 | // The wikitext we use for tooltips |
833 | // depends on which other extensions |
834 | // are installed. |
835 | if ( class_exists( 'RegularTooltipsParser' ) ) { |
836 | // RegularTooltips |
837 | $descPlaceholder = " {{#info-tooltip:$fieldDesc}}"; |
838 | } elseif ( defined( 'SMW_VERSION' ) ) { |
839 | // Semantic MediaWiki |
840 | $descPlaceholder = " {{#info:$fieldDesc}}"; |
841 | } elseif ( class_exists( 'SimpleTooltipParserFunction' ) ) { |
842 | // SimpleTooltip |
843 | $descPlaceholder = " {{#tip-info:$fieldDesc}}"; |
844 | } else { |
845 | // Don't make it a tooltip. |
846 | $descPlaceholder = '<br><p class="pfFieldDescription" style="font-size:0.7em; color:gray;">' . $fieldDesc . '</p>'; |
847 | } |
848 | } else { |
849 | $descPlaceholder = '<br><p class="pfFieldDescription" style="font-size:0.7em; color:gray;">' . $fieldDesc . '</p>'; |
850 | } |
851 | } |
852 | } |
853 | |
854 | if ( array_key_exists( "TextBeforeField", $this->mDescriptionArgs ) ) { |
855 | $textBeforeField = $this->mDescriptionArgs['TextBeforeField']; |
856 | } |
857 | |
858 | $fieldLabel = $this->template_field->getLabel(); |
859 | if ( $fieldLabel == '' ) { |
860 | $fieldLabel = $this->template_field->getFieldName(); |
861 | } |
862 | if ( $textBeforeField != '' ) { |
863 | $fieldLabel = $textBeforeField . ' ' . $fieldLabel; |
864 | } |
865 | |
866 | if ( $part_of_multiple ) { |
867 | $text .= "'''$fieldLabel:''' $descPlaceholder"; |
868 | } else { |
869 | $text .= "! $fieldLabel: $descPlaceholder\n"; |
870 | } |
871 | |
872 | if ( !$part_of_multiple ) { |
873 | $text .= "| "; |
874 | } |
875 | $text .= "{{{field|" . $this->template_field->getFieldName(); |
876 | if ( $this->mIsHidden ) { |
877 | $text .= "|hidden"; |
878 | } elseif ( $this->getInputType() !== null && $this->getInputType() !== '' ) { |
879 | $text .= "|input type=" . $this->getInputType(); |
880 | } |
881 | foreach ( $this->mFieldArgs as $arg => $value ) { |
882 | if ( $value === true ) { |
883 | $text .= "|$arg"; |
884 | } elseif ( $arg === 'uploadable' ) { |
885 | // Are there similar value-less arguments |
886 | // that need to be handled here? |
887 | $text .= "|$arg"; |
888 | } else { |
889 | $text .= "|$arg=$value"; |
890 | } |
891 | } |
892 | |
893 | // Special handling if neither SMW nor Cargo are installed - the |
894 | // form has to handle stuff that otherwise would go in the |
895 | // template. |
896 | if ( |
897 | !defined( 'SMW_VERSION' ) && |
898 | !defined( 'CARGO_VERSION' ) && |
899 | !array_key_exists( 'values', $this->mFieldArgs ) && |
900 | is_array( $this->template_field->getPossibleValues() ) && |
901 | count( $this->template_field->getPossibleValues() ) > 0 |
902 | ) { |
903 | if ( $this->getInputType() == null ) { |
904 | if ( $this->template_field->isList() ) { |
905 | $text .= '|input type=checkboxes'; |
906 | } else { |
907 | $text .= '|input type=dropdown'; |
908 | } |
909 | } |
910 | $delimiter = ','; |
911 | if ( $this->template_field->isList() ) { |
912 | $delimiter = $this->template_field->getDelimiter(); |
913 | if ( $delimiter == '' ) { |
914 | $delimiter = ','; |
915 | } |
916 | // @todo - we need to add a "|delimiter=" param |
917 | // here too, if #template_params is not being |
918 | // called in the template. |
919 | } |
920 | $text .= '|values=' . implode( $delimiter, $this->template_field->getPossibleValues() ); |
921 | } |
922 | |
923 | if ( $this->mIsMandatory ) { |
924 | $text .= "|mandatory"; |
925 | } elseif ( $this->mIsRestricted ) { |
926 | $text .= "|restricted"; |
927 | } |
928 | $text .= "}}}\n"; |
929 | if ( $part_of_multiple ) { |
930 | $text .= "\n"; |
931 | } elseif ( !$is_last_field_in_template ) { |
932 | $text .= "|-\n"; |
933 | } |
934 | return $text; |
935 | } |
936 | |
937 | function getArgumentsForInputCallSMW( array &$other_args ) { |
938 | if ( $this->template_field->getSemanticProperty() !== '' && |
939 | !array_key_exists( 'semantic_property', $other_args ) ) { |
940 | $other_args['semantic_property'] = $this->template_field->getSemanticProperty(); |
941 | $other_args['property_type'] = $this->template_field->getPropertyType(); |
942 | } |
943 | // If autocompletion hasn't already been hardcoded in the form, |
944 | // and it's a property of type page, or a property of another |
945 | // type with 'autocomplete' specified, set the necessary |
946 | // parameters. |
947 | if ( !array_key_exists( 'autocompletion source', $other_args ) ) { |
948 | if ( $this->template_field->getPropertyType() == '_wpg' ) { |
949 | $other_args['autocompletion source'] = $this->template_field->getSemanticProperty(); |
950 | $other_args['autocomplete field type'] = 'property'; |
951 | } elseif ( array_key_exists( 'autocomplete', $other_args ) || array_key_exists( 'remote autocompletion', $other_args ) ) { |
952 | $other_args['autocompletion source'] = $this->template_field->getSemanticProperty(); |
953 | $other_args['autocomplete field type'] = 'property'; |
954 | } |
955 | } |
956 | } |
957 | |
958 | function getArgumentsForInputCallCargo( array &$other_args ) { |
959 | $fullCargoField = $this->template_field->getFullCargoField(); |
960 | if ( $fullCargoField !== null && |
961 | array_key_exists( 'cargo where', $other_args ) ) { |
962 | $fullCargoField .= '|' . $other_args['cargo where']; |
963 | } |
964 | if ( $fullCargoField !== null && |
965 | !array_key_exists( 'full_cargo_field', $other_args ) ) { |
966 | $other_args['full_cargo_field'] = $fullCargoField; |
967 | } |
968 | |
969 | if ( $this->template_field->getFieldType() == 'Hierarchy' ) { |
970 | $other_args['structure'] = $this->template_field->getHierarchyStructure(); |
971 | } |
972 | |
973 | if ( !array_key_exists( 'autocompletion source', $other_args ) ) { |
974 | if ( |
975 | $this->template_field->getFieldType() == 'Page' || |
976 | array_key_exists( 'autocomplete', $other_args ) || |
977 | array_key_exists( 'remote autocompletion', $other_args ) |
978 | ) { |
979 | if ( array_key_exists( 'mapping cargo table', $other_args ) && |
980 | array_key_exists( 'mapping cargo field', $other_args ) ) { |
981 | $mapping_cargo_field = $other_args[ 'mapping cargo field' ]; |
982 | $mapping_cargo_table = $other_args[ 'mapping cargo table' ]; |
983 | $other_args['autocompletion source'] = $mapping_cargo_table . '|' . $mapping_cargo_field; |
984 | } else { |
985 | $other_args['autocompletion source'] = $fullCargoField; |
986 | } |
987 | $other_args['autocomplete field type'] = 'cargo field'; |
988 | } |
989 | } |
990 | } |
991 | |
992 | /** |
993 | * Since Page Forms uses a hook system for the functions that |
994 | * create HTML inputs, most arguments are contained in the "$other_args" |
995 | * array - create this array, using the attributes of this form |
996 | * field and the template field it corresponds to, if any. |
997 | * @param array|null $default_args |
998 | * @return array |
999 | */ |
1000 | function getArgumentsForInputCall( array $default_args = null ) { |
1001 | $parser = PFUtils::getParser(); |
1002 | |
1003 | // start with the arguments array already defined |
1004 | $other_args = $this->mFieldArgs; |
1005 | // a value defined for the form field should always supersede |
1006 | // the coresponding value for the template field |
1007 | if ( $this->mPossibleValues != null ) { |
1008 | $other_args['possible_values'] = $this->mPossibleValues; |
1009 | } else { |
1010 | $other_args['possible_values'] = $this->template_field->getPossibleValues(); |
1011 | if ( $this->hasFieldArg( 'mapping using translate' ) ) { |
1012 | $mappedValues = PFMappingUtils::getValuesWithTranslateMapping( $other_args['possible_values'], $other_args['mapping using translate'] ); |
1013 | $other_args['value_labels'] = array_values( $mappedValues ); |
1014 | } else { |
1015 | $other_args['value_labels'] = $this->template_field->getValueLabels(); |
1016 | } |
1017 | } |
1018 | $other_args['is_list'] = ( $this->mIsList || $this->template_field->isList() ); |
1019 | if ( $this->template_field->isMandatory() ) { |
1020 | $other_args['mandatory'] = true; |
1021 | } |
1022 | if ( $this->template_field->isUnique() ) { |
1023 | $other_args['unique'] = true; |
1024 | } |
1025 | |
1026 | // Now add some extension-specific arguments to the input call. |
1027 | if ( defined( 'CARGO_VERSION' ) ) { |
1028 | $this->getArgumentsForInputCallCargo( $other_args ); |
1029 | } |
1030 | if ( defined( 'SMW_VERSION' ) ) { |
1031 | $this->getArgumentsForInputCallSMW( $other_args ); |
1032 | } |
1033 | |
1034 | // Now merge in the default values set by PFFormPrinter, if |
1035 | // there were any - put the default values first, so that if |
1036 | // there's a conflict they'll be overridden. |
1037 | if ( $default_args != null ) { |
1038 | $other_args = array_merge( $default_args, $other_args ); |
1039 | } |
1040 | |
1041 | foreach ( $other_args as $argname => $argvalue ) { |
1042 | if ( is_string( $argvalue ) ) { |
1043 | $other_args[$argname] = |
1044 | PFFormPrinter::getParsedValue( $parser, $argvalue ); |
1045 | } |
1046 | } |
1047 | |
1048 | return $other_args; |
1049 | } |
1050 | } |