r29908 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r29907‎ | r29908 | r29909 >
Date:00:13, 18 January 2008
Author:yaron
Status:old
Tags:
Comment:
Added wiki-text parsing for forms, plus handling for the new "info" tag
and its three currently-allowed properties: "partial form", "add title" and
"edit title"; this includes a whole set of code contributed by Harold
Solbrig for implementing a partial form
Modified paths:
  • /trunk/extensions/SemanticForms/includes/SF_FormPrinter.inc (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticForms/includes/SF_FormPrinter.inc
@@ -6,6 +6,7 @@
77 * @author Nils Oppermann
88 * @author Jeffrey Stuckman
99 * @author Matt Williamson
 10+ * @author Harold Solbrig
1011 */
1112
1213 class SFFormPrinter {
@@ -106,6 +107,32 @@
107108 $sfgTabIndex = 1;
108109 $sfgFieldNum = 1;
109110 $source_page_matches_this_form = false;
 111+ $form_page_title = NULL;
 112+ // $form_is_partial is true if:
 113+ // (a) 'partial' == 1 in the arguments
 114+ // (b) 'partial form' is found in the form definition
 115+ // in the latter case, it may remain false until close to the end of
 116+ // the parsing, so we have to assume that it will become a possibility
 117+ $form_is_partial = false;
 118+
 119+ // if we have existing content and we're not in an active replacement
 120+ // situation, preserve the original content. We do this because we want
 121+ // to pass the original content on IF this is a partial form
 122+ // TODO: A better approach here would be to pass the revision id of the
 123+ // existing page content through the replace value, which would
 124+ // minimize the html traffic and would allow us to do a concurrent
 125+ // update check. For now, we pass it through the hidden text field...
 126+
 127+ if (! $wgRequest->getCheck('partial')) {
 128+ $original_page_content = $existing_page_content;
 129+ } else {
 130+ $original_page_content = null;
 131+ if($wgRequest->getCheck('free_text')) {
 132+ $existing_page_content= $wgRequest->getVal('free_text');
 133+ $form_is_partial = true;
 134+ }
 135+ }
 136+
110137 // disable all form elements if user doesn't have edit permission -
111138 // two different checks are needed, because editing permissions can be
112139 // set in different ways
@@ -114,8 +141,7 @@
115142 $form_is_disabled = false;
116143 $form_text = "";
117144 // show "Your IP address will be recorded" warning if user is
118 - // anonymous - wikitext for bolding has to be replaced with HTML, until
119 - // FormPrinter can parse wikitext
 145+ // anonymous - wikitext for bolding has to be replaced with HTML
120146 if ($wgUser->isAnon()) {
121147 $anon_edit_warning = preg_replace("/'''(.*)'''/", "<strong>$1</strong>", wfMsg('anoneditwarning'));
122148 $form_text .= "<p>$anon_edit_warning</p>\n";
@@ -141,6 +167,19 @@
142168 $form_def = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_def);
143169 $form_def = strtr($form_def, array('<includeonly>' => '', '</includeonly>' => ''));
144170
 171+ // parse wiki-text
 172+ // add '<nowiki>' tags around every triple-bracketed form definition
 173+ // element, so that the wiki parser won't touch it - the parser will
 174+ // remove the '<nowiki>' tags, leaving us with what we need
 175+ global $sfgDisableWikiTextParsing;
 176+ if (! $sfgDisableWikiTextParsing) {
 177+ $form_def = strtr($form_def, array('{{{' => '<nowiki>{{{', '}}}' => '}}}</nowiki>'));
 178+ $parser = new Parser();
 179+ $parser->mOptions = new ParserOptions();
 180+ $parser->mOptions->initialiseFromUser($wgUser);
 181+ $form_def = $parser->parse($form_def, $this->mPageTitle, $parser->mOptions)->getText();
 182+ }
 183+
145184 // turn form definition file into an array of sections, one for each
146185 // template definition (plus the first section)
147186 $form_def_sections = array();
@@ -183,12 +222,14 @@
184223 // modified; is it necessary?
185224 $section = " " . $form_def_sections[$section_num];
186225
187 -$while_instance = 0;
188226 while ($brackets_loc = strpos($section, '{{{', $start_position)) {
189227 $brackets_end_loc = strpos($section, "}}}", $brackets_loc);
190228 $bracketed_string = substr($section, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
191229 $tag_components = explode('|', $bracketed_string);
192230 $tag_title = trim($tag_components[0]);
 231+ // =====================================================
 232+ // for template processing
 233+ // =====================================================
193234 if ($tag_title == 'for template') {
194235 $old_template_name = $template_name;
195236 $template_name = trim($tag_components[1]);
@@ -242,7 +283,7 @@
243284 // underlines in name
244285 $search_template_str = str_replace('/', '\/', $tif->template_name);
245286 $search_template_str = preg_replace('/[_| ]/', '[_| ]', $search_template_str);
246 - if ($source_is_page) {
 287+ if ($source_is_page || $form_is_partial) {
247288 $matches = array();
248289 if ($allow_multiple) {
249290 // find the number of instances of this template in the page -
@@ -303,7 +344,17 @@
304345 }
305346 }
306347 // now remove this template from the text being edited
307 - $existing_page_content = str_replace($matches[0], '', $existing_page_content);
 348+ // if this is a partial form, establish a new insertion point
 349+ if($existing_page_content && $form_is_partial && $wgRequest->getCheck('partial')) {
 350+ // if something already exists, set the new insertion point
 351+ // to its position; otherwise just let it lie
 352+ if (strpos($existing_page_content, $matches[0])) {
 353+ $existing_page_content = str_replace('{{{insertionpoint}}}', '', $existing_page_content);
 354+ $existing_page_content = str_replace($matches[0], '{{{insertionpoint}}}', $existing_page_content);
 355+ }
 356+ } else {
 357+ $existing_page_content = str_replace($matches[0], '', $existing_page_content);
 358+ }
308359 // if this is not a multiple-instance template, and we've found
309360 // a match in the source page, there's a good chance that this
310361 // page was created with this form - note that, so we don't
@@ -339,6 +390,9 @@
340391 }
341392 }
342393 }
 394+ // =====================================================
 395+ // end template processing
 396+ // =====================================================
343397 } elseif ($tag_title == 'end template') {
344398 // remove this tag, reset some variables, and close off form HTML tag
345399 $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
@@ -354,6 +408,9 @@
355409 // be hidden because it is empty and choosers are being used. So,
356410 // hide it.
357411 $form_text = str_replace("[[placeholder]]", "style='display:none'", $form_text);
 412+ // =====================================================
 413+ // field processing
 414+ // =====================================================
358415 } elseif ($tag_title == 'field') {
359416 $field_name = trim($tag_components[1]);
360417 // cycle through the other components
@@ -401,6 +458,14 @@
402459 if ($cur_value && ! is_array($cur_value)) {
403460 $cur_value = Sanitizer::safeEncodeAttribute($cur_value);
404461 }
 462+ if ($cur_value && is_array($cur_value)) {
 463+ // HACK - this is sometimes necessary
 464+ // TODO: the code around line 433 might correct for this. This
 465+ // should be checked.
 466+ if (!$cur_value[0] && $cur_value[1])
 467+ $cur_value = null;
 468+ }
 469+
405470 if ($cur_value == null) {
406471 // set to default value specified in the form, if it's there
407472 $cur_value = $default_value;
@@ -589,7 +654,7 @@
590655 $sfgJSValidationCalls[] = "validate_mandatory_field ('$input_id" . "_1', '$info_id')";
591656 $sfgJSValidationCalls[] = "validate_mandatory_field ('$input_id" . "_2', '$info_id')";
592657 $sfgJSValidationCalls[] = "validate_mandatory_field ('$input_id" . "_3', '$info_id')";
593 - if ($input_type == 'datetime' || $input_type == 'datetime with timezone') {
 658+ if ($input_type == 'datetime' || $input_type == 'datetime with timezone') {
594659 // TODO - validate the time fields
595660 if ($input_type == 'datetime with timezone') {
596661 // TODO - validate the timezone
@@ -607,6 +672,9 @@
608673 $start_position = $brackets_end_loc;
609674 }
610675 }
 676+ // =====================================================
 677+ // standard input processing
 678+ // =====================================================
611679 } elseif ($tag_title == 'standard input') {
612680 // set a flag so that the standard 'form bottom' won't get displayed
613681 $this->standardInputsIncluded = true;
@@ -639,21 +707,67 @@
640708 $new_text = $this->cancelLinkHTML($form_is_disabled, $input_label);
641709 }
642710 $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
 711+ // =====================================================
 712+ // page info processing
 713+ // =====================================================
 714+ } elseif ($tag_title == 'info') {
 715+ // TODO: Generate an error message if this is included more than once
 716+ foreach(array_slice($tag_components, 1) as $component) {
 717+ list($tag, $val) = explode('=', $component, 2);
 718+ if ($tag == 'add title') {
 719+ // handle this only if we're adding a page
 720+ if (! $this->mPageTitle->exists()) {
 721+ $form_page_title = $val;
 722+ }
 723+ }
 724+ elseif($tag == 'edit title') {
 725+ // handle this only if we're editing a page
 726+ if ($this->mPageTitle->exists()) {
 727+ $form_page_title = $val;
 728+ }
 729+ }
 730+ elseif($tag == 'partial form') {
 731+ $form_is_partial = true;
 732+ // replacement pages may have minimal matches...
 733+ $source_page_matches_this_form = true;
 734+ }
 735+ }
 736+ $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
 737+ // =====================================================
 738+ // default outer level processing
 739+ // =====================================================
643740 } else { // tag is not one of the three allowed values
644741 // ignore tag
645742 $start_position = $brackets_end_loc;
646743 } // end if
647744 } // end while
648745
649 - if (! $all_instances_printed && ($template_text != '')) {
650 - // add another newline before the final bracket, if this template
651 - // call is already more than one line
652 - if (strpos($template_text, "\n")) {
653 - $template_text .= "\n";
 746+ if (! $all_instances_printed ) {
 747+ if ( $template_text != '' ) {
 748+ // add another newline before the final bracket, if this template
 749+ // call is already more than one line
 750+ if (strpos($template_text, "\n"))
 751+ $template_text .= "\n";
 752+ $template_text .= "}}";
 753+ $data_text .= $template_text . "\n";
 754+ // if there is a placeholder in the text, we know that we are
 755+ // doing a replace
 756+ if ($existing_page_content && strpos($existing_page_content, '{{{insertionpoint}}}', 0)) {
 757+ $existing_page_content = preg_replace('/\{\{\{insertionpoint\}\}\}(\r?\n?)/',
 758+ preg_replace('/\}\}/m', '}�',
 759+ preg_replace('/\{\{/m', '�{', $template_text)) .
 760+ "\n{{{insertionpoint}}}",
 761+ $existing_page_content);
 762+ // otherwise, if it's a partial form, we have to add the new
 763+ // text somewhere
 764+ } elseif ($form_is_partial && $wgRequest->getCheck('partial') ) {
 765+ $existing_page_content = preg_replace('/\}\}/m', '}�',
 766+ preg_replace('/\{\{/m', '�{', $template_text)) .
 767+ "\n{{{insertionpoint}}}\n" . $existing_page_content;
 768+ }
654769 }
655 - $template_text .= "}}\n";
656 - $data_text .= $template_text;
657770 }
 771+
658772 if ($allow_multiple) {
659773 if (! $all_instances_printed) {
660774 $section = str_replace('[num]', "[{$instance_num}a]", $section);
@@ -704,7 +818,21 @@
705819 }
706820 // get free text, and add to page data, as well as retroactively
707821 // inserting it into the form
708 - if ($source_is_page) {
 822+
 823+ // If $form_is_partial is true then either:
 824+ // (a) we're processing a replacement (param 'partial' == 1)
 825+ // (b) we're sending out something to be replaced (param 'partial' is missing)
 826+ if ($form_is_partial) {
 827+ if(!$wgRequest->getCheck('partial')) {
 828+ $free_text = $original_page_content;
 829+ $form_text .= $this->hiddenFieldHTML('partial', 1);
 830+ } else {
 831+ $free_text = null;
 832+ $existing_page_content = preg_replace('/�\{(.*?)\}�/s', '{{\1}}', $existing_page_content);
 833+ $existing_page_content = preg_replace('/\{\{\{insertionpoint\}\}\}/', '', $existing_page_content);
 834+ $existing_page_content = Sanitizer::safeEncodeAttribute($existing_page_content);
 835+ }
 836+ } elseif ($source_is_page) {
709837 // if the page is the source, free_text will just be whatever in the
710838 // page hasn't already been inserted into the form
711839 $free_text = trim($existing_page_content);
@@ -1062,9 +1190,13 @@
10631191
10641192 END;
10651193
1066 - // send the autocomplete values to the browser, along with the mappings of which values should apply to which fields
 1194+ // send the autocomplete values to the browser, along with the mappings
 1195+ // of which values should apply to which fields
 1196+ // if doing a replace, the data text is actually the modified original page
 1197+ if($wgRequest->getCheck('partial'))
 1198+ $data_text = $existing_page_content;
10671199 $javascript_text .= $fields_javascript_text;
1068 - return array($form_text, $javascript_text, $data_text);
 1200+ return array($form_text, $javascript_text, $data_text, $form_page_title);
10691201 }
10701202
10711203 function formFieldHTML($form_field, $cur_value) {

Status & tagging log