Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 503 |
|
0.00% |
0 / 28 |
CRAP | |
0.00% |
0 / 1 |
PFPageSchemas | |
0.00% |
0 / 503 |
|
0.00% |
0 / 28 |
34410 | |
0.00% |
0 / 1 |
createPageSchemasObject | |
0.00% |
0 / 33 |
|
0.00% |
0 / 1 |
462 | |||
createSchemaXMLFromForm | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
272 | |||
createTemplateXMLFromForm | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
42 | |||
createFieldXMLFromForm | |
0.00% |
0 / 26 |
|
0.00% |
0 / 1 |
156 | |||
createPageSectionXMLFromForm | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
20 | |||
createFormInputXMLFromForm | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
getDisplayColor | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSchemaDisplayString | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSchemaEditingHTML | |
0.00% |
0 / 41 |
|
0.00% |
0 / 1 |
56 | |||
getTemplateEditingHTML | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
12 | |||
getFieldEditingHTML | |
0.00% |
0 / 49 |
|
0.00% |
0 / 1 |
210 | |||
getPageSectionEditingHTML | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
56 | |||
getFormName | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
getMainFormInfo | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
42 | |||
getFormFieldInfo | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
90 | |||
getPageSection | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
42 | |||
getPagesToGenerate | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
getFieldsFromTemplateSchema | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
72 | |||
generateForm | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
56 | |||
generatePages | |
0.00% |
0 / 83 |
|
0.00% |
0 / 1 |
420 | |||
getSchemaDisplayValues | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
20 | |||
getTemplateValues | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
30 | |||
getTemplateDisplayString | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getTemplateDisplayValues | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
30 | |||
getFieldDisplayString | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getPageSectionDisplayString | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getFieldDisplayValues | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
30 | |||
getPageSectionDisplayValues | |
0.00% |
0 / 9 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | |
3 | use MediaWiki\MediaWikiServices; |
4 | |
5 | /** |
6 | * Static functions for Page Forms, for use by the Page Schemas |
7 | * extension. |
8 | * |
9 | * @author Yaron Koren |
10 | * @author Ankit Garg |
11 | * @file |
12 | * @ingroup PF |
13 | */ |
14 | |
15 | class PFPageSchemas extends PSExtensionHandler { |
16 | |
17 | /** |
18 | * Creates an object to hold form-wide information, based on an XML |
19 | * object from the Page Schemas extension. |
20 | * @param string $tagName |
21 | * @param SimpleXMLElement $xml |
22 | * @return string[]|null |
23 | */ |
24 | public static function createPageSchemasObject( $tagName, $xml ) { |
25 | $pfarray = []; |
26 | |
27 | if ( $tagName == "standardInputs" ) { |
28 | foreach ( $xml->children() as $_ => $child ) { |
29 | foreach ( $child->children() as $tag => $formelem ) { |
30 | if ( $tag == $tagName ) { |
31 | foreach ( $formelem->attributes() as $attr => $name ) { |
32 | $pfarray[$attr] = (string)$formelem->attributes()->$attr; |
33 | } |
34 | } |
35 | } |
36 | return $pfarray; |
37 | } |
38 | } |
39 | |
40 | if ( $tagName == "pageforms_Form" ) { |
41 | foreach ( $xml->children() as $tag => $child ) { |
42 | if ( $tag == $tagName ) { |
43 | $formName = (string)$child->attributes()->name; |
44 | $pfarray['name'] = $formName; |
45 | foreach ( $child->children() as $childTag => $formelem ) { |
46 | $pfarray[$childTag] = (string)$formelem; |
47 | } |
48 | return $pfarray; |
49 | } |
50 | } |
51 | } |
52 | if ( $tagName == "pageforms_TemplateDetails" ) { |
53 | foreach ( $xml->children() as $tag => $child ) { |
54 | if ( $tag == $tagName ) { |
55 | foreach ( $child->children() as $childTag => $formelem ) { |
56 | $pfarray[$childTag] = (string)$formelem; |
57 | } |
58 | return $pfarray; |
59 | } |
60 | } |
61 | } |
62 | if ( $tagName == "pageforms_FormInput" || $tagName == "pageforms_PageSection" ) { |
63 | foreach ( $xml->children() as $tag => $child ) { |
64 | if ( $tag == $tagName ) { |
65 | foreach ( $child->children() as $prop ) { |
66 | if ( $prop->getName() == 'InputType' ) { |
67 | $pfarray[$prop->getName()] = (string)$prop; |
68 | } else { |
69 | if ( (string)$prop->attributes()->name == '' ) { |
70 | $pfarray[$prop->getName()] = (string)$prop; |
71 | } else { |
72 | $pfarray[(string)$prop->attributes()->name] = (string)$prop; |
73 | } |
74 | } |
75 | } |
76 | return $pfarray; |
77 | } |
78 | } |
79 | } |
80 | return null; |
81 | } |
82 | |
83 | /** |
84 | * Creates Page Schemas XML for form-wide information. |
85 | * @return string |
86 | */ |
87 | public static function createSchemaXMLFromForm() { |
88 | global $wgRequest; |
89 | |
90 | // Quick check: if the "form name" field hasn't been sent, |
91 | // it means the main "Form" checkbox wasn't selected; don't |
92 | // create any XML if so. |
93 | if ( !$wgRequest->getCheck( 'pf_form_name' ) ) { |
94 | return ''; |
95 | } |
96 | |
97 | $formName = null; |
98 | $xml = ''; |
99 | $includeFreeText = false; |
100 | foreach ( $wgRequest->getValues() as $var => $val ) { |
101 | $val = str_replace( [ '<', '>' ], [ '<', '>' ], $val ); |
102 | if ( $var == 'pf_form_name' ) { |
103 | $formName = $val; |
104 | } elseif ( $var == 'pf_page_name_formula' ) { |
105 | if ( !empty( $val ) ) { |
106 | $val = Xml::escapeTagsOnly( $val ); |
107 | $xml .= '<PageNameFormula>' . $val . '</PageNameFormula>'; |
108 | } |
109 | } elseif ( $var == 'pf_create_title' ) { |
110 | if ( !empty( $val ) ) { |
111 | $xml .= '<CreateTitle>' . $val . '</CreateTitle>'; |
112 | } |
113 | } elseif ( $var == 'pf_edit_title' ) { |
114 | if ( !empty( $val ) ) { |
115 | $xml .= '<EditTitle>' . $val . '</EditTitle>'; |
116 | } |
117 | } elseif ( $var == 'pf_fi_free_text' && !empty( $val ) ) { |
118 | $includeFreeText = true; |
119 | $xml .= '<standardInputs inputFreeText="1" '; |
120 | } elseif ( $includeFreeText && $var == 'pf_fi_free_text_label' ) { |
121 | if ( !empty( $val ) ) { |
122 | $xml .= 'freeTextLabel="' . Xml::escapeTagsOnly( $val ) . '" '; |
123 | } |
124 | } |
125 | } |
126 | if ( $includeFreeText ) { |
127 | $xml .= ' />'; |
128 | } |
129 | $xml = '<pageforms_Form name="' . $formName . '" >' . $xml; |
130 | $xml .= '</pageforms_Form>'; |
131 | return $xml; |
132 | } |
133 | |
134 | /** |
135 | * Creates Page Schemas XML from form information on templates. |
136 | * @return string[] |
137 | */ |
138 | public static function createTemplateXMLFromForm() { |
139 | global $wgRequest; |
140 | |
141 | $xmlPerTemplate = []; |
142 | $templateNum = -1; |
143 | $xml = ''; |
144 | foreach ( $wgRequest->getValues() as $var => $val ) { |
145 | $val = str_replace( [ '<', '>' ], [ '<', '>' ], $val ); |
146 | if ( substr( $var, 0, 18 ) === 'pf_template_label_' ) { |
147 | $templateNum = substr( $var, 18 ); |
148 | $xml = '<pageforms_TemplateDetails>'; |
149 | if ( !empty( $val ) ) { |
150 | $xml .= "<Label>$val</Label>"; |
151 | } |
152 | } elseif ( substr( $var, 0, 23 ) === 'pf_template_addanother_' ) { |
153 | if ( !empty( $val ) ) { |
154 | $xml .= "<AddAnotherText>$val</AddAnotherText>"; |
155 | } |
156 | $xml .= '</pageforms_TemplateDetails>'; |
157 | $xmlPerTemplate[$templateNum] = $xml; |
158 | } |
159 | } |
160 | return $xmlPerTemplate; |
161 | } |
162 | |
163 | /** |
164 | * Creates Page Schemas XML for form fields. |
165 | * @return string[] |
166 | */ |
167 | public static function createFieldXMLFromForm() { |
168 | global $wgRequest; |
169 | |
170 | $xmlPerField = []; |
171 | $fieldNum = -1; |
172 | $xml = ''; |
173 | foreach ( $wgRequest->getValues() as $var => $val ) { |
174 | $val = str_replace( [ '<', '>' ], [ '<', '>' ], $val ); |
175 | if ( substr( $var, 0, 14 ) === 'pf_input_type_' ) { |
176 | $fieldNum = substr( $var, 14 ); |
177 | $xml = '<pageforms_FormInput>'; |
178 | if ( !empty( $val ) ) { |
179 | $xml .= '<InputType>' . $val . '</InputType>'; |
180 | } |
181 | } elseif ( substr( $var, 0, 14 ) === 'pf_key_values_' ) { |
182 | $xml .= self::createFormInputXMLFromForm( $val ); |
183 | } elseif ( substr( $var, 0, 14 ) === 'pf_input_befo_' ) { |
184 | if ( $val !== '' ) { |
185 | $xml .= '<TextBeforeField>' . $val . '</TextBeforeField>'; |
186 | } |
187 | } elseif ( substr( $var, 0, 14 ) === 'pf_input_desc_' ) { |
188 | if ( $val !== '' ) { |
189 | $xml .= '<Description>' . $val . '</Description>'; |
190 | } |
191 | } elseif ( substr( $var, 0, 18 ) === 'pf_input_desctool_' ) { |
192 | if ( $val !== '' ) { |
193 | $xml .= '<DescriptionTooltipMode>' . $val . '</DescriptionTooltipMode>'; |
194 | } |
195 | } elseif ( substr( $var, 0, 16 ) === 'pf_input_finish_' ) { |
196 | // This is a hack. |
197 | $xml .= '</pageforms_FormInput>'; |
198 | $xmlPerField[$fieldNum] = $xml; |
199 | } |
200 | } |
201 | return $xmlPerField; |
202 | } |
203 | |
204 | /** |
205 | * Creates Page Schemas XML for page sections |
206 | * @return string[] |
207 | */ |
208 | public static function createPageSectionXMLFromForm() { |
209 | global $wgRequest; |
210 | $xmlPerPageSection = []; |
211 | $pageSectionNum = -1; |
212 | |
213 | foreach ( $wgRequest->getValues() as $var => $val ) { |
214 | $val = str_replace( [ '<', '>' ], [ '<', '>' ], $val ); |
215 | if ( substr( $var, 0, 26 ) == 'pf_pagesection_key_values_' ) { |
216 | $pageSectionNum = substr( $var, 26 ); |
217 | $xml = ""; |
218 | if ( $val != '' ) { |
219 | $xml = '<pageforms_PageSection>'; |
220 | $xml .= self::createFormInputXMLFromForm( $val ); |
221 | $xml .= '</pageforms_PageSection>'; |
222 | } |
223 | $xmlPerPageSection[$pageSectionNum] = $xml; |
224 | } |
225 | } |
226 | return $xmlPerPageSection; |
227 | } |
228 | |
229 | static function createFormInputXMLFromForm( $valueFromForm ) { |
230 | $xml = ''; |
231 | if ( $valueFromForm !== '' ) { |
232 | // replace the comma substitution character that has no chance of |
233 | // being included in the values list - namely, the ASCII beep |
234 | $listSeparator = ','; |
235 | $key_values_str = str_replace( "\\$listSeparator", "\a", $valueFromForm ); |
236 | $key_values_array = explode( $listSeparator, $key_values_str ); |
237 | foreach ( $key_values_array as $value ) { |
238 | // replace beep back with comma, trim |
239 | $value = str_replace( "\a", $listSeparator, trim( $value ) ); |
240 | $param_value = explode( "=", $value, 2 ); |
241 | if ( count( $param_value ) == 2 && $param_value[1] != null ) { |
242 | // Handles <Parameter name="size">20</Parameter> |
243 | $xml .= '<Parameter name="' . $param_value[0] . '">' . $param_value[1] . '</Parameter>'; |
244 | } else { |
245 | // Handles <Parameter name="mandatory" /> |
246 | $xml .= '<Parameter name="' . $param_value[0] . '"/>'; |
247 | } |
248 | } |
249 | } |
250 | return $xml; |
251 | } |
252 | |
253 | public static function getDisplayColor() { |
254 | return '#CF9'; |
255 | } |
256 | |
257 | public static function getSchemaDisplayString() { |
258 | return wfMessage( 'pf-pageschemas-header' )->escaped(); |
259 | } |
260 | |
261 | public static function getSchemaEditingHTML( $pageSchemaObj ) { |
262 | $form_array = []; |
263 | $hasExistingValues = false; |
264 | if ( $pageSchemaObj !== null ) { |
265 | $form_array = $pageSchemaObj->getObject( 'pageforms_Form' ); |
266 | if ( $form_array !== null ) { |
267 | $hasExistingValues = true; |
268 | } |
269 | } |
270 | |
271 | // Get all the values from the page schema. |
272 | $formName = PageSchemas::getValueFromObject( $form_array, 'name' ); |
273 | $pageNameFormula = PageSchemas::getValueFromObject( $form_array, 'PageNameFormula' ); |
274 | $createTitle = PageSchemas::getValueFromObject( $form_array, 'CreateTitle' ); |
275 | $editTitle = PageSchemas::getValueFromObject( $form_array, 'EditTitle' ); |
276 | |
277 | // Inputs |
278 | if ( $pageSchemaObj !== null ) { |
279 | $standardInputs = $pageSchemaObj->getObject( 'standardInputs' ); |
280 | $includeFreeText = isset( $standardInputs['inputFreeText'] ) ? $standardInputs['inputFreeText'] : false; |
281 | } else { |
282 | $includeFreeText = true; |
283 | } |
284 | |
285 | $freeTextLabel = html_entity_decode( PageSchemas::getValueFromObject( $form_array, 'freeTextLabel' ) ); |
286 | |
287 | $text = "\t<p>" . wfMessage( 'ps-namelabel' )->escaped() . ' ' . Html::input( 'pf_form_name', $formName, 'text', [ 'size' => 15 ] ) . "</p>\n"; |
288 | // The checkbox isn't actually a field in the page schema - |
289 | // we set it based on whether or not a page formula has been |
290 | // specified. |
291 | $twoStepProcessAttrs = [ 'id' => 'pf-two-step-process' ]; |
292 | if ( $pageNameFormula === null ) { |
293 | $twoStepProcessAttrs['checked'] = true; |
294 | } |
295 | $text .= '<p>' . Html::input( 'pf_two_step_process', null, 'checkbox', $twoStepProcessAttrs ); |
296 | $text .= ' Users must enter the page name before getting to the form (default)'; |
297 | $text .= "</p>\n"; |
298 | $text .= '<div class="editSchemaMinorFields">'; |
299 | $text .= "\t<p id=\"pf-page-name-formula\">" . wfMessage( 'pf-pageschemas-pagenameformula' )->escaped() . ' ' . |
300 | Html::input( 'pf_page_name_formula', $pageNameFormula, 'text', [ 'size' => 30 ] ) . "</p>\n"; |
301 | $text .= "\t<p>" . wfMessage( 'pf-pageschemas-createtitle' )->escaped() . ' ' . |
302 | Html::input( 'pf_create_title', $createTitle, 'text', [ 'size' => 25 ] ) . "</p>\n"; |
303 | $text .= "\t<p id=\"pf-edit-title\">" . wfMessage( 'pf-pageschemas-edittitle' )->escaped() . ' ' . |
304 | Html::input( 'pf_edit_title', $editTitle, 'text', [ 'size' => 25 ] ) . "</p>\n"; |
305 | |
306 | // This checkbox went from a default of false to true in PF 5.2. |
307 | $text .= '<p>'; |
308 | $text .= Html::input( 'pf_fi_free_text', '1', 'checkbox', [ 'id' => 'pf_fi_free_text', 'checked' => $includeFreeText ] ) . ' '; |
309 | $text .= Html::rawElement( 'label', [ 'for' => 'pf_fi_free_text' ], wfMessage( 'pf-pageschemas-includefreetextinput' )->escaped() ); |
310 | $text .= "</p>"; |
311 | |
312 | if ( empty( $freeTextLabel ) ) { |
313 | $freeTextLabel = wfMessage( 'pf_form_freetextlabel' )->inContentLanguage()->text(); |
314 | } |
315 | $text .= '<p>' . wfMessage( 'pf-pageschemas-freetextlabel' )->escaped() . ' ' . |
316 | Html::input( 'pf_fi_free_text_label', $freeTextLabel, 'text' ) . "</p>"; |
317 | |
318 | $text .= "</div>\n"; |
319 | |
320 | global $wgOut; |
321 | // Separately, add Javascript for getting the checkbox to |
322 | // hide certain fields. |
323 | $wgOut->addModules( [ 'ext.pageforms.PF_PageSchemas' ] ); |
324 | |
325 | return [ $text, $hasExistingValues ]; |
326 | } |
327 | |
328 | public static function getTemplateEditingHTML( $psTemplate ) { |
329 | $hasExistingValues = false; |
330 | $templateLabel = null; |
331 | $addAnotherText = null; |
332 | if ( $psTemplate !== null ) { |
333 | $form_array = $psTemplate->getObject( 'pageforms_TemplateDetails' ); |
334 | if ( $form_array !== null ) { |
335 | $hasExistingValues = true; |
336 | $templateLabel = PageSchemas::getValueFromObject( $form_array, 'Label' ); |
337 | $addAnotherText = PageSchemas::getValueFromObject( $form_array, 'AddAnotherText' ); |
338 | } |
339 | } |
340 | |
341 | $text = "\t<p>" . wfMessage( 'pf-pageschemas-templatedetailslabel' )->escaped() . "</p>\n"; |
342 | $text .= "\t<p>" . wfMessage( 'exif-label' )->escaped() . ': ' . |
343 | Html::input( 'pf_template_label_num', $templateLabel, 'text', [ 'size' => 15 ] ) . "</p>\n"; |
344 | $text .= "\t<p>" . 'Text of button to add another instance (default is "Add another"):' . ' ' . |
345 | Html::input( 'pf_template_addanother_num', $addAnotherText, 'text', [ 'size' => 25 ] ) . "</p>\n"; |
346 | |
347 | return [ $text, $hasExistingValues ]; |
348 | } |
349 | |
350 | /** |
351 | * Returns the HTML for inputs to define a single form field, |
352 | * within the Page Schemas 'edit schema' page. |
353 | * @param PSTemplateField $psField |
354 | * @return array |
355 | */ |
356 | public static function getFieldEditingHTML( $psField ) { |
357 | $fieldValues = []; |
358 | $hasExistingValues = false; |
359 | $inputType = null; |
360 | $inputDesc = null; |
361 | $inputDescTooltipMode = null; |
362 | $inputBeforeText = null; |
363 | if ( $psField !== null ) { |
364 | $fieldValues = $psField->getObject( 'pageforms_FormInput' ); |
365 | if ( $fieldValues !== null ) { |
366 | $hasExistingValues = true; |
367 | $inputType = PageSchemas::getValueFromObject( $fieldValues, 'InputType' ); |
368 | $inputDesc = PageSchemas::getValueFromObject( $fieldValues, 'Description' ); |
369 | $inputDescTooltipMode = PageSchemas::getValueFromObject( $fieldValues, 'DescriptionTooltipMode' ); |
370 | $inputBeforeText = PageSchemas::getValueFromObject( $fieldValues, 'TextBeforeField' ); |
371 | } else { |
372 | $fieldValues = []; |
373 | } |
374 | } |
375 | |
376 | global $wgPageFormsFormPrinter; |
377 | $possibleInputTypes = $wgPageFormsFormPrinter->getAllInputTypes(); |
378 | $inputTypeDropdownHTML = Html::element( 'option', null, null ); |
379 | foreach ( $possibleInputTypes as $possibleInputType ) { |
380 | $inputTypeOptionAttrs = []; |
381 | if ( $possibleInputType == $inputType ) { |
382 | $inputTypeOptionAttrs['selected'] = true; |
383 | } |
384 | $inputTypeDropdownHTML .= Html::element( 'option', $inputTypeOptionAttrs, $possibleInputType ) . "\n"; |
385 | } |
386 | $inputTypeDropdown = Html::rawElement( 'select', [ 'name' => 'pf_input_type_num' ], $inputTypeDropdownHTML ); |
387 | $text = '<p>' . wfMessage( 'pf-pageschemas-inputtype' )->escaped() . ' ' . $inputTypeDropdown . '</p>'; |
388 | |
389 | $text .= "\t" . '<p>' . wfMessage( 'pf-pageschemas-otherparams', 'size=20, mandatory' )->escaped() . '</p>' . "\n"; |
390 | $paramValues = []; |
391 | foreach ( $fieldValues as $param => $value ) { |
392 | if ( !empty( $param ) && $param != 'InputType' && $param != 'Description' && $param != 'DescriptionTooltipMode' && $param != 'TextBeforeField' ) { |
393 | if ( !empty( $value ) ) { |
394 | $paramValues[] = $param . '=' . $value; |
395 | } else { |
396 | $paramValues[] = $param; |
397 | } |
398 | } |
399 | } |
400 | foreach ( $paramValues as $i => $paramAndVal ) { |
401 | $paramValues[$i] = str_replace( ',', '\,', $paramAndVal ); |
402 | } |
403 | $param_value_str = implode( ', ', $paramValues ); |
404 | $inputParamsAttrs = [ 'size' => 80 ]; |
405 | $inputParamsInput = Html::input( 'pf_key_values_num', $param_value_str, 'text', $inputParamsAttrs ); |
406 | $text .= "\t<p>$inputParamsInput</p>\n"; |
407 | |
408 | $text .= '<div class="editSchemaMinorFields">' . "\n"; |
409 | $inputBeforeTextPrint = Html::input( 'pf_input_befo_num', $inputBeforeText, 'text', [ 'size' => 80 ] ); |
410 | $text .= "\t<p>Text that will be printed before the field: $inputBeforeTextPrint</p>\n"; |
411 | |
412 | $inputDescriptionLabel = wfMessage( 'pf-pageschemas-inputdescription' )->parse(); |
413 | $inputDescription = Html::input( 'pf_input_desc_num', $inputDesc, 'text', [ 'size' => 80 ] ); |
414 | $inputDescriptionTooltipMode = Html::input( 'pf_input_desctool_num', $inputDescTooltipMode, 'checkbox', [ 'checked' => ( $inputDescTooltipMode ) ? 'checked' : null ] ); |
415 | $useTooltipLabel = wfMessage( 'pf-pageschemas-usetooltip' )->escaped(); |
416 | $text .= "\t<p>$inputDescriptionLabel $inputDescription<br>$inputDescriptionTooltipMode $useTooltipLabel</p>\n"; |
417 | |
418 | // @HACK to make input parsing easier. |
419 | $text .= Html::hidden( 'pf_input_finish_num', 1 ); |
420 | |
421 | $text .= "</div>\n"; |
422 | |
423 | return [ $text, $hasExistingValues ]; |
424 | } |
425 | |
426 | public static function getPageSectionEditingHTML( $psPageSection ) { |
427 | $otherParams = []; |
428 | |
429 | if ( $psPageSection !== null ) { |
430 | $otherParams = $psPageSection->getObject( 'pageforms_PageSection' ); |
431 | } |
432 | $paramValues = []; |
433 | if ( $otherParams !== null ) { |
434 | foreach ( $otherParams as $param => $value ) { |
435 | if ( !empty( $param ) ) { |
436 | if ( !empty( $value ) ) { |
437 | $paramValues[] = $param . '=' . $value; |
438 | } else { |
439 | $paramValues[] = $param; |
440 | } |
441 | } |
442 | } |
443 | } |
444 | |
445 | foreach ( $paramValues as $i => $paramAndVal ) { |
446 | $paramValues[$i] = str_replace( ',', '\,', $paramAndVal ); |
447 | } |
448 | $param_value_str = implode( ', ', $paramValues ); |
449 | $text = "\t" . '<p>' . wfMessage( 'pf-pageschemas-otherparams', 'rows=10, mandatory' )->escaped() . '</p>' . "\n"; |
450 | $inputParamsInput = Html::input( 'pf_pagesection_key_values_num', $param_value_str, 'text', [ 'size' => 80 ] ); |
451 | $text .= "\t<p>$inputParamsInput</p>\n"; |
452 | |
453 | return $text; |
454 | } |
455 | |
456 | public static function getFormName( $pageSchemaObj ) { |
457 | $mainFormInfo = self::getMainFormInfo( $pageSchemaObj ); |
458 | if ( $mainFormInfo === null || !array_key_exists( 'name', $mainFormInfo ) ) { |
459 | return null; |
460 | } |
461 | return $mainFormInfo['name']; |
462 | } |
463 | |
464 | public static function getMainFormInfo( $pageSchemaObj ) { |
465 | // return $pageSchemaObj->getObject( 'pageforms_Form' ); |
466 | // We don't just call getObject() here, because sometimes, for |
467 | // some reason, this gets called before PF registers itself |
468 | // with Page Schemas, which means that getObject() would return |
469 | // null. Instead, we directly call the code that would have |
470 | // been called. |
471 | $xml = $pageSchemaObj->getXML(); |
472 | foreach ( $xml->children() as $tag => $child ) { |
473 | if ( $tag == "pageforms_Form" ) { |
474 | $pfarray = []; |
475 | $formName = (string)$child->attributes()->name; |
476 | $pfarray['name'] = $formName; |
477 | foreach ( $child->children() as $childTag => $formelem ) { |
478 | if ( $childTag == "standardInputs" ) { |
479 | foreach ( $formelem->attributes() as $attr => $value ) { |
480 | $pfarray[$attr] = (string)$formelem->attributes()->$attr; |
481 | } |
482 | } else { |
483 | $pfarray[$childTag] = (string)$formelem; |
484 | } |
485 | } |
486 | return $pfarray; |
487 | } |
488 | } |
489 | return []; |
490 | } |
491 | |
492 | public static function getFormFieldInfo( $psTemplate, $template_fields ) { |
493 | $form_fields = []; |
494 | $fieldsInfo = $psTemplate->getFields(); |
495 | foreach ( $fieldsInfo as $i => $psField ) { |
496 | $fieldFormArray = $psField->getObject( 'pageforms_FormInput' ); |
497 | if ( $fieldFormArray === null ) { |
498 | continue; |
499 | } |
500 | $formField = PFFormField::create( $template_fields[$i] ); |
501 | foreach ( $fieldFormArray as $var => $val ) { |
502 | if ( $var == 'InputType' ) { |
503 | $formField->setInputType( $val ); |
504 | } elseif ( $var == 'mandatory' ) { |
505 | $formField->setIsMandatory( true ); |
506 | } elseif ( $var == 'hidden' ) { |
507 | $formField->setIsHidden( true ); |
508 | } elseif ( $var == 'restricted' ) { |
509 | $formField->setIsRestricted( true ); |
510 | } elseif ( in_array( $var, [ 'Description', 'DescriptionTooltipMode', 'TextBeforeField' ] ) ) { |
511 | $formField->setDescriptionArg( $var, $val ); |
512 | } else { |
513 | $formField->setFieldArg( $var, $val ); |
514 | } |
515 | } |
516 | $form_fields[] = $formField; |
517 | } |
518 | return $form_fields; |
519 | } |
520 | |
521 | public static function getPageSection( $psPageSection ) { |
522 | $pageSection = PFPageSection::create( $psPageSection->getSectionName() ); |
523 | $pageSectionArray = $psPageSection->getObject( 'pageforms_PageSection' ); |
524 | if ( $pageSectionArray == null ) { |
525 | return null; |
526 | } |
527 | |
528 | foreach ( $pageSectionArray as $var => $val ) { |
529 | if ( $var == 'mandatory' ) { |
530 | $pageSection->setIsMandatory( true ); |
531 | } elseif ( $var == 'hidden' ) { |
532 | $pageSection->setIsHidden( true ); |
533 | } elseif ( $var == 'restricted' ) { |
534 | $pageSection->setIsRestricted( true ); |
535 | } else { |
536 | $pageSection->setSectionArgs( $var, $val ); |
537 | } |
538 | } |
539 | |
540 | return $pageSection; |
541 | } |
542 | |
543 | /** |
544 | * Return the list of pages that Page Forms could generate from |
545 | * the current Page Schemas schema. |
546 | * @param PFPageSchemas $pageSchemaObj |
547 | * @return Title[] |
548 | */ |
549 | public static function getPagesToGenerate( $pageSchemaObj ) { |
550 | $genPageList = []; |
551 | $psTemplates = $pageSchemaObj->getTemplates(); |
552 | foreach ( $psTemplates as $psTemplate ) { |
553 | $title = Title::makeTitleSafe( NS_TEMPLATE, $psTemplate->getName() ); |
554 | $genPageList[] = $title; |
555 | } |
556 | $form_name = self::getFormName( $pageSchemaObj ); |
557 | if ( $form_name != null ) { |
558 | $title = Title::makeTitleSafe( PF_NS_FORM, $form_name ); |
559 | $genPageList[] = $title; |
560 | } |
561 | |
562 | return $genPageList; |
563 | } |
564 | |
565 | /** |
566 | * Returns an array of PFTemplateField objects, representing the fields |
567 | * of a template, based on the contents of a <PageSchema> tag. |
568 | * @param PFTemplate $psTemplate |
569 | * @return PFTemplateField[] |
570 | */ |
571 | public static function getFieldsFromTemplateSchema( $psTemplate ) { |
572 | $psFields = $psTemplate->getFields(); |
573 | $templateFields = []; |
574 | foreach ( $psFields as $psField ) { |
575 | if ( defined( 'SMW_VERSION' ) ) { |
576 | $prop_array = $psField->getObject( 'semanticmediawiki_Property' ); |
577 | $propertyName = PageSchemas::getValueFromObject( $prop_array, 'name' ); |
578 | if ( $prop_array !== null && empty( $propertyName ) ) { |
579 | $propertyName = $psField->getName(); |
580 | } |
581 | } else { |
582 | $propertyName = null; |
583 | } |
584 | |
585 | if ( $psField->getLabel() === '' ) { |
586 | $fieldLabel = $psField->getName(); |
587 | } else { |
588 | $fieldLabel = $psField->getLabel(); |
589 | } |
590 | $templateField = PFTemplateField::create( |
591 | $psField->getName(), |
592 | $fieldLabel, |
593 | $propertyName, |
594 | $psField->isList(), |
595 | $psField->getDelimiter(), |
596 | $psField->getDisplay() |
597 | ); |
598 | $templateField->setNSText( $psField->getNamespace() ); |
599 | if ( defined( 'CARGO_VERSION' ) ) { |
600 | $cargoFieldArray = $psField->getObject( 'cargo_Field' ); |
601 | $fieldType = PageSchemas::getValueFromObject( $cargoFieldArray, 'Type' ); |
602 | $allowedValues = PageSchemas::getValueFromObject( $cargoFieldArray, 'AllowedValues' ); |
603 | if ( $fieldType != '' ) { |
604 | $templateField->setFieldType( $fieldType ); |
605 | $templateField->setPossibleValues( $allowedValues ); |
606 | } |
607 | } |
608 | |
609 | $templateFields[] = $templateField; |
610 | } |
611 | return $templateFields; |
612 | } |
613 | |
614 | /** |
615 | * Creates a form page, when called from the 'generatepages' page |
616 | * of Page Schemas. |
617 | * @param string $formName |
618 | * @param Title $formTitle |
619 | * @param array $formItems |
620 | * @param array $formDataFromSchema |
621 | * @param string $categoryName |
622 | */ |
623 | public static function generateForm( $formName, $formTitle, |
624 | $formItems, $formDataFromSchema, $categoryName ) { |
625 | $includeFreeText = array_key_exists( 'inputFreeText', $formDataFromSchema ); |
626 | $freeTextLabel = null; |
627 | if ( $includeFreeText && array_key_exists( 'freeTextLabel', $formDataFromSchema ) ) { |
628 | $freeTextLabel = $formDataFromSchema['freeTextLabel']; |
629 | } |
630 | |
631 | $form = PFForm::create( $formName, $formItems ); |
632 | $form->setAssociatedCategory( $categoryName ); |
633 | if ( array_key_exists( 'PageNameFormula', $formDataFromSchema ) ) { |
634 | $form->setPageNameFormula( $formDataFromSchema['PageNameFormula'] ); |
635 | } |
636 | if ( array_key_exists( 'CreateTitle', $formDataFromSchema ) ) { |
637 | $form->setCreateTitle( $formDataFromSchema['CreateTitle'] ); |
638 | } |
639 | if ( array_key_exists( 'EditTitle', $formDataFromSchema ) ) { |
640 | $form->setEditTitle( $formDataFromSchema['EditTitle'] ); |
641 | } |
642 | |
643 | $user = RequestContext::getMain()->getUser(); |
644 | |
645 | $formContents = $form->createMarkup( $includeFreeText, $freeTextLabel ); |
646 | $params = []; |
647 | $params['user_id'] = $user->getId(); |
648 | $params['page_text'] = $formContents; |
649 | $job = new PSCreatePageJob( $formTitle, $params ); |
650 | |
651 | $jobs = [ $job ]; |
652 | if ( method_exists( MediaWikiServices::class, 'getJobQueueGroup' ) ) { |
653 | // MW 1.37+ |
654 | MediaWikiServices::getInstance()->getJobQueueGroup()->push( $jobs ); |
655 | } else { |
656 | JobQueueGroup::singleton()->push( $jobs ); |
657 | } |
658 | } |
659 | |
660 | /** |
661 | * Generate pages (form and templates) specified in the list. |
662 | * @param PageSchemas $pageSchemaObj |
663 | * @param array $selectedPages |
664 | */ |
665 | public static function generatePages( $pageSchemaObj, $selectedPages ) { |
666 | if ( $selectedPages == null ) { |
667 | return; |
668 | } |
669 | |
670 | $user = RequestContext::getMain()->getUser(); |
671 | |
672 | $psFormItems = $pageSchemaObj->getFormItemsList(); |
673 | $form_items = []; |
674 | $jobs = []; |
675 | $templateHackUsed = false; |
676 | $isCategoryNameSet = false; |
677 | |
678 | // Generate every specified template |
679 | foreach ( $psFormItems as $psFormItem ) { |
680 | if ( $psFormItem['type'] == 'Template' ) { |
681 | $psTemplate = $psFormItem['item']; |
682 | $templateName = $psTemplate->getName(); |
683 | $templateTitle = Title::makeTitleSafe( NS_TEMPLATE, $templateName ); |
684 | $fullTemplateName = $templateTitle->getPrefixedText(); |
685 | $template_fields = self::getFieldsFromTemplateSchema( $psTemplate ); |
686 | // Get property for use in either #set_internal |
687 | // or #subobject, defined by either SIO's or |
688 | // SMW's Page Schemas portion. We don't need |
689 | // to record which one it came from, because |
690 | // PF's code to generate the template runs its |
691 | // own, similar check. |
692 | // @TODO - $internalObjProperty should probably |
693 | // have a more generic name. |
694 | if ( class_exists( 'SIOPageSchemas' ) ) { |
695 | $internalObjProperty = SIOPageSchemas::getInternalObjectPropertyName( $psTemplate ); |
696 | } elseif ( method_exists( 'SMWPageSchemas', 'getConnectingPropertyName' ) ) { |
697 | $internalObjProperty = SMWPageSchemas::getConnectingPropertyName( $psTemplate ); |
698 | } else { |
699 | $internalObjProperty = null; |
700 | } |
701 | // TODO - actually, the category-setting should be |
702 | // smarter than this: if there's more than one |
703 | // template in the schema, it should probably be only |
704 | // the first non-multiple template that includes the |
705 | // category tag. |
706 | if ( $psTemplate->isMultiple() ) { |
707 | $categoryName = null; |
708 | } else { |
709 | if ( $isCategoryNameSet == false ) { |
710 | $categoryName = $pageSchemaObj->getCategoryName(); |
711 | $isCategoryNameSet = true; |
712 | } else { |
713 | $categoryName = null; |
714 | } |
715 | |
716 | } |
717 | if ( method_exists( $psTemplate, 'getFormat' ) ) { |
718 | $templateFormat = $psTemplate->getFormat(); |
719 | } else { |
720 | $templateFormat = null; |
721 | } |
722 | |
723 | $pfTemplate = new PFTemplate( $templateName, $template_fields ); |
724 | $pfTemplate->setConnectingProperty( $internalObjProperty ); |
725 | $pfTemplate->setCategoryName( $categoryName ); |
726 | $pfTemplate->setFormat( $templateFormat ); |
727 | |
728 | // Set Cargo table, if one was set in the schema. |
729 | $cargoArray = $psTemplate->getObject( 'cargo_TemplateDetails' ); |
730 | if ( $cargoArray !== null ) { |
731 | $cargoTable = PageSchemas::getValueFromObject( $cargoArray, 'Table' ); |
732 | $pfTemplate->setCargoTable( $cargoTable ); |
733 | } |
734 | |
735 | $templateText = $pfTemplate->createText(); |
736 | |
737 | if ( in_array( $fullTemplateName, $selectedPages ) ) { |
738 | $params = []; |
739 | $params['user_id'] = $user->getId(); |
740 | $params['page_text'] = $templateText; |
741 | $jobs[] = new PSCreatePageJob( $templateTitle, $params ); |
742 | if ( strpos( $templateText, '{{!}}' ) > 0 ) { |
743 | $templateHackUsed = true; |
744 | } |
745 | } |
746 | |
747 | $templateValues = self::getTemplateValues( $psTemplate ); |
748 | if ( array_key_exists( 'Label', $templateValues ) ) { |
749 | $templateLabel = $templateValues['Label']; |
750 | } else { |
751 | $templateLabel = null; |
752 | } |
753 | $form_fields = self::getFormFieldInfo( $psTemplate, $template_fields ); |
754 | // Create template info for form, for use in generating |
755 | // the form (if it will be generated). |
756 | $form_template = PFTemplateInForm::create( |
757 | $templateName, |
758 | $templateLabel, |
759 | $psTemplate->isMultiple(), |
760 | null, |
761 | $form_fields |
762 | ); |
763 | $form_items[] = [ 'type' => 'template', 'name' => $form_template->getTemplateName(), 'item' => $form_template ]; |
764 | } elseif ( $psFormItem['type'] == 'Section' ) { |
765 | $psPageSection = $psFormItem['item']; |
766 | $form_section = self::getPageSection( $psPageSection ); |
767 | if ( $form_section !== null ) { |
768 | $form_section->setSectionLevel( $psPageSection->getSectionLevel() ); |
769 | $form_items[] = [ 'type' => 'section', 'name' => $form_section->getSectionName(), 'item' => $form_section ]; |
770 | } |
771 | } |
772 | |
773 | } |
774 | |
775 | // Create the "!" hack template, if it's necessary |
776 | if ( $templateHackUsed ) { |
777 | $templateTitle = Title::makeTitleSafe( NS_TEMPLATE, '!' ); |
778 | if ( !$templateTitle->exists() ) { |
779 | $params = []; |
780 | $params['user_id'] = $user->getId(); |
781 | $params['page_text'] = '|'; |
782 | $jobs[] = new PSCreatePageJob( $templateTitle, $params ); |
783 | } |
784 | } |
785 | |
786 | if ( method_exists( MediaWikiServices::class, 'getJobQueueGroup' ) ) { |
787 | // MW 1.37+ |
788 | MediaWikiServices::getInstance()->getJobQueueGroup()->push( $jobs ); |
789 | } else { |
790 | JobQueueGroup::singleton()->push( $jobs ); |
791 | } |
792 | |
793 | // Create form, if it's specified. |
794 | $formName = self::getFormName( $pageSchemaObj ); |
795 | $categoryName = $pageSchemaObj->getCategoryName(); |
796 | if ( !empty( $formName ) ) { |
797 | $formInfo = self::getMainFormInfo( $pageSchemaObj ); |
798 | $formTitle = Title::makeTitleSafe( PF_NS_FORM, $formName ); |
799 | $fullFormName = $formTitle->getPrefixedText(); |
800 | if ( in_array( $fullFormName, $selectedPages ) ) { |
801 | self::generateForm( $formName, $formTitle, |
802 | $form_items, $formInfo, $categoryName ); |
803 | } |
804 | } |
805 | } |
806 | |
807 | public static function getSchemaDisplayValues( $schemaXML ) { |
808 | foreach ( $schemaXML->children() as $tag => $child ) { |
809 | if ( $tag == "pageforms_Form" ) { |
810 | $formName = $child->attributes()->name; |
811 | $values = []; |
812 | foreach ( $child->children() as $tagName => $prop ) { |
813 | $values[$tagName] = (string)$prop; |
814 | } |
815 | return [ $formName, $values ]; |
816 | } |
817 | } |
818 | return null; |
819 | } |
820 | |
821 | public static function getTemplateValues( $psTemplate ) { |
822 | // TODO - fix this. |
823 | $values = []; |
824 | if ( $psTemplate instanceof PSTemplate ) { |
825 | $psTemplate = $psTemplate->getXML(); |
826 | } |
827 | // @phan-suppress-next-line PhanNonClassMethodCall |
828 | foreach ( $psTemplate->children() as $tag => $child ) { |
829 | if ( $tag == "pageforms_TemplateDetails" ) { |
830 | foreach ( $child->children() as $prop ) { |
831 | $values[$prop->getName()] = (string)$prop; |
832 | } |
833 | } |
834 | } |
835 | return $values; |
836 | } |
837 | |
838 | public static function getTemplateDisplayString() { |
839 | return wfMessage( 'pf-pageschemas-templatedetails' )->escaped(); |
840 | } |
841 | |
842 | /** |
843 | * Displays form details for one template in the Page Schemas XML. |
844 | * @param string $templateXML |
845 | * @return null|array |
846 | */ |
847 | public static function getTemplateDisplayValues( $templateXML ) { |
848 | $templateValues = self::getTemplateValues( $templateXML ); |
849 | if ( count( $templateValues ) == 0 ) { |
850 | return null; |
851 | } |
852 | |
853 | $displayValues = []; |
854 | foreach ( $templateValues as $key => $value ) { |
855 | if ( $key == 'Label' ) { |
856 | $propName = wfMessage( 'exif-label' )->escaped(); |
857 | } elseif ( $key == 'AddAnotherText' ) { |
858 | $propName = "'Add another' button"; |
859 | } |
860 | $displayValues[$propName] = $value; |
861 | } |
862 | return [ null, $displayValues ]; |
863 | } |
864 | |
865 | public static function getFieldDisplayString() { |
866 | return wfMessage( 'pf-pageschemas-forminput' )->parse(); |
867 | } |
868 | |
869 | public static function getPageSectionDisplayString() { |
870 | return wfMessage( 'ps-otherparams' )->text(); |
871 | } |
872 | |
873 | /** |
874 | * Displays data on a single form input in the Page Schemas XML. |
875 | * @param Node $fieldXML |
876 | * @return array|null |
877 | * @suppress PhanUndeclaredTypeParameter |
878 | */ |
879 | public static function getFieldDisplayValues( $fieldXML ) { |
880 | foreach ( $fieldXML->children() as $tag => $child ) { |
881 | if ( $tag == "pageforms_FormInput" ) { |
882 | $inputName = $child->attributes()->name; |
883 | $values = []; |
884 | foreach ( $child->children() as $prop ) { |
885 | if ( $prop->getName() == 'InputType' ) { |
886 | $propName = 'Input type'; |
887 | } else { |
888 | $propName = (string)$prop->attributes()->name; |
889 | } |
890 | $values[$propName] = (string)$prop; |
891 | } |
892 | return [ $inputName, $values ]; |
893 | } |
894 | } |
895 | return null; |
896 | } |
897 | |
898 | public static function getPageSectionDisplayValues( $pageSectionXML ) { |
899 | foreach ( $pageSectionXML->children() as $tag => $child ) { |
900 | if ( $tag == "pageforms_PageSection" ) { |
901 | $inputName = $child->attributes()->name; |
902 | $values = []; |
903 | foreach ( $child->children() as $prop ) { |
904 | $propName = (string)$prop->attributes()->name; |
905 | $values[$propName] = (string)$prop; |
906 | } |
907 | return [ $inputName, $values ]; |
908 | } |
909 | } |
910 | return null; |
911 | } |
912 | } |