Ejemplo n.º 1
0
 public static function monthDropdownHTML($cur_month, $input_name, $is_disabled)
 {
     global $sfgTabIndex, $wgAmericanDates;
     $optionsText = '';
     $month_names = SFFormUtils::getMonthNames();
     // Add a "null" value at the beginning.
     array_unshift($month_names, null);
     foreach ($month_names as $i => $name) {
         if (is_null($name)) {
             $month_value = null;
         } else {
             // Pad out month to always be two digits.
             $month_value = $wgAmericanDates == true ? $name : str_pad($i, 2, '0', STR_PAD_LEFT);
         }
         $optionAttrs = array('value' => $month_value);
         if ($name == $cur_month || $i == $cur_month) {
             $optionAttrs['selected'] = 'selected';
         }
         $optionsText .= Html::element('option', $optionAttrs, $name);
     }
     $selectAttrs = array('class' => 'monthInput', 'name' => $input_name . '[month]', 'tabindex' => $sfgTabIndex);
     if ($is_disabled) {
         $selectAttrs['disabled'] = 'disabled';
     }
     $text = Html::rawElement('select', $selectAttrs, $optionsText);
     return $text;
 }
Ejemplo n.º 2
0
    function doSpecialCreateForm($query)
    {
        global $wgOut, $wgRequest, $sfgScriptPath;
        $db = wfGetDB(DB_SLAVE);
        if (!is_null($query)) {
            $presetFormName = str_replace('_', ' ', $query);
            $wgOut->setPageTitle(wfMessage('sf-createform-with-name', $presetFormName)->text());
            $form_name = $presetFormName;
        } else {
            $presetFormName = null;
            $form_name = $wgRequest->getVal('form_name');
        }
        // Create Javascript to populate fields to let the user input
        // parameters for the field, based on the input type selected
        // in the dropdown.
        $url = Skin::makeSpecialUrl('CreateForm', "showinputtypeoptions=' + this.val() + '&formfield=' + this.attr('formfieldid') + '");
        foreach ($wgRequest->getValues() as $param => $value) {
            $url .= '&params[' . Xml::escapeJsString($param) . ']=' . Xml::escapeJsString($value);
        }
        $wgOut->addModules('ext.semanticforms.collapsible');
        $section_name_error_str = '<font color="red" id="section_error">' . wfMessage('sf_blank_error')->escaped() . '</font>';
        $wgOut->addScript("<script>\njQuery.fn.displayInputParams = function() {\n\tinputParamsDiv = this.closest('.formField').find('.otherInputParams');\n\tjQuery.ajax({\n\t\turl: '{$url}',\n\t\tcontext: document.body,\n\t\tsuccess: function(data){\n\t\t\tinputParamsDiv.html(data);\n\t\t}\n\t});\n};\njQuery(document).ready(function() {\n\tjQuery('.inputTypeSelector').change( function() {\n\t\tjQuery(this).displayInputParams();\n\t});\n\tjQuery('#addsection').click( function(event) {\n\tif(jQuery('#sectionname').val() == '') {\n\t\t\tevent.preventDefault();\n\t\t\tjQuery('#section_error').remove();\n\t\t\tjQuery('<div/>').append('{$section_name_error_str}').appendTo('#sectionerror');\n\t}\n    });\n});\n</script>");
        // Get the names of all templates on this site.
        $all_templates = array();
        $res = $db->select('page', 'page_title', array('page_namespace' => NS_TEMPLATE, 'page_is_redirect' => 0), __METHOD__, array('ORDER BY' => 'page_title'));
        if ($db->numRows($res) > 0) {
            while ($row = $db->fetchRow($res)) {
                $template_name = str_replace('_', ' ', $row[0]);
                $all_templates[] = $template_name;
            }
        }
        $deleted_template_loc = null;
        $deleted_section_loc = null;
        // To keep the templates and sections
        $form_items = array();
        // Handle inputs.
        foreach ($wgRequest->getValues() as $var => $val) {
            # ignore variables that are not of the right form
            if (strpos($var, "_") != false) {
                # get the template declarations and work from there
                list($action, $id) = explode("_", $var, 2);
                if ($action == "template") {
                    // If the button was pressed to remove
                    // this template, just don't add it to
                    // the array.
                    if ($wgRequest->getVal("del_{$id}") != null) {
                        $deleted_template_loc = $id;
                    } else {
                        $form_template = SFTemplateInForm::create($val, $wgRequest->getVal("label_{$id}"), $wgRequest->getVal("allow_multiple_{$id}"));
                        $form_items[] = array('type' => 'template', 'name' => $form_template->getTemplateName(), 'item' => $form_template);
                    }
                } elseif ($action == "section") {
                    if ($wgRequest->getVal("delsection_{$id}") != null) {
                        $deleted_section_loc = $id;
                    } else {
                        $form_section = SFPageSection::create($val);
                        $form_items[] = array('type' => 'section', 'name' => $form_section->getSectionName(), 'item' => $form_section);
                    }
                }
            }
        }
        if ($wgRequest->getVal('add_field') != null) {
            $form_template = SFTemplateInForm::create($wgRequest->getVal('new_template'), "", false);
            $template_loc = $wgRequest->getVal('before_template');
            $template_count = 0;
            if ($template_loc === null) {
                $new_template_loc = 0;
                $template_loc = 0;
            } else {
                // Count the number of templates before the
                // location of the template to be added
                for ($i = 0; $i < $template_loc; $i++) {
                    if ($form_items[$i]['type'] == 'template') {
                        $template_count++;
                    }
                }
                $new_template_loc = $template_count;
            }
            // @HACK - array_splice() doesn't work for objects, so
            // we have to first insert a stub element into the
            // array, then replace that with the actual object.
            array_splice($form_items, $template_loc, 0, "stub");
            $form_items[$template_loc] = array('type' => 'template', 'name' => $form_template->getTemplateName(), 'item' => $form_template);
        } else {
            $template_loc = null;
            $new_template_loc = null;
        }
        if ($wgRequest->getVal('add_section') != null) {
            $form_section = SFPageSection::create($wgRequest->getVal('sectionname'));
            $section_loc = $wgRequest->getVal('before_section');
            $section_count = 0;
            if ($section_loc === null) {
                $new_section_loc = 0;
                $section_loc = 0;
            } else {
                // Count the number of sections before the
                // location of the section to be added
                for ($i = 0; $i < $section_loc; $i++) {
                    if ($form_items[$i]['type'] == 'section') {
                        $section_count++;
                    }
                }
                $new_section_loc = $section_count;
            }
            // The same used hack for templates
            array_splice($form_items, $section_loc, 0, "stub");
            $form_items[$section_loc] = array('type' => 'section', 'name' => $form_section->getSectionName(), 'item' => $form_section);
        } else {
            $section_loc = null;
            $new_section_loc = null;
        }
        // Now cycle through the templates and fields, modifying each
        // one per the query variables.
        $templates = 0;
        $sections = 0;
        foreach ($form_items as $fi) {
            if ($fi['type'] == 'template') {
                foreach ($fi['item']->getFields() as $j => $field) {
                    $old_i = SFFormUtils::getChangedIndex($templates, $new_template_loc, $deleted_template_loc);
                    foreach ($wgRequest->getValues() as $key => $value) {
                        if (($pos = strpos($key, '_' . $old_i . '_' . $j)) != false) {
                            $paramName = substr($key, 0, $pos);
                            // Spaces got replaced by
                            // underlines in the query.
                            $paramName = str_replace('_', ' ', $paramName);
                        } else {
                            continue;
                        }
                        if ($paramName == 'label') {
                            $field->template_field->setLabel($value);
                        } elseif ($paramName == 'input type') {
                            $input_type = $wgRequest->getVal("input_type_" . $old_i . "_" . $j);
                            if ($input_type == 'hidden') {
                                $field->template_field->setInputType($input_type);
                                $field->setIsHidden(true);
                            } elseif (substr($input_type, 0, 1) == '.') {
                                // It's the default input type -
                                // don't do anything.
                            } else {
                                $field->template_field->setInputType($input_type);
                            }
                        } else {
                            if (!empty($value)) {
                                if ($value == 'on') {
                                    $value = true;
                                }
                                $field->setFieldArg($paramName, $value);
                            }
                        }
                    }
                }
                $templates++;
            } elseif ($fi['type'] == 'section') {
                $section = $fi['item'];
                $old_i = SFFormUtils::getChangedIndex($sections, $new_section_loc, $deleted_section_loc);
                foreach ($wgRequest->getValues() as $key => $value) {
                    if (($pos = strpos($key, '_section_' . $old_i)) != false) {
                        $paramName = substr($key, 0, $pos);
                        $paramName = str_replace('_', ' ', $paramName);
                    } else {
                        continue;
                    }
                    if (!empty($value)) {
                        if ($value == 'on') {
                            $value = true;
                        }
                        if ($paramName == 'level') {
                            $section->setSectionLevel($value);
                        } elseif ($paramName == 'hidden') {
                            $section->setIsHidden($value);
                        } elseif ($paramName == 'restricted') {
                            $section->setIsRestricted($value);
                        } elseif ($paramName == 'mandatory') {
                            $section->setIsMandatory($value);
                        } else {
                            $section->setSectionArgs($paramName, $value);
                        }
                    }
                }
                $sections++;
            }
        }
        $form = SFForm::create($form_name, $form_items);
        // If a submit button was pressed, create the form-definition
        // file, then redirect.
        $save_page = $wgRequest->getCheck('wpSave');
        $preview_page = $wgRequest->getCheck('wpPreview');
        if ($save_page || $preview_page) {
            $validToken = $this->getUser()->matchEditToken($wgRequest->getVal('csrf'), 'CreateForm');
            if (!$validToken) {
                $text = "This appears to be a cross-site request forgery; canceling save.";
                $wgOut->addHTML($text);
                return;
            }
            // Validate form name.
            if ($form->getFormName() == "") {
                $form_name_error_str = wfMessage('sf_blank_error')->text();
            } else {
                // Redirect to wiki interface.
                $wgOut->setArticleBodyOnly(true);
                $title = Title::makeTitleSafe(SF_NS_FORM, $form->getFormName());
                $full_text = $form->createMarkup();
                $text = SFUtils::printRedirectForm($title, $full_text, "", $save_page, $preview_page, false, false, false, null, null);
                $wgOut->addHTML($text);
                return;
            }
        }
        $text = "\t" . '<form action="" method="post">' . "\n";
        if (is_null($presetFormName)) {
            // Set 'title' field, in case there's no URL niceness
            $text .= Html::hidden('title', $this->getTitle()->getPrefixedText());
            $text .= "\n\t<p>" . wfMessage('sf_createform_nameinput')->escaped() . ' ' . wfMessage('sf_createform_nameinputdesc')->escaped() . Html::input('form_name', $form_name, 'text', array('size' => 25));
            if (!empty($form_name_error_str)) {
                $text .= "\t" . Html::element('font', array('color' => 'red'), $form_name_error_str);
            }
            $text .= "</p>\n";
        }
        $text .= $form->creationHTML();
        $text .= "<h2> " . wfMessage('sf_createform_addelements')->escaped() . " </h2>";
        $text .= "\t<p>" . wfMessage('sf_createform_addtemplate')->escaped() . "\n";
        $select_body = "";
        foreach ($all_templates as $template) {
            $select_body .= "\t" . Html::element('option', array('value' => $template), $template) . "\n";
        }
        $text .= "\t" . Html::rawElement('select', array('name' => 'new_template'), $select_body) . "\n";
        // If a template has already been added, show a dropdown letting
        // the user choose where in the list to add a new dropdown.
        $select_body = "";
        foreach ($form_items as $i => $fi) {
            if ($fi['type'] == 'template') {
                $option_str = wfMessage('sf_createform_template')->escaped();
            } elseif ($fi['type'] == 'section') {
                $option_str = wfMessage('sf_createform_pagesection')->escaped();
            }
            $option_str .= $fi['name'];
            $select_body .= "\t" . Html::element('option', array('value' => $i), $option_str) . "\n";
        }
        $final_index = count($form_items);
        $at_end_msg = wfMessage('sf_createform_atend')->escaped();
        $select_body .= "\t" . Html::element('option', array('value' => $final_index, 'selected' => 'selected'), $at_end_msg);
        // Selection for before which item this template should be placed
        if (count($form_items) > 0) {
            $text .= wfMessage('sf_createform_before')->escaped();
            $text .= Html::rawElement('select', array('name' => 'before_template'), $select_body) . "\n";
        }
        // Disable 'save' and 'preview' buttons if user has not yet
        // added any templates.
        $add_button_text = wfMessage('sf_createform_add')->text();
        $text .= "\t" . Html::input('add_field', $add_button_text, 'submit') . "\n";
        // The form HTML for page sections
        $text .= "</br></br>" . Html::rawElement('span', null, wfMessage('sf_createform_addsection')->text() . ":") . "\n";
        $text .= Html::input('sectionname', '', 'text', array('size' => '30', 'placeholder' => wfMessage('sf_createform_sectionname')->text(), 'id' => 'sectionname')) . "\n";
        // Selection for before which item this section should be placed
        if (count($form_items) > 0) {
            $text .= wfMessage('sf_createform_before')->escaped();
            $text .= Html::rawElement('select', array('name' => 'before_section'), $select_body) . "\n";
        }
        $add_section_text = wfMessage('sf_createform_addsection')->text();
        $text .= "\t" . Html::input('add_section', $add_section_text, 'submit', array('id' => 'addsection'));
        $text .= "\n\t" . Html::rawElement('div', array('id' => 'sectionerror'));
        $text .= <<<END
</p>
\t<br />

END;
        $text .= "\t" . Html::hidden('csrf', $this->getUser()->getEditToken('CreateForm')) . "\n";
        $saveAttrs = array('id' => 'wpSave');
        if (count($form_items) == 0) {
            $saveAttrs['disabled'] = true;
        }
        $editButtonsText = "\t" . Html::input('wpSave', wfMessage('savearticle')->text(), 'submit', $saveAttrs) . "\n";
        $previewAttrs = array('id' => 'wpPreview');
        if (count($form_items) == 0) {
            $previewAttrs['disabled'] = true;
        }
        $editButtonsText .= "\t" . Html::input('wpPreview', wfMessage('preview')->text(), 'submit', $previewAttrs) . "\n";
        $text .= "\t" . Html::rawElement('div', array('class' => 'editButtons'), Html::rawElement('p', array(), $editButtonsText) . "\n") . "\n";
        // Explanatory message if buttons are disabled because no
        // templates have been added.
        if (count($form_items) == 0) {
            $text .= "\t" . Html::element('p', null, "(" . wfMessage('sf_createform_additembeforesave')->text() . ")");
        }
        $text .= <<<END
\t</form>

END;
        $wgOut->addExtensionStyle($sfgScriptPath . "/skins/SemanticForms.css");
        $wgOut->addHTML($text);
        //Don't submit the form if enter is pressed on a text input box or a select
        $wgOut->addScript('<script>
		jQuery("input,select").keypress(function(event) { return event.keyCode != 13; });
		</script>');
    }
Ejemplo n.º 3
0
 static function printForm(&$form_name, &$target_name, $alt_forms = array(), $redirectOnError = false)
 {
     global $wgOut, $wgRequest, $wgUser, $sfgFormPrinter;
     // initialize some variables
     $target_title = null;
     $page_name_formula = null;
     $form_title = Title::makeTitleSafe(SF_NS_FORM, $form_name);
     // If the given form is not a valid title, bail out.
     if (!$form_title) {
         return 'sf_formedit_badurl';
     }
     $form_article = new Article($form_title, 0);
     $form_definition = $form_article->getContent();
     // If the form page is a redirect, use the other form
     // instead.
     if ($form_title->isRedirect()) {
         $form_title = Title::newFromRedirectRecurse($form_definition);
         $form_article = new Article($form_title, 0);
         $form_definition = $form_article->getContent();
     }
     $form_definition = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_definition);
     if (is_null($target_name)) {
         $target_name = '';
     }
     if ($target_name === '') {
         // parse the form to see if it has a 'page name' value set
         $matches;
         if (preg_match('/{{{info.*page name\\s*=\\s*(.*)}}}/m', $form_definition, $matches)) {
             $page_name_elements = SFUtils::getFormTagComponents($matches[1]);
             $page_name_formula = $page_name_elements[0];
         } elseif (count($alt_forms) == 0) {
             return 'sf_formedit_badurl';
         }
     } else {
         $target_title = Title::newFromText($target_name);
         if ($target_title && $target_title->exists()) {
             if ($wgRequest->getVal('query') == 'true') {
                 $page_contents = null;
                 //$page_is_source = false;
             } else {
                 // If page already exists and 'redlink'
                 // is in the query string, redirect to
                 // the actual page, just like
                 // MediaWiki does it.
                 if ($wgRequest->getBool('redlink')) {
                     $wgOut->redirect($target_title->getFullURL());
                     wfProfileOut(__METHOD__);
                     return;
                 }
                 $target_article = new Article($target_title, 0);
                 $page_contents = $target_article->getContent();
                 //$page_is_source = true;
             }
         } else {
             $target_name = str_replace('_', ' ', $target_name);
         }
     }
     if (!$form_title || !$form_title->exists()) {
         if (count($alt_forms) > 0) {
             $text = '<div class="infoMessage">' . wfMsg('sf_formedit_altformsonly') . ' ' . self::printAltFormsList($alt_forms, $form_name) . "</div>\n";
         } else {
             $text = Html::rawElement('p', array('class' => 'error'), wfMsgExt('sf_formstart_badform', 'parseinline', SFUtils::linkText(SF_NS_FORM, $form_name))) . "\n";
         }
     } elseif ($target_name === '' && $page_name_formula === '') {
         $text = Html::element('p', array('class' => 'error'), wfMsg('sf_formedit_badurl')) . "\n";
     } else {
         $save_page = $wgRequest->getCheck('wpSave');
         $preview_page = $wgRequest->getCheck('wpPreview');
         $diff_page = $wgRequest->getCheck('wpDiff');
         $form_submitted = $save_page || $preview_page || $diff_page;
         // get 'preload' query value, if it exists
         if (!$form_submitted) {
             if ($wgRequest->getCheck('preload')) {
                 $page_is_source = true;
                 $page_contents = SFFormUtils::getPreloadedText($wgRequest->getVal('preload'));
             } else {
                 // let other extensions preload the page, if they want
                 wfRunHooks('sfEditFormPreloadText', array(&$page_contents, $target_title, $form_title));
                 $page_is_source = $page_contents != null;
             }
         } else {
             $page_is_source = false;
             $page_contents = null;
         }
         list($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name) = $sfgFormPrinter->formHTML($form_definition, $form_submitted, $page_is_source, $form_article->getID(), $page_contents, $target_name, $page_name_formula);
         // Before we do anything else, set the form header
         // title - this needs to be done after formHTML() is
         // called, because otherwise it doesn't take hold
         // for some reason if the form is disabled.
         if (empty($target_title)) {
             $s = wfMsg('sf_formedit_createtitlenotarget', $form_title->getText());
         } elseif ($target_title->exists()) {
             $s = wfMsg('sf_formedit_edittitle', $form_title->getText(), $target_title->getPrefixedText());
         } else {
             $s = wfMsg('sf_formedit_createtitle', $form_title->getText(), $target_title->getPrefixedText());
         }
         $wgOut->setPageTitle($s);
         if ($form_submitted) {
             if (!is_null($page_name_formula) && $page_name_formula !== '') {
                 $target_name = $generated_page_name;
                 // prepend a super-page, if one was specified
                 if ($wgRequest->getCheck('super_page')) {
                     $target_name = $wgRequest->getVal('super_page') . '/' . $target_name;
                 }
                 // prepend a namespace, if one was specified
                 if ($wgRequest->getCheck('namespace')) {
                     $target_name = $wgRequest->getVal('namespace') . ':' . $target_name;
                 }
                 // replace "unique number" tag with one
                 // that won't get erased by the next line
                 $target_name = preg_replace('/<unique number(.*)>/', '{num\\1}', $target_name, 1);
                 // if any formula stuff is still in the
                 // name after the parsing, just remove it
                 $target_name = StringUtils::delimiterReplace('<', '>', '', $target_name);
                 // now run the parser on it
                 global $wgParser;
                 // ...but first, replace spaces back
                 // with underlines, in case a magic word
                 // or parser function name contains
                 // underlines - hopefully this won't
                 // cause problems of its own
                 $target_name = str_replace(' ', '_', $target_name);
                 $target_name = $wgParser->preprocess($target_name, $wgOut->getTitle(), ParserOptions::newFromUser(null));
                 $title_number = "";
                 $isRandom = false;
                 $randomNumHasPadding = false;
                 $randomNumDigits = 6;
                 if (strpos($target_name, '{num') !== false) {
                     // Random number
                     if (preg_match('/{num;random(;(0)?([1-9][0-9]*))?}/', $target_name, $matches)) {
                         $isRandom = true;
                         $randomNumHasPadding = array_key_exists(2, $matches);
                         $randomNumDigits = array_key_exists(3, $matches) ? $matches[3] : $randomNumDigits;
                         $title_number = self::makeRandomNumber($randomNumDigits, $randomNumHasPadding);
                     } else {
                         // get unique number start value
                         // from target name; if it's not
                         // there, or it's not a positive
                         // number, start it out as blank
                         preg_match('/{num.*start[_]*=[_]*([^;]*).*}/', $target_name, $matches);
                         if (count($matches) == 2 && is_numeric($matches[1]) && $matches[1] >= 0) {
                             // the "start" value"
                             $title_number = $matches[1];
                         }
                     }
                     // set target title
                     $target_title = Title::newFromText(preg_replace('/{num.*}/', $title_number, $target_name));
                     // if title exists already
                     // cycle through numbers for
                     // this tag until we find one
                     // that gives a nonexistent page
                     // title
                     while ($target_title->exists()) {
                         if ($isRandom) {
                             $title_number = self::makeRandomNumber($randomNumDigits, $randomNumHasPadding);
                         } elseif ($title_number == "") {
                             $title_number = 2;
                         } else {
                             $title_number = str_pad($title_number + 1, strlen($title_number), '0', STR_PAD_LEFT);
                         }
                         $target_title = Title::newFromText(preg_replace('/{num.*}/', $title_number, $target_name));
                     }
                     $target_name = $target_title->getPrefixedText();
                 } else {
                     $target_title = Title::newFromText($target_name);
                 }
             }
             if (is_null($target_title)) {
                 if ($target_name) {
                     return array('sf_formstart_badtitle', array($target_name));
                 } else {
                     return 'sf_formedit_emptytitle';
                 }
             }
             if ($save_page) {
                 $permErrors = $target_title->getUserPermissionsErrors('edit', $wgUser);
                 if ($permErrors) {
                     // just return the first error and let them fix it one by one
                     return array_shift($permErrors);
                 }
                 // Set up all the variables for the
                 // page save.
                 $data = array('wpTextbox1' => $data_text, 'wpSummary' => $wgRequest->getVal('wpSummary'), 'wpStarttime' => $wgRequest->getVal('wpStarttime'), 'wpEdittime' => $wgRequest->getVal('wpEdittime'), 'wpEditToken' => $wgUser->isLoggedIn() ? $wgUser->editToken() : EDIT_TOKEN_SUFFIX, 'wpSave' => '', 'action' => 'submit');
                 if ($wgRequest->getCheck('wpMinoredit')) {
                     $data['wpMinoredit'] = true;
                 }
                 if ($wgRequest->getCheck('wpWatchthis')) {
                     $data['wpWatchthis'] = true;
                 }
                 $request = new FauxRequest($data, true);
                 // Find existing article if it exists,
                 // or create a new one.
                 $article = new Article($target_title, 0);
                 $editor = new EditPage($article);
                 $editor->importFormData($request);
                 // Try to save the page!
                 $resultDetails = array();
                 $saveResult = $editor->internalAttemptSave($resultDetails);
                 // Return value was made an object in MW 1.19
                 if (is_object($saveResult)) {
                     $saveResultCode = $saveResult->value;
                 } else {
                     $saveResultCode = $saveResult;
                 }
                 if (($saveResultCode == EditPage::AS_HOOK_ERROR || $saveResultCode == EditPage::AS_HOOK_ERROR_EXPECTED) && $redirectOnError) {
                     $wgOut->clearHTML();
                     $wgOut->setArticleBodyOnly(true);
                     // Lets other code process additional form-definition syntax
                     wfRunHooks('sfWritePageData', array($form_name, $target_title, &$data_text));
                     $text = SFUtils::printRedirectForm($target_title, $data_text, $wgRequest->getVal('wpSummary'), $save_page, $preview_page, $diff_page, $wgRequest->getCheck('wpMinoredit'), $wgRequest->getCheck('wpWatchthis'), $wgRequest->getVal('wpStarttime'), $wgRequest->getVal('wpEdittime'));
                 } else {
                     if ($saveResultCode == EditPage::AS_SUCCESS_UPDATE || $saveResultCode == EditPage::AS_SUCCESS_NEW_ARTICLE) {
                         $wgOut->redirect($target_title->getFullURL());
                     }
                     return SFUtils::processEditErrors($saveResultCode);
                 }
             } else {
                 // Lets other code process additional form-definition syntax
                 wfRunHooks('sfWritePageData', array($form_name, $target_title, &$data_text));
                 $text = SFUtils::printRedirectForm($target_title, $data_text, $wgRequest->getVal('wpSummary'), $save_page, $preview_page, $diff_page, $wgRequest->getCheck('wpMinoredit'), $wgRequest->getCheck('wpWatchthis'), $wgRequest->getVal('wpStarttime'), $wgRequest->getVal('wpEdittime'));
                 // extract its data
             }
         } else {
             // override the default title for this page if
             // a title was specified in the form
             if ($form_page_title != null) {
                 if ($target_name === '') {
                     $wgOut->setPageTitle($form_page_title);
                 } else {
                     $wgOut->setPageTitle("{$form_page_title}: {$target_title->getPrefixedText()}");
                 }
             }
             $text = "";
             if (count($alt_forms) > 0) {
                 $text .= '<div class="infoMessage">' . wfMsg('sf_formedit_altforms') . ' ';
                 $text .= self::printAltFormsList($alt_forms, $target_name);
                 $text .= "</div>\n";
             }
             $text .= '<form name="createbox" id="sfForm" method="post" class="createbox">';
             $pre_form_html = '';
             wfRunHooks('sfHTMLBeforeForm', array(&$target_title, &$pre_form_html));
             $text .= $pre_form_html;
             $text .= $form_text;
         }
     }
     SFUtils::addJavascriptAndCSS();
     if (!empty($javascript_text)) {
         $wgOut->addScript('		<script type="text/javascript">' . "\n{$javascript_text}\n" . '</script>' . "\n");
     }
     $wgOut->addHTML($text);
     return null;
 }
    /**
     * This function is the real heart of the entire Semantic Forms
     * extension. It handles two main actions: (1) displaying a form on the
     * screen, given a form definition and possibly page contents (if an
     * existing page is being edited); and (2) creating actual page
     * contents, if the form was already submitted by the user.
     *
     * It also does some related tasks, like figuring out the page name (if
     * only a page formula exists).
     */
    function formHTML($form_def, $form_submitted, $source_is_page, $form_id = null, $existing_page_content = null, $page_name = null, $page_name_formula = null, $is_query = false, $is_embedded = false)
    {
        global $wgRequest, $wgUser, $wgParser;
        global $sfgTabIndex;
        // used to represent the current tab index in the form
        global $sfgFieldNum;
        // used for setting various HTML IDs
        // initialize some variables
        $wiki_page = new SFWikiPage();
        $sfgTabIndex = 1;
        $sfgFieldNum = 1;
        $source_page_matches_this_form = false;
        $form_page_title = null;
        $generated_page_name = $page_name_formula;
        // $form_is_partial is true if:
        // (a) 'partial' == 1 in the arguments
        // (b) 'partial form' is found in the form definition
        // in the latter case, it may remain false until close to the end of
        // the parsing, so we have to assume that it will become a possibility
        $form_is_partial = false;
        $new_text = "";
        // If we have existing content and we're not in an active replacement
        // situation, preserve the original content. We do this because we want
        // to pass the original content on IF this is a partial form.
        // TODO: A better approach here would be to pass the revision ID of the
        // existing page content through the replace value, which would
        // minimize the html traffic and would allow us to do a concurrent
        // update check. For now, we pass it through a hidden text field.
        if (!$wgRequest->getCheck('partial')) {
            $original_page_content = $existing_page_content;
        } else {
            $original_page_content = null;
            if ($wgRequest->getCheck('sf_free_text')) {
                if (!isset($existing_page_content) || $existing_page_content == '') {
                    $existing_page_content = $wgRequest->getVal('sf_free_text');
                }
                $form_is_partial = true;
            }
        }
        // Disable all form elements if user doesn't have edit
        // permission - two different checks are needed, because
        // editing permissions can be set in different ways.
        // HACK - sometimes we don't know the page name in advance, but
        // we still need to set a title here for testing permissions.
        if ($is_embedded) {
            // If this is an embedded form (probably a 'RunQuery'),
            // just use the name of the actual page we're on.
            global $wgTitle;
            $this->mPageTitle = $wgTitle;
        } elseif ($is_query) {
            // We're in Special:RunQuery - just use that as the
            // title.
            global $wgTitle;
            $this->mPageTitle = $wgTitle;
        } elseif ($page_name === '' || $page_name === null) {
            $this->mPageTitle = Title::newFromText($wgRequest->getVal('namespace') . ":Semantic Forms permissions test");
        } else {
            $this->mPageTitle = Title::newFromText($page_name);
        }
        global $wgOut;
        // Show previous set of deletions for this page, if it's been
        // deleted before.
        if (!$form_submitted && ($this->mPageTitle && !$this->mPageTitle->exists() && is_null($page_name_formula))) {
            $this->showDeletionLog($wgOut);
        }
        // Unfortunately, we can't just call userCan() here because,
        // since MW 1.16, it has a bug in which it ignores a setting of
        // "$wgEmailConfirmToEdit = true;". Instead, we'll just get the
        // permission errors from the start, and use those to determine
        // whether the page is editable.
        if (!$is_query) {
            // $userCanEditPage = ( $wgUser->isAllowed( 'edit' ) && $this->mPageTitle->userCan( 'edit' ) );
            $permissionErrors = $this->mPageTitle->getUserPermissionsErrors('edit', $wgUser);
            // The handling of $wgReadOnly and $wgReadOnlyFile
            // has to be done separately.
            if (wfReadOnly()) {
                $permissionErrors = array(array('readonlytext', array(wfReadOnlyReason())));
            }
            $userCanEditPage = count($permissionErrors) == 0;
            Hooks::run('sfUserCanEditPage', array($this->mPageTitle, &$userCanEditPage));
        }
        $form_text = "";
        if ($is_query || $userCanEditPage) {
            $form_is_disabled = false;
            // Show "Your IP address will be recorded" warning if
            // user is anonymous, and it's not a query.
            if ($wgUser->isAnon() && !$is_query) {
                // Based on code in MediaWiki's EditPage.php.
                $anonEditWarning = wfMessage('anoneditwarning', '{{fullurl:Special:UserLogin|returnto={{FULLPAGENAMEE}}}}', '{{fullurl:Special:UserLogin/signup|returnto={{FULLPAGENAMEE}}}}')->parse();
                $form_text .= Html::rawElement('div', array('id' => 'mw-anon-edit-warning', 'class' => 'warningbox'), $anonEditWarning);
            }
        } else {
            $form_is_disabled = true;
            $wgOut->setPageTitle(wfMessage('badaccess')->text());
            $wgOut->addWikiText($wgOut->formatPermissionsErrorMessage($permissionErrors, 'edit'));
            $wgOut->addHTML("\n<hr />\n");
        }
        //		$oldParser = $wgParser;
        //		$wgParser = unserialize( serialize( $oldParser ) ); // deep clone of parser
        if (!$wgParser->Options()) {
            $wgParser->Options(ParserOptions::newFromUser($wgUser));
        }
        $wgParser->Title($this->mPageTitle);
        // This is needed in order to make sure $parser->mLinkHolders
        // is set.
        $wgParser->clearState();
        $form_def = SFFormUtils::getFormDefinition($wgParser, $form_def, $form_id);
        // Turn form definition file into an array of sections, one for
        // each template definition (plus the first section).
        $form_def_sections = array();
        $start_position = 0;
        $section_start = 0;
        $free_text_was_included = false;
        // Unencode any HTML-encoded representations of curly brackets and
        // pipes - this is a hack to allow for forms to include templates
        // that themselves contain form elements - the escaping was needed
        // to make sure that those elements don't get parsed too early.
        $form_def = str_replace(array('&#123;', '&#124;', '&#125;'), array('{', '|', '}'), $form_def);
        // And another hack - replace the 'free text' standard input
        // with a field declaration to get it to be handled as a field.
        $form_def = str_replace('standard input|free text', 'field|<freetext>', $form_def);
        while ($brackets_loc = strpos($form_def, "{{{", $start_position)) {
            $brackets_end_loc = strpos($form_def, "}}}", $brackets_loc);
            $bracketed_string = substr($form_def, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
            $tag_components = SFUtils::getFormTagComponents($bracketed_string);
            $tag_title = trim($tag_components[0]);
            if ($tag_title == 'for template' || $tag_title == 'end template') {
                // Create a section for everything up to here
                $section = substr($form_def, $section_start, $brackets_loc - $section_start);
                $form_def_sections[] = $section;
                $section_start = $brackets_loc;
            }
            $start_position = $brackets_loc + 1;
        }
        // end while
        $form_def_sections[] = trim(substr($form_def, $section_start));
        // Cycle through the form definition file, and possibly an
        // existing article as well, finding template and field
        // declarations and replacing them with form elements, either
        // blank or pre-populated, as appropriate.
        $tif = null;
        // This array will keep track of all the replaced @<name>@ strings
        $placeholderFields = array();
        for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
            $start_position = 0;
            // the append is there to ensure that the original
            // array doesn't get modified; is it necessary?
            $section = " " . $form_def_sections[$section_num];
            while ($brackets_loc = strpos($section, '{{{', $start_position)) {
                $brackets_end_loc = strpos($section, "}}}", $brackets_loc);
                $bracketed_string = substr($section, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
                $tag_components = SFUtils::getFormTagComponents($bracketed_string);
                $tag_title = trim($tag_components[0]);
                // =====================================================
                // for template processing
                // =====================================================
                if ($tag_title == 'for template') {
                    if ($tif) {
                        $previous_template_name = $tif->getTemplateName();
                    } else {
                        $previous_template_name = '';
                    }
                    $template_name = str_replace('_', ' ', $tag_components[1]);
                    $is_new_template = $template_name != $previous_template_name;
                    if ($is_new_template) {
                        $tif = SFTemplateInForm::newFromFormTag($tag_components);
                    }
                    // Remove template tag.
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // If we are editing a page, and this
                    // template can be found more than
                    // once in that page, and multiple
                    // values are allowed, repeat this
                    // section.
                    if ($source_is_page) {
                        $tif->setPageRelatedInfo($existing_page_content);
                        // Get the first instance of
                        // this template on the page
                        // being edited, even if there
                        // are more.
                        if ($tif->pageCallsThisTemplate()) {
                            $tif->setFieldValuesFromPage($existing_page_content);
                            $existing_template_text = $tif->getFullTextInPage();
                            // Now remove this template from the text being edited.
                            // If this is a partial form, establish a new insertion point.
                            if ($existing_page_content && $form_is_partial && $wgRequest->getCheck('partial')) {
                                // If something already exists, set the new insertion point
                                // to its position; otherwise just let it lie.
                                if (strpos($existing_page_content, $existing_template_text) !== false) {
                                    $existing_page_content = str_replace("\n" . '{{{insertionpoint}}}', '', $existing_page_content);
                                    $existing_page_content = str_replace($existing_template_text, '{{{insertionpoint}}}', $existing_page_content);
                                }
                            } else {
                                $existing_page_content = $this->strReplaceFirst($existing_template_text, '', $existing_page_content);
                            }
                            // If we've found a match in the source
                            // page, there's a good chance that this
                            // page was created with this form - note
                            // that, so we don't send the user a warning.
                            $source_page_matches_this_form = true;
                        }
                    }
                    if ($form_submitted) {
                        $tif->setFieldValuesFromSubmit();
                    }
                    $tif->checkIfAllInstancesPrinted($form_submitted, $source_is_page);
                    if (!$tif->allInstancesPrinted()) {
                        $wiki_page->addTemplate($tif);
                    }
                    // =====================================================
                    // end template processing
                    // =====================================================
                } elseif ($tag_title == 'end template') {
                    if ($source_is_page) {
                        // Add any unhandled template fields
                        // in the page as hidden variables.
                        $form_text .= SFFormUtils::unhandledFieldsHTML($tif);
                    }
                    // Remove this tag from the $section variable.
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    $tif = null;
                    // =====================================================
                    // field processing
                    // =====================================================
                } elseif ($tag_title == 'field') {
                    // If the template is null, that (hopefully)
                    // means we're handling the free text field.
                    // Make the template a dummy variable.
                    if ($tif == null) {
                        $tif = new SFTemplateInForm();
                    }
                    // We get the field name both here
                    // and in the SFFormField constructor,
                    // because SFFormField isn't equipped
                    // to deal with the <freetext> hack,
                    // among others.
                    $field_name = trim($tag_components[1]);
                    $form_field = SFFormField::newFromFormFieldTag($tag_components, $tif, $form_is_disabled);
                    $cur_value = $form_field->getCurrentValue($tif->getValuesFromSubmit(), $form_submitted, $source_is_page);
                    if ($form_field->holdsTemplate()) {
                        $placeholderFields[] = self::placeholderFormat($tif->getTemplateName(), $field_name);
                    }
                    // If the user is editing a page, and that page contains a call to
                    // the template being processed, get the current field's value
                    // from the template call
                    if ($source_is_page && ($tif->getFullTextInPage() != '' && !$form_submitted)) {
                        if ($tif->hasValueFromPageForField($field_name)) {
                            // Get value, and remove it,
                            // so that at the end we
                            // can have a list of all
                            // the fields that weren't
                            // handled by the form.
                            $cur_value = $tif->getAndRemoveValueFromPageForField($field_name);
                            // If the field is a placeholder, the contents of this template
                            // parameter should be treated as elements parsed by an another
                            // multiple template form.
                            // By putting that at the very end of the parsed string, we'll
                            // have it processed as a regular multiple template form.
                            if ($form_field->holdsTemplate()) {
                                $existing_page_content .= $cur_value;
                            }
                        } elseif (isset($cur_value) && !empty($cur_value)) {
                            // Do nothing.
                        } else {
                            $cur_value = '';
                        }
                    }
                    // Handle the free text field.
                    if ($field_name == '<freetext>') {
                        // Add placeholders for the free text in both the form and
                        // the page, using <free_text> tags - once all the free text
                        // is known (at the end), it will get substituted in.
                        if ($form_field->isHidden()) {
                            $new_text = Html::hidden('sf_free_text', '!free_text!');
                        } else {
                            $sfgTabIndex++;
                            $sfgFieldNum++;
                            if ($cur_value === '' || is_null($cur_value)) {
                                $default_value = '!free_text!';
                            } else {
                                $default_value = $cur_value;
                            }
                            $new_text = SFTextAreaInput::getHTML($default_value, 'sf_free_text', false, $form_is_disabled || $form_field->isRestricted(), $form_field->getFieldArgs());
                            if ($form_field->hasFieldArg('edittools')) {
                                // borrowed from EditPage::showEditTools()
                                $edittools_text = $wgParser->recursiveTagParse(wfMessage('edittools', array('content'))->text());
                                $new_text .= <<<END
\t\t<div class="mw-editTools">
\t\t{$edittools_text}
\t\t</div>

END;
                            }
                        }
                        $free_text_was_included = true;
                        $wiki_page->addFreeTextSection();
                    }
                    if ($tif->getTemplateName() === '' || $field_name == '<freetext>') {
                        $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    } else {
                        if (is_array($cur_value)) {
                            // @TODO - is this code ever called?
                            $delimiter = $form_field->getFieldArg('is_list');
                            // first, check if it's a list
                            if (array_key_exists('is_list', $cur_value) && $cur_value['is_list'] == true) {
                                $cur_value_in_template = "";
                                foreach ($cur_value as $key => $val) {
                                    if ($key !== "is_list") {
                                        if ($cur_value_in_template != "") {
                                            $cur_value_in_template .= $delimiter . " ";
                                        }
                                        $cur_value_in_template .= $val;
                                    }
                                }
                            } else {
                                // If it's not a list, it's probably from a checkbox or date input -
                                // convert the values into a string.
                                $cur_value_in_template = self::getStringFromPassedInArray($cur_value, $delimiter);
                            }
                        } else {
                            // value is not an array
                            $cur_value_in_template = $cur_value;
                        }
                        // If we're creating the page name from a formula based on
                        // form values, see if the current input is part of that formula,
                        // and if so, substitute in the actual value.
                        if ($form_submitted && $generated_page_name !== '') {
                            // This line appears to be unnecessary.
                            // $generated_page_name = str_replace('.', '_', $generated_page_name);
                            $generated_page_name = str_replace(' ', '_', $generated_page_name);
                            $escaped_input_name = str_replace(' ', '_', $form_field->getInputName());
                            $generated_page_name = str_ireplace("<{$escaped_input_name}>", $cur_value_in_template, $generated_page_name);
                            // Once the substitution is done, replace underlines back
                            // with spaces.
                            $generated_page_name = str_replace('_', ' ', $generated_page_name);
                        }
                        // Call hooks - unfortunately this has to be split into two
                        // separate calls, because of the different variable names in
                        // each case.
                        if ($form_submitted) {
                            Hooks::run('sfCreateFormField', array(&$form_field, &$cur_value_in_template, true));
                        } else {
                            if (!empty($cur_value) && ($form_field->hasFieldArg('mapping template') || $form_field->hasFieldArg('mapping property') || $form_field->hasFieldArg('mapping cargo table') && $form_field->hasFieldArg('mapping cargo field'))) {
                                $cur_value = SFUtils::valuesToLabels($cur_value, $delimiter, $form_field->getPossibleValues());
                            }
                            Hooks::run('sfCreateFormField', array(&$form_field, &$cur_value, false));
                        }
                        // if this is not part of a 'multiple' template, increment the
                        // global tab index (used for correct tabbing)
                        if (!$form_field->hasFieldArg('part_of_multiple')) {
                            $sfgTabIndex++;
                        }
                        // increment the global field number regardless
                        $sfgFieldNum++;
                        // If the field is a date field, and its default value was set
                        // to 'now', and it has no current value, set $cur_value to be
                        // the current date.
                        if ($form_field->getDefaultValue() == 'now' && ($cur_value == '' || $cur_value == 'now')) {
                            $input_type = $form_field->getInputType();
                            if ($input_type == 'date' || $input_type == 'datetime' || $input_type == 'year' || $input_type == '' && $form_field->getTemplateField()->getPropertyType() == '_dat') {
                                $cur_value_in_template = self::getStringForCurrentTime($input_type == 'datetime', $form_field->hasFieldArg('include timezone'));
                            }
                        }
                        // If the field is a text field, and its default value was set
                        // to 'current user', and it has no current value, set $cur_value
                        // to be the current user.
                        if ($form_field->getDefaultValue() == 'current user' && ($cur_value === '' || $cur_value == 'current user')) {
                            $cur_value_in_template = $wgUser->getName();
                            $cur_value = $cur_value_in_template;
                        }
                        // If all instances have been
                        // printed, that means we're
                        // now printing a "starter"
                        // div - set the current value
                        // to null.
                        // (Ideally it wouldn't get
                        // set at all, but that seems a
                        // little harder.)
                        if ($tif->allInstancesPrinted()) {
                            $cur_value = null;
                        }
                        $new_text = $this->formFieldHTML($form_field, $cur_value);
                        $new_text .= $form_field->additionalHTMLForInput($cur_value, $field_name, $tif->getTemplateName());
                        if ($new_text) {
                            $wiki_page->addTemplateParam($template_name, $tif->getInstanceNum(), $field_name, $cur_value_in_template);
                            $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        } else {
                            $start_position = $brackets_end_loc;
                        }
                    }
                    // =====================================================
                    // standard input processing
                    // =====================================================
                } elseif ($tag_title == 'standard input') {
                    // handle all the possible values
                    $input_name = $tag_components[1];
                    $input_label = null;
                    $attr = array();
                    // if it's a query, ignore all standard inputs except run query
                    if ($is_query && $input_name != 'run query' || !$is_query && $input_name == 'run query') {
                        $new_text = "";
                        $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        continue;
                    }
                    // set a flag so that the standard 'form bottom' won't get displayed
                    $this->standardInputsIncluded = true;
                    // cycle through the other components
                    $is_checked = false;
                    for ($i = 2; $i < count($tag_components); $i++) {
                        $component = $tag_components[$i];
                        $sub_components = array_map('trim', explode('=', $component));
                        if (count($sub_components) == 1) {
                            if ($sub_components[0] == 'checked') {
                                $is_checked = true;
                            }
                        } elseif (count($sub_components) == 2) {
                            switch ($sub_components[0]) {
                                case 'label':
                                    $input_label = $wgParser->recursiveTagParse($sub_components[1]);
                                    break;
                                case 'class':
                                case 'style':
                                    $attr[$sub_components[0]] = $sub_components[1];
                                    break;
                            }
                        }
                    }
                    if ($input_name == 'summary') {
                        $value = $wgRequest->getVal('wpSummary');
                        $new_text = SFFormUtils::summaryInputHTML($form_is_disabled, $input_label, $attr, $value);
                    } elseif ($input_name == 'minor edit') {
                        $is_checked = $wgRequest->getCheck('wpMinoredit');
                        $new_text = SFFormUtils::minorEditInputHTML($form_submitted, $form_is_disabled, $is_checked, $input_label, $attr);
                    } elseif ($input_name == 'watch') {
                        $is_checked = $wgRequest->getCheck('wpWatchthis');
                        $new_text = SFFormUtils::watchInputHTML($form_submitted, $form_is_disabled, $is_checked, $input_label, $attr);
                    } elseif ($input_name == 'save') {
                        $new_text = SFFormUtils::saveButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'save and continue') {
                        $new_text = SFFormUtils::saveAndContinueButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'preview') {
                        $new_text = SFFormUtils::showPreviewButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'changes') {
                        $new_text = SFFormUtils::showChangesButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'cancel') {
                        $new_text = SFFormUtils::cancelLinkHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'run query') {
                        $new_text = SFFormUtils::runQueryButtonHTML($form_is_disabled, $input_label, $attr);
                    }
                    $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // for section processing
                    // =====================================================
                } elseif ($tag_title == 'section') {
                    $section_name = trim($tag_components[1]);
                    $page_section_in_form = SFPageSection::newFromFormTag($tag_components);
                    // Split the existing page contents into the textareas in the form.
                    $default_value = "";
                    $section_start_loc = 0;
                    if ($source_is_page && $existing_page_content !== null) {
                        // For the last section of the page, there is no trailing newline in
                        // $existing_page_content, but the code below expects it. This code
                        // ensures that there is always trailing newline. T72202
                        if (substr($existing_page_content, -1) !== "\n") {
                            $existing_page_content .= "\n";
                        }
                        $equalsSigns = str_pad('', $page_section_in_form->getSectionLevel(), '=');
                        $searchStr = '/^' . preg_quote($equalsSigns, '/') . '[ ]*?' . preg_quote($section_name, '/') . '[ ]*?' . preg_quote($equalsSigns, '/') . '$/m';
                        if (preg_match($searchStr, $existing_page_content, $matches, PREG_OFFSET_CAPTURE)) {
                            $section_start_loc = $matches[0][1];
                            $header_text = $matches[0][0];
                            $existing_page_content = str_replace($header_text, '', $existing_page_content);
                        } else {
                            $section_start_loc = 0;
                        }
                        $section_end_loc = -1;
                        // get the position of the next template or section defined in the form
                        $next_section_start_loc = strpos($section, '{{{', $brackets_end_loc);
                        if ($next_section_start_loc == false) {
                            $section_end_loc = strpos($existing_page_content, '{{', $section_start_loc);
                        } else {
                            $next_section_end_loc = strpos($section, '}}}', $next_section_start_loc);
                            $bracketed_string_next_section = substr($section, $next_section_start_loc + 3, $next_section_end_loc - ($next_section_start_loc + 3));
                            $tag_components_next_section = SFUtils::getFormTagComponents($bracketed_string_next_section);
                            $tag_title_next_section = trim($tag_components_next_section[0]);
                            if ($tag_title_next_section == 'section') {
                                if (preg_match('/(^={1,6}[ ]*?' . $tag_components_next_section[1] . '[ ]*?={1,6}\\s*?$)/m', $existing_page_content, $matches, PREG_OFFSET_CAPTURE)) {
                                    $section_end_loc = $matches[0][1];
                                }
                            }
                        }
                        if ($section_end_loc === -1) {
                            $section_text = $existing_page_content;
                            $existing_page_content = '';
                        } else {
                            $section_text = substr($existing_page_content, $section_start_loc, $section_end_loc - $section_start_loc);
                            $existing_page_content = substr($existing_page_content, $section_end_loc);
                        }
                    }
                    // If input is from the form.
                    if (!$source_is_page && $wgRequest) {
                        $text_per_section = $wgRequest->getArray('_section');
                        $section_text = $text_per_section[trim($section_name)];
                        $wiki_page->addSection($section_name, $page_section_in_form->getSectionLevel(), $section_text);
                    }
                    $section_text = trim($section_text);
                    // Set input name for query string.
                    $input_name = '_section' . '[' . trim($section_name) . ']';
                    $other_args = $page_section_in_form->getSectionArgs();
                    $other_args['isSection'] = true;
                    if ($page_section_in_form->isMandatory()) {
                        $other_args['mandatory'] = true;
                    }
                    if ($page_section_in_form->isHidden()) {
                        $form_section_text = Html::hidden($input_name, $section_text);
                    } else {
                        $form_section_text = SFTextAreaInput::getHTML($section_text, $input_name, false, $form_is_disabled || $page_section_in_form->isRestricted(), $other_args);
                    }
                    $section = substr_replace($section, $form_section_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // page info processing
                    // =====================================================
                } elseif ($tag_title == 'info') {
                    // TODO: Generate an error message if this is included more than once
                    foreach (array_slice($tag_components, 1) as $component) {
                        $sub_components = array_map('trim', explode('=', $component, 2));
                        // Tag names are case-insensitive
                        $tag = strtolower($sub_components[0]);
                        if ($tag == 'create title' || $tag == 'add title') {
                            // Handle this only if
                            // we're adding a page.
                            if (!$is_query && !$this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'edit title') {
                            // Handle this only if
                            // we're editing a page.
                            if (!$is_query && $this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'query title') {
                            // Handle this only if
                            // we're in 'RunQuery'.
                            if ($is_query) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'partial form') {
                            $form_is_partial = true;
                            // replacement pages may have minimal matches...
                            $source_page_matches_this_form = true;
                        } elseif ($tag == 'includeonly free text' || $tag == 'onlyinclude free text') {
                            $wiki_page->makeFreeTextOnlyInclude();
                        } elseif ($tag == 'query form at top') {
                            // TODO - this should be made a field of
                            // some non-static class that actually
                            // prints the form, instead of requiring
                            // a global variable.
                            global $sfgRunQueryFormAtTop;
                            $sfgRunQueryFormAtTop = true;
                        }
                    }
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // default outer level processing
                    // =====================================================
                } else {
                    // Tag is not one of the three allowed values -
                    // ignore the tag.
                    $start_position = $brackets_end_loc;
                }
                // end if
            }
            // end while
            if ($tif && (!$tif->allowsMultiple() || $tif->allInstancesPrinted())) {
                $template_text = $wiki_page->createTemplateCallsForTemplateName($tif->getTemplateName());
                // If there is a placeholder in the text, we
                // know that we are doing a replace.
                if ($existing_page_content && strpos($existing_page_content, '{{{insertionpoint}}}', 0) !== false) {
                    $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}(\\r?\\n?)/', preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "\n{{{insertionpoint}}}", $existing_page_content);
                    // Otherwise, if it's a partial form, we have to add the new
                    // text somewhere.
                } elseif ($form_is_partial && $wgRequest->getCheck('partial')) {
                    $existing_page_content = preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "{{{insertionpoint}}}" . $existing_page_content;
                }
            }
            if ($tif && $tif->allowsMultiple()) {
                if ($tif->getInstanceNum() == 0) {
                    $multipleTemplateHTML = $this->multipleTemplateStartHTML($tif);
                } else {
                    $multipleTemplateHTML = '';
                }
                if (!$tif->allInstancesPrinted()) {
                    $multipleTemplateHTML .= $this->multipleTemplateInstanceHTML($tif, $form_is_disabled, $section);
                } else {
                    $multipleTemplateHTML .= $this->multipleTemplateEndHTML($tif, $form_is_disabled, $section);
                }
                $placeholder = $tif->getPlaceholder();
                if ($placeholder != null) {
                    $multipleTemplateHTML .= self::makePlaceholderInFormHTML($placeholder);
                }
                if ($tif->allInstancesPrinted() && $tif->getLabel() != null) {
                    $multipleTemplateHTML .= "</fieldset>\n";
                }
                if ($placeholder == null) {
                    // The normal process.
                    $form_text .= $multipleTemplateHTML;
                } else {
                    // The template text won't be appended
                    // at the end of the template like for
                    // usual multiple template forms.
                    // The HTML text will instead be stored in
                    // the $multipleTemplateHTML variable,
                    // and then added in the right
                    // @insertHTML_".$placeHolderField."@"; position
                    // Optimization: actually, instead of
                    // separating the processes, the usual
                    // multiple template forms could also be
                    // handled this way if a fitting
                    // placeholder tag was added.
                    // We replace the HTML into the current
                    // placeholder tag, but also add another
                    // placeholder tag, to keep track of it.
                    $form_text = str_replace(self::makePlaceholderInFormHTML($placeholder), $multipleTemplateHTML, $form_text);
                }
                if (!$tif->allInstancesPrinted()) {
                    // This will cause the section to be
                    // re-parsed on the next go.
                    $section_num--;
                    $tif->incrementInstanceNum();
                }
            } else {
                $form_text .= $section;
            }
        }
        // end for
        // Cleanup - everything has been browsed.
        // Remove all the remaining placeholder
        // tags in the HTML and wiki-text.
        foreach ($placeholderFields as $stringToReplace) {
            // Remove the @<insertHTML>@ tags from the generated
            // HTML form.
            $form_text = str_replace(self::makePlaceholderInFormHTML($stringToReplace), '', $form_text);
        }
        // If it wasn't included in the form definition, add the
        // 'free text' input as a hidden field at the bottom.
        if (!$free_text_was_included) {
            $form_text .= Html::hidden('sf_free_text', '!free_text!');
        }
        // Get free text, and add to page data, as well as retroactively
        // inserting it into the form.
        // If $form_is_partial is true then either:
        // (a) we're processing a replacement (param 'partial' == 1)
        // (b) we're sending out something to be replaced (param 'partial' is missing)
        if ($form_is_partial) {
            if (!$wgRequest->getCheck('partial')) {
                $free_text = $original_page_content;
            } else {
                $free_text = null;
                $existing_page_content = preg_replace(array('/�\\{/m', '/\\}�/m'), array('{{', '}}'), $existing_page_content);
                $existing_page_content = str_replace('{{{insertionpoint}}}', '', $existing_page_content);
            }
            $form_text .= Html::hidden('partial', 1);
        } elseif ($source_is_page) {
            // If the page is the source, free_text will just be
            // whatever in the page hasn't already been inserted
            // into the form.
            $free_text = trim($existing_page_content);
            // or get it from a form submission
        } elseif ($wgRequest->getCheck('sf_free_text')) {
            $free_text = $wgRequest->getVal('sf_free_text');
            if (!$free_text_was_included) {
                $wiki_page->addFreeTextSection();
            }
        } else {
            $free_text = null;
        }
        if ($wiki_page->freeTextOnlyInclude()) {
            $free_text = str_replace("<onlyinclude>", '', $free_text);
            $free_text = str_replace("</onlyinclude>", '', $free_text);
            $free_text = trim($free_text);
        }
        $page_text = '';
        // The first hook here is deprecated. Use the second.
        // Note: Hooks::run can take a third argument which indicates
        // a deprecated hook, but it expects a MediaWiki version, not
        // an extension version.
        Hooks::run('sfModifyFreeTextField', array(&$free_text, $existing_page_content));
        Hooks::run('sfBeforeFreeTextSubstitution', array(&$free_text, $existing_page_content, &$page_text));
        // Now that we have it, add free text to the page, and
        // substitute it into the form.
        if ($form_submitted) {
            $wiki_page->setFreeText($free_text);
            $page_text = $wiki_page->createPageText();
        }
        $escaped_free_text = Sanitizer::safeEncodeAttribute($free_text);
        $form_text = str_replace('!free_text!', $escaped_free_text, $form_text);
        // Add a warning in, if we're editing an existing page and that
        // page appears to not have been created with this form.
        if (!$is_query && is_null($page_name_formula) && $this->mPageTitle->exists() && $existing_page_content !== '' && !$source_page_matches_this_form) {
            $form_text = "\t" . '<div class="warningbox">' . wfMessage('sf_formedit_formwarning', $this->mPageTitle->getFullURL())->text() . "</div>\n<br clear=\"both\" />\n" . $form_text;
        }
        // Add form bottom, if no custom "standard inputs" have been defined.
        if (!$this->standardInputsIncluded) {
            if ($is_query) {
                $form_text .= SFFormUtils::queryFormBottom($form_is_disabled);
            } else {
                $form_text .= SFFormUtils::formBottom($form_submitted, $form_is_disabled);
            }
        }
        if (!$is_query) {
            $form_text .= Html::hidden('wpStarttime', wfTimestampNow());
            $article = new Article($this->mPageTitle, 0);
            $form_text .= Html::hidden('wpEdittime', $article->getTimestamp());
            $form_text .= Html::hidden('wpEditToken', $wgUser->getEditToken());
        }
        $form_text .= "\t</form>\n";
        $wgParser->replaceLinkHolders($form_text);
        Hooks::run('sfRenderingEnd', array(&$form_text));
        // Add general Javascript code.
        $javascript_text = "";
        Hooks::run('sfAddJavascriptToForm', array(&$javascript_text));
        // Send the autocomplete values to the browser, along with the
        // mappings of which values should apply to which fields.
        // If doing a replace, the page text is actually the modified
        // original page.
        if ($wgRequest->getCheck('partial')) {
            $page_text = $existing_page_content;
        }
        if (!$is_embedded) {
            $form_page_title = $wgParser->recursiveTagParse(str_replace("{{!}}", "|", $form_page_title));
        } else {
            $form_page_title = null;
        }
        // If the form has already been submitted, i.e. this is just
        // the redirect page, get rid of all the Javascript, to avoid
        // JS errors.
        if ($form_submitted) {
            $javascript_text = '';
        }
        //		$wgParser = $oldParser;
        return array($form_text, $javascript_text, $page_text, $form_page_title, $generated_page_name);
    }
Ejemplo n.º 5
0
	function execute( $query ) {
		global $wgOut, $wgRequest;

		$this->setHeaders();

		$form_name = $wgRequest->getVal( 'form' );
		$target_namespace = $wgRequest->getVal( 'namespace' );
		$super_page = $wgRequest->getVal( 'super_page' );
		$params = $wgRequest->getVal( 'params' );

		// If the query string did not contain a form name, try the URL
		if ( ! $form_name ) {
			$queryparts = explode( '/', $query, 2 );
			$form_name = isset( $queryparts[0] ) ? $queryparts[0] : '';
			// If a target was specified, it means we should
			// redirect to 'FormEdit' for this target page.
			if ( isset( $queryparts[1] ) ) {
				$target_name = $queryparts[1];
				$this->doRedirect( $form_name, $target_name, $params );
			}

			// Get namespace from the URL, if it's there.
			if ( $namespace_label_loc = strpos( $form_name, "/Namespace:" ) ) {
				$target_namespace = substr( $form_name, $namespace_label_loc + 11 );
				$form_name = substr( $form_name, 0, $namespace_label_loc );
			}
		}

		// Remove forbidden characters from the form name.
		$forbidden_chars = array( '"', "'", '<', '>', '{', '}', '(', ')', '[', ']', '=' );
		$form_name = str_replace( $forbidden_chars, "", $form_name );

		// Get title of form.
		$form_title = Title::makeTitleSafe( SF_NS_FORM, $form_name );

		// Handle submission of this form.
		$form_submitted = $wgRequest->getCheck( 'page_name' );
		if ( $form_submitted ) {
			$page_name = $wgRequest->getVal( 'page_name' );
			// This form can be used to create a sub-page for an
			// existing page
			if ( !is_null( $super_page ) && $super_page !== '' ) {
				$page_name = "$super_page/$page_name";
			}

			if ( $page_name !== '' ) {
				// Append the namespace prefix to the page name,
				// if this namespace was not already entered.
				if ( strpos( $page_name, $target_namespace . ':' ) === false && !is_null( $target_namespace ) )
					$page_name = $target_namespace . ':' . $page_name;
				// If there was no page title, it's probably an
				// invalid page name, containing forbidden
				// characters - in that case, display an error
				// message.
				$page_title = Title::newFromText( $page_name );
				if ( !$page_title ) {
					$wgOut->addHTML( htmlspecialchars( wfMsg( 'sf_formstart_badtitle', $page_name ) ) );
					return;
				} else {
					$this->doRedirect( $form_name, $page_name, $params );
					return;
				}
			}
		}

		if ( ( !$form_title || !$form_title->exists() ) && ( $form_name !== '' ) ) {
			$text = Html::rawElement( 'p', array( 'class' => 'error' ), wfMsgExt( 'sf_formstart_badform', 'parseinline', SFUtils::linkText( SF_NS_FORM, $form_name ) ) ) . "\n";
		} else {
			if ( $form_name === '' ) {
				$description = htmlspecialchars( wfMsg( 'sf_formstart_noform_docu', $form_name ) );
			}
			else {
				$description = htmlspecialchars( wfMsg( 'sf_formstart_docu', $form_name ) );
			}

			$text = <<<END
	<form action="" method="post">
	<p>$description</p>
	<p><input type="text" size="40" name="page_name" />

END;
			// If no form was specified, display a dropdown letting
			// the user choose the form.
			if ( $form_name === '' )
				$text .= SFUtils::formDropdownHTML();

			$text .= "\t</p>\n";
			$text .= SFFormUtils::hiddenFieldHTML( 'namespace', $target_namespace );
			$text .= SFFormUtils::hiddenFieldHTML( 'super_page', $super_page );
			$text .= SFFormUtils::hiddenFieldHTML( 'params', $params );
			$text .= "\t" . Html::input( null, wfMsg( 'sf_formstart_createoredit' ), 'submit' ) . "\n";
			$text .= "\t</form>\n";
		}
		$wgOut->addHTML( $text );
	}
 private static function getAllValuesForProperty($property_name, $substring, $basePropertyName = null, $baseValue = null)
 {
     global $sfgMaxAutocompleteValues, $sfgCacheAutocompleteValues, $sfgAutocompleteCacheTimeout;
     global $smwgDefaultStore;
     $values = array();
     $db = wfGetDB(DB_SLAVE);
     $sqlOptions = array();
     $sqlOptions['LIMIT'] = $sfgMaxAutocompleteValues;
     $property = SMWPropertyValue::makeUserProperty($property_name);
     $propertyHasTypePage = $property->getPropertyTypeID() == '_wpg';
     $property_name = str_replace(' ', '_', $property_name);
     $conditions = array('p_ids.smw_title' => $property_name);
     // Use cache if allowed
     if ($sfgCacheAutocompleteValues) {
         $cache = SFFormUtils::getFormCache();
         // Remove trailing whitespace to avoid unnecessary database selects
         $cacheKeyString = $property_name . '::' . rtrim($substring);
         if (!is_null($basePropertyName)) {
             $cacheKeyString .= ',' . $basePropertyName . ',' . $baseValue;
         }
         $cacheKey = wfMemcKey('sf-autocomplete', md5($cacheKeyString));
         $values = $cache->get($cacheKey);
         if (!empty($values)) {
             // Return with results immediately
             return $values;
         }
     }
     if ($propertyHasTypePage) {
         $valueField = 'o_ids.smw_title';
         if ($smwgDefaultStore === 'SMWSQLStore3') {
             $idsTable = $db->tableName('smw_object_ids');
             $propsTable = $db->tableName('smw_di_wikipage');
         } else {
             $idsTable = $db->tableName('smw_ids');
             $propsTable = $db->tableName('smw_rels2');
         }
         $fromClause = "{$propsTable} p JOIN {$idsTable} p_ids ON p.p_id = p_ids.smw_id JOIN {$idsTable} o_ids ON p.o_id = o_ids.smw_id";
     } else {
         if ($smwgDefaultStore === 'SMWSQLStore3') {
             $valueField = 'p.o_hash';
             $idsTable = $db->tableName('smw_object_ids');
             $propsTable = $db->tableName('smw_di_blob');
         } else {
             $valueField = 'p.value_xsd';
             $idsTable = $db->tableName('smw_ids');
             $propsTable = $db->tableName('smw_atts2');
         }
         $fromClause = "{$propsTable} p JOIN {$idsTable} p_ids ON p.p_id = p_ids.smw_id";
     }
     if (!is_null($basePropertyName)) {
         $baseProperty = SMWPropertyValue::makeUserProperty($basePropertyName);
         $basePropertyHasTypePage = $baseProperty->getPropertyTypeID() == '_wpg';
         $basePropertyName = str_replace(' ', '_', $basePropertyName);
         $conditions['base_p_ids.smw_title'] = $basePropertyName;
         if ($basePropertyHasTypePage) {
             if ($smwgDefaultStore === 'SMWSQLStore3') {
                 $idsTable = $db->tableName('smw_object_ids');
                 $propsTable = $db->tableName('smw_di_wikipage');
             } else {
                 $idsTable = $db->tableName('smw_ids');
                 $propsTable = $db->tableName('smw_rels2');
             }
             $fromClause .= " JOIN {$propsTable} p_base ON p.s_id = p_base.s_id";
             $fromClause .= " JOIN {$idsTable} base_p_ids ON p_base.p_id = base_p_ids.smw_id JOIN {$idsTable} base_o_ids ON p_base.o_id = base_o_ids.smw_id";
             $baseValue = str_replace(' ', '_', $baseValue);
             $conditions['base_o_ids.smw_title'] = $baseValue;
         } else {
             if ($smwgDefaultStore === 'SMWSQLStore3') {
                 $baseValueField = 'p_base.o_hash';
                 $idsTable = $db->tableName('smw_object_ids');
                 $propsTable = $db->tableName('smw_di_blob');
             } else {
                 $baseValueField = 'p_base.value_xsd';
                 $idsTable = $db->tableName('smw_ids');
                 $propsTable = $db->tableName('smw_atts2');
             }
             $fromClause .= " JOIN {$propsTable} p_base ON p.s_id = p_base.s_id";
             $fromClause .= " JOIN {$idsTable} base_p_ids ON p_base.p_id = base_p_ids.smw_id";
             $conditions[$baseValueField] = $baseValue;
         }
     }
     if (!is_null($substring)) {
         // "Page" type property valeus are stored differently
         // in the DB, i.e. underlines instead of spaces.
         $conditions[] = SFUtils::getSQLConditionForAutocompleteInColumn($valueField, $substring, $propertyHasTypePage);
     }
     $sqlOptions['ORDER BY'] = $valueField;
     $res = $db->select($fromClause, "DISTINCT {$valueField}", $conditions, __METHOD__, $sqlOptions);
     while ($row = $db->fetchRow($res)) {
         $values[] = str_replace('_', ' ', $row[0]);
     }
     $db->freeResult($res);
     if ($sfgCacheAutocompleteValues) {
         // Save to cache.
         $cache->set($cacheKey, $values, $sfgAutocompleteCacheTimeout);
     }
     return $values;
 }
	/**
	 * Create the HTML and Javascript to display this field within a form
	 */
	function formFieldHTML( $form_field, $cur_value ) {
		// Also get the actual field, with all the semantic information
		// (type is SFTemplateField, instead of SFFormField)
		$template_field = $form_field->getTemplateField();

		if ( $form_field->isHidden() ) {
			$text = SFFormUtils::hiddenFieldHTML( $form_field->getInputName(), $cur_value );
		} elseif ( $form_field->getInputType() !== '' &&
							array_key_exists( $form_field->getInputType(), $this->mInputTypeHooks ) &&
							$this->mInputTypeHooks[$form_field->getInputType()] != null ) {
			$funcArgs = array();
			$funcArgs[] = $cur_value;
			$funcArgs[] = $form_field->getInputName();
			$funcArgs[] = $form_field->isMandatory();
			$funcArgs[] = $form_field->isDisabled();
			// last argument to function should be a hash, merging the default
			// values for this input type with all other properties set in
			// the form definition, plus some semantic-related arguments
			$hook_values = $this->mInputTypeHooks[$form_field->getInputType()];
			$other_args = $form_field->getArgumentsForInputCall( $hook_values[1] );
			$funcArgs[] = $other_args;
			$text = call_user_func_array( $hook_values[0], $funcArgs );
		} else { // input type not defined in form
			$property_type = $template_field->getPropertyType();
			$is_list = ( $form_field->isList() || $template_field->isList() );
			if ( $property_type !== '' &&
				array_key_exists( $property_type, $this->mSemanticTypeHooks ) &&
				isset( $this->mSemanticTypeHooks[$property_type][$is_list] ) ) {
				$funcArgs = array();
				$funcArgs[] = $cur_value;
				$funcArgs[] = $form_field->getInputName();
				$funcArgs[] = $form_field->isMandatory();
				$funcArgs[] = $form_field->isDisabled();
				$hook_values = $this->mSemanticTypeHooks[$property_type][$is_list];
				$other_args = $form_field->getArgumentsForInputCall( $hook_values[1] );
				$funcArgs[] = $other_args;
				$text = call_user_func_array( $hook_values[0], $funcArgs );
			} else { // anything else
				$other_args = $form_field->getArgumentsForInputCall();
				// special call to ensure that a list input is the right default size
				if ( $form_field->isList() ) {
					if ( ! array_key_exists( 'size', $other_args ) ) {
						$other_args['size'] = 100;
					}
				}
				$text = SFTextInput::getHTML( $cur_value, $form_field->getInputName(), $form_field->isMandatory(), $form_field->isDisabled(), $other_args );
			}
		}
		return $text;
	}
Ejemplo n.º 8
0
    /**
     * This function is the real heart of the entire Semantic Forms
     * extension. It handles two main actions: (1) displaying a form on the
     * screen, given a form definition and possibly page contents (if an
     * existing page is being edited); and (2) creating actual page
     * contents, if the form was already submitted by the user.
     *
     * It also does some related tasks, like figuring out the page name (if
     * only a page formula exists).
     */
    function formHTML($form_def, $form_submitted, $source_is_page, $form_id = null, $existing_page_content = null, $page_name = null, $page_name_formula = null, $is_query = false, $is_embedded = false)
    {
        global $wgRequest, $wgUser, $wgParser;
        global $sfgTabIndex;
        // used to represent the current tab index in the form
        global $sfgFieldNum;
        // used for setting various HTML IDs
        wfProfileIn(__METHOD__);
        // initialize some variables
        $sfgTabIndex = 1;
        $sfgFieldNum = 1;
        $source_page_matches_this_form = false;
        $form_page_title = null;
        $generated_page_name = $page_name_formula;
        // $form_is_partial is true if:
        // (a) 'partial' == 1 in the arguments
        // (b) 'partial form' is found in the form definition
        // in the latter case, it may remain false until close to the end of
        // the parsing, so we have to assume that it will become a possibility
        $form_is_partial = false;
        $new_text = "";
        // flag for placing "<onlyinclude>" tags in form output
        $onlyinclude_free_text = false;
        // If we have existing content and we're not in an active replacement
        // situation, preserve the original content. We do this because we want
        // to pass the original content on IF this is a partial form.
        // TODO: A better approach here would be to pass the revision ID of the
        // existing page content through the replace value, which would
        // minimize the html traffic and would allow us to do a concurrent
        // update check. For now, we pass it through a hidden text field.
        if (!$wgRequest->getCheck('partial')) {
            $original_page_content = $existing_page_content;
        } else {
            $original_page_content = null;
            if ($wgRequest->getCheck('sf_free_text')) {
                $existing_page_content = $wgRequest->getVal('sf_free_text');
                $form_is_partial = true;
            }
        }
        // Disable all form elements if user doesn't have edit
        // permission - two different checks are needed, because
        // editing permissions can be set in different ways.
        // HACK - sometimes we don't know the page name in advance, but
        // we still need to set a title here for testing permissions.
        if ($is_embedded) {
            // If this is an embedded form (probably a 'RunQuery'),
            // just use the name of the actual page we're on.
            global $wgTitle;
            $this->mPageTitle = $wgTitle;
        } elseif ($is_query) {
            $this->mPageTitle = Title::newFromText('RunQuery dummy title');
        } elseif ($page_name === '' || $page_name === null) {
            $this->mPageTitle = Title::newFromText($wgRequest->getVal('namespace') . ":Semantic Forms permissions test");
        } else {
            $this->mPageTitle = Title::newFromText($page_name);
        }
        global $wgOut;
        // show previous set of deletions for this page, if it's been deleted before
        if (!$form_submitted && ($this->mPageTitle && !$this->mPageTitle->exists())) {
            $this->showDeletionLog($wgOut);
        }
        // Unfortunately, we can't just call userCan() here because,
        // since MW 1.16, it has a bug in which it ignores a setting of
        // "$wgEmailConfirmToEdit = true;". Instead, we'll just get the
        // permission errors from the start, and use those to determine whether
        // the page is editable.
        if (!$is_query) {
            // $userCanEditPage = ( $wgUser->isAllowed( 'edit' ) && $this->mPageTitle->userCan( 'edit' ) );
            $permissionErrors = $this->mPageTitle->getUserPermissionsErrors('edit', $wgUser);
            // The handling of $wgReadOnly and $wgReadOnlyFile
            // has to be done separately.
            if (wfReadOnly()) {
                global $wgReadOnly;
                $permissionErrors = array(array('readonlytext', array(wfReadOnlyReason())));
            }
            $userCanEditPage = count($permissionErrors) == 0;
            wfRunHooks('sfUserCanEditPage', array($this->mPageTitle, &$userCanEditPage));
        }
        $form_text = "";
        if ($is_query || $userCanEditPage) {
            $form_is_disabled = false;
            // Show "Your IP address will be recorded" warning if
            // user is anonymous, and it's not a query -
            // wiki-text for bolding has to be replaced with HTML.
            if ($wgUser->isAnon() && !$is_query) {
                $anon_edit_warning = preg_replace("/'''(.*)'''/", "<strong>\$1</strong>", wfMsg('anoneditwarning'));
                $form_text .= "<p>{$anon_edit_warning}</p>\n";
            }
        } else {
            $form_is_disabled = true;
            $wgOut->setPageTitle(wfMsg('badaccess'));
            $wgOut->addWikiText($wgOut->formatPermissionsErrorMessage($permissionErrors, 'edit'));
            $wgOut->addHTML("\n<hr />\n");
        }
        //		$oldParser = $wgParser;
        //		$wgParser = unserialize( serialize( $oldParser ) ); // deep clone of parser
        if (!$wgParser->Options()) {
            $wgParser->Options(ParserOptions::newFromUser($wgUser));
        }
        $wgParser->Title($this->mPageTitle);
        //		$wgParser->clearState();
        $form_def = SFFormUtils::getFormDefinition($wgParser, $form_def, $form_id);
        // Turn form definition file into an array of sections, one for each
        // template definition (plus the first section)
        $form_def_sections = array();
        $start_position = 0;
        $section_start = 0;
        $free_text_was_included = false;
        $free_text_preload_page = null;
        $free_text_components = array();
        $all_values_for_template = array();
        // Unencode any HTML-encoded representations of curly brackets and
        // pipes - this is a hack to allow for forms to include templates
        // that themselves contain form elements - the escaping was needed
        // to make sure that those elements don't get parsed too early.
        $form_def = str_replace(array('&#123;', '&#124;', '&#125;'), array('{', '|', '}'), $form_def);
        // And another hack - replace the 'free text' standard input with
        // a field declaration to get it to be handled as a field.
        $form_def = str_replace('standard input|free text', 'field|<freetext>', $form_def);
        while ($brackets_loc = strpos($form_def, "{{{", $start_position)) {
            $brackets_end_loc = strpos($form_def, "}}}", $brackets_loc);
            $bracketed_string = substr($form_def, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
            $tag_components = SFUtils::getFormTagComponents($bracketed_string);
            $tag_title = trim($tag_components[0]);
            if ($tag_title == 'for template' || $tag_title == 'end template') {
                // Create a section for everything up to here
                $section = substr($form_def, $section_start, $brackets_loc - $section_start);
                $form_def_sections[] = $section;
                $section_start = $brackets_loc;
            }
            $start_position = $brackets_loc + 1;
        }
        // end while
        $form_def_sections[] = trim(substr($form_def, $section_start));
        // Cycle through the form definition file, and possibly an
        // existing article as well, finding template and field
        // declarations and replacing them with form elements, either
        // blank or pre-populated, as appropriate.
        $all_fields = array();
        $data_text = "";
        $template_name = "";
        $allow_multiple = false;
        $instance_num = 0;
        $all_instances_printed = false;
        $strict_parsing = false;
        // Placeholder name in the form
        $curPlaceholder = null;
        // Used to store the HTML code of the multiple template, to reinsert it into the right spot
        // This array will keep track of all the replaced @<name>@ strings
        $placeholderFields = array();
        for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
            $start_position = 0;
            $template_text = "";
            // the append is there to ensure that the original
            // array doesn't get modified; is it necessary?
            $section = " " . $form_def_sections[$section_num];
            $multipleTemplateString = "";
            while ($brackets_loc = strpos($section, '{{{', $start_position)) {
                $brackets_end_loc = strpos($section, "}}}", $brackets_loc);
                $bracketed_string = substr($section, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
                $tag_components = SFUtils::getFormTagComponents($bracketed_string);
                $tag_title = trim($tag_components[0]);
                // =====================================================
                // for template processing
                // =====================================================
                if ($tag_title == 'for template') {
                    $old_template_name = $template_name;
                    $template_name = trim($tag_components[1]);
                    $tif = SFTemplateInForm::create($template_name);
                    $query_template_name = str_replace(' ', '_', $template_name);
                    $add_button_text = wfMsg('sf_formedit_addanother');
                    // Also replace periods with underlines, since that's what
                    // POST does to strings anyway.
                    $query_template_name = str_replace('.', '_', $query_template_name);
                    // ...and escape apostrophes.
                    $query_template_name = str_replace("'", "\\'", $query_template_name);
                    // Cycle through the other components.
                    for ($i = 2; $i < count($tag_components); $i++) {
                        $component = $tag_components[$i];
                        if ($component == 'multiple') {
                            $allow_multiple = true;
                        }
                        if ($component == 'strict') {
                            $strict_parsing = true;
                        }
                        $sub_components = array_map('trim', explode('=', $component, 2));
                        if (count($sub_components) == 2) {
                            if ($sub_components[0] == 'label') {
                                $template_label = $sub_components[1];
                            } elseif ($sub_components[0] == 'add button text') {
                                $add_button_text = $sub_components[1];
                            } elseif ($sub_components[0] == 'embed in field') {
                                // Placeholder on form template level. Assume that the template form def
                                // will have a multiple+placeholder parameters, and get the placeholder value.
                                // We expect something like TemplateName[fieldName], and convert it to the
                                // TemplateName___fieldName form used internally.
                                preg_match('/\\s*(.*)\\[(.*)\\]\\s*/', $sub_components[1], $matches);
                                $curPlaceholder = count($matches) > 2 ? self::placeholderFormat($matches[1], $matches[2]) : null;
                                unset($matches);
                            }
                        }
                    }
                    // If this is the first instance, add
                    // the label into the form, if there is
                    // one, and add the appropriate wrapper
                    // div, if this is a multiple-instance
                    // template.
                    if ($old_template_name != $template_name) {
                        if (isset($template_label)) {
                            $multipleTemplateString .= "<fieldset>\n";
                            $multipleTemplateString .= Html::element('legend', null, $template_label) . "\n";
                        }
                        // If $curPlaceholder is set, it means we want to insert a
                        // multiple template form's HTML into the main form's HTML.
                        // So, the HTML will be stored in $multipleTemplateString.
                        if ($allow_multiple) {
                            $multipleTemplateString .= "\t" . '<div class="multipleTemplateWrapper">' . "\n";
                            $multipleTemplateString .= "\t" . '<div class="multipleTemplateList">' . "\n";
                        }
                    }
                    if ($curPlaceholder == null) {
                        $form_text .= $multipleTemplateString;
                    }
                    $template_text .= "{{" . $template_name;
                    $all_fields = $tif->getAllFields();
                    // remove template tag
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    $template_instance_query_values = $wgRequest->getArray($query_template_name);
                    // If we are editing a page, and this
                    // template can be found more than
                    // once in that page, and multiple
                    // values are allowed, repeat this
                    // section.
                    $existing_template_text = null;
                    if ($source_is_page || $form_is_partial) {
                        // Replace underlines with spaces in template name, to allow for
                        // searching on either.
                        $search_template_str = str_replace('_', ' ', $template_name);
                        $preg_match_template_str = str_replace(array('/', '(', ')'), array('\\/', '\\(', '\\)'), $search_template_str);
                        $found_instance = preg_match('/{{' . $preg_match_template_str . '\\s*[\\|}]/i', str_replace('_', ' ', $existing_page_content));
                        if ($allow_multiple) {
                            // find instances of this template in the page -
                            // if there's at least one, re-parse this section of the
                            // definition form for the subsequent template instances in
                            // this page; if there's none, don't include fields at all.
                            // there has to be a more efficient way to handle multiple
                            // instances of templates, one that doesn't involve re-parsing
                            // the same tags, but I don't know what it is.
                            if ($found_instance) {
                                $instance_num++;
                            } else {
                                $all_instances_printed = true;
                            }
                        }
                        // get the first instance of this template on the page being edited,
                        // even if there are more
                        if ($found_instance) {
                            $matches = array();
                            $search_pattern = '/{{' . $preg_match_template_str . '\\s*[\\|}]/i';
                            $content_str = str_replace('_', ' ', $existing_page_content);
                            preg_match($search_pattern, $content_str, $matches, PREG_OFFSET_CAPTURE);
                            // is this check necessary?
                            if (array_key_exists(0, $matches) && array_key_exists(1, $matches[0])) {
                                $start_char = $matches[0][1];
                                $fields_start_char = $start_char + 2 + strlen($search_template_str);
                                // Skip ahead to the first real character.
                                while (in_array($existing_page_content[$fields_start_char], array(' ', '\\n'))) {
                                    $fields_start_char++;
                                }
                                // If the next character is a pipe, skip that too.
                                if ($existing_page_content[$fields_start_char] == '|') {
                                    $fields_start_char++;
                                }
                                $template_contents = array('0' => '');
                                // Cycle through template call, splitting it up by pipes ('|'),
                                // except when that pipe is part of a piped link.
                                $field = "";
                                $uncompleted_square_brackets = 0;
                                $uncompleted_curly_brackets = 2;
                                $template_ended = false;
                                for ($i = $fields_start_char; !$template_ended && $i < strlen($existing_page_content); $i++) {
                                    $c = $existing_page_content[$i];
                                    if ($c == '[') {
                                        $uncompleted_square_brackets++;
                                    } elseif ($c == ']' && $uncompleted_square_brackets > 0) {
                                        $uncompleted_square_brackets--;
                                    } elseif ($c == '{') {
                                        $uncompleted_curly_brackets++;
                                    } elseif ($c == '}' && $uncompleted_curly_brackets > 0) {
                                        $uncompleted_curly_brackets--;
                                    }
                                    // handle an end to a field and/or template declaration
                                    $template_ended = $uncompleted_curly_brackets == 0 && $uncompleted_square_brackets == 0;
                                    $field_ended = $c == '|' && $uncompleted_square_brackets == 0 && $uncompleted_curly_brackets <= 2;
                                    if ($template_ended || $field_ended) {
                                        // if this was the last character in the template, remove
                                        // the closing curly brackets
                                        if ($template_ended) {
                                            $field = substr($field, 0, -1);
                                        }
                                        // either there's an equals sign near the beginning or not -
                                        // handling is similar in either way; if there's no equals
                                        // sign, the index of this field becomes the key
                                        $sub_fields = explode('=', $field, 2);
                                        if (count($sub_fields) > 1) {
                                            $template_contents[trim($sub_fields[0])] = trim($sub_fields[1]);
                                        } else {
                                            $template_contents[] = trim($sub_fields[0]);
                                        }
                                        $field = '';
                                    } else {
                                        $field .= $c;
                                    }
                                }
                                // If there are uncompleted opening brackets, the whole form will get messed up -
                                // display a warning.
                                // (If there are too many *closing* brackets, some template stuff will end up in
                                // the "free text" field - which is bad, but it's harder for the code to detect
                                // the problem - though hopefully, easier for users.)
                                if ($uncompleted_curly_brackets > 0 || $uncompleted_square_brackets > 0) {
                                    $form_text .= "\t" . '<div class="warningbox">' . wfMsg('sf_formedit_mismatchedbrackets', $this->mPageTitle->getFullURL(array('action' => 'edit'))) . "</div>\n<br clear=\"both\" />\n";
                                }
                                $existing_template_text = substr($existing_page_content, $start_char, $i - $start_char);
                                // now remove this template from the text being edited
                                // if this is a partial form, establish a new insertion point
                                if ($existing_page_content && $form_is_partial && $wgRequest->getCheck('partial')) {
                                    // if something already exists, set the new insertion point
                                    // to its position; otherwise just let it lie
                                    if (strpos($existing_page_content, $existing_template_text) !== false) {
                                        $existing_page_content = str_replace('{{{insertionpoint}}}', '', $existing_page_content);
                                        $existing_page_content = str_replace($existing_template_text, '{{{insertionpoint}}}', $existing_page_content);
                                    }
                                } else {
                                    $existing_page_content = $this->strReplaceFirst($existing_template_text, '', $existing_page_content);
                                }
                                // If this is not a multiple-instance template, and we've found
                                // a match in the source page, there's a good chance that this
                                // page was created with this form - note that, so we don't
                                // send the user a warning
                                // (multiple-instance templates have a greater chance of
                                // getting repeated from one form to the next)
                                // - on second thought, allow even the presence of multiple-
                                // instance templates to validate that this is the correct
                                // form: the problem is that some forms contain *only* mutliple-
                                // instance templates.
                                // if (! $allow_multiple) {
                                $source_page_matches_this_form = true;
                                // }
                            }
                        }
                    }
                    // If the input is from the form (meaning the user has hit one
                    // of the bottom row of buttons), and we're dealing with a
                    // multiple template, get the values for this instance of this
                    // template, then delete them from the array, so we can get the
                    // next group next time - the next() command for arrays doesn't
                    // seem to work here.
                    if (!$source_is_page && $allow_multiple && $wgRequest) {
                        $all_instances_printed = true;
                        if ($old_template_name != $template_name) {
                            $all_values_for_template = $wgRequest->getArray($query_template_name);
                        }
                        if ($all_values_for_template) {
                            $cur_key = key($all_values_for_template);
                            // skip the input coming in from the "starter" div
                            // TODO: this code is probably no longer necessary
                            if ($cur_key == 'num') {
                                unset($all_values_for_template[$cur_key]);
                                $cur_key = key($all_values_for_template);
                            }
                            if ($template_instance_query_values = current($all_values_for_template)) {
                                $all_instances_printed = false;
                                unset($all_values_for_template[$cur_key]);
                            }
                        }
                    }
                    // =====================================================
                    // end template processing
                    // =====================================================
                } elseif ($tag_title == 'end template') {
                    if ($source_is_page) {
                        // Add any unhandled template fields in the page as hidden variables.
                        if (isset($template_contents)) {
                            $form_text .= SFFormUtils::unhandledFieldsHTML($template_name, $template_contents);
                            $template_contents = null;
                        }
                    }
                    // Remove this tag, reset some variables, and close off form HTML tag.
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    $template_name = null;
                    if (isset($template_label) && $curPlaceholder == null) {
                        $form_text .= "</fieldset>\n";
                        unset($template_label);
                    }
                    $allow_multiple = false;
                    $all_instances_printed = false;
                    $instance_num = 0;
                    // =====================================================
                    // field processing
                    // =====================================================
                } elseif ($tag_title == 'field') {
                    $field_name = trim($tag_components[1]);
                    $fullFieldName = $template_name . '[' . $field_name . ']';
                    // cycle through the other components
                    $is_mandatory = false;
                    $is_hidden = false;
                    $is_restricted = false;
                    $is_uploadable = false;
                    $is_list = false;
                    $input_type = null;
                    $field_args = array();
                    $show_on_select = array();
                    $default_value = null;
                    $values = null;
                    $possible_values = null;
                    $semantic_property = null;
                    $preload_page = null;
                    $holds_template = false;
                    for ($i = 2; $i < count($tag_components); $i++) {
                        $component = trim($tag_components[$i]);
                        if ($component == 'mandatory') {
                            $is_mandatory = true;
                        } elseif ($component == 'hidden') {
                            $is_hidden = true;
                        } elseif ($component == 'restricted') {
                            $is_restricted = !$wgUser || !$wgUser->isAllowed('editrestrictedfields');
                        } elseif ($component == 'list') {
                            $is_list = true;
                        } elseif ($component == 'edittools') {
                            // free text only
                            $free_text_components[] = 'edittools';
                        }
                        $sub_components = array_map('trim', explode('=', $component, 2));
                        if (count($sub_components) == 1) {
                            // add handling for single-value params, for custom input types
                            $field_args[$sub_components[0]] = true;
                            if ($component == 'holds template') {
                                $is_hidden = true;
                                $holds_template = true;
                                $placeholderFields[] = self::placeholderFormat($template_name, $field_name);
                            }
                        } elseif (count($sub_components) == 2) {
                            // First, set each value as its own entry in $field_args.
                            $field_args[$sub_components[0]] = $sub_components[1];
                            // Then, do all special handling.
                            if ($sub_components[0] == 'input type') {
                                $input_type = $sub_components[1];
                            } elseif ($sub_components[0] == 'default') {
                                $default_value = $wgParser->recursiveTagParse($sub_components[1]);
                            } elseif ($sub_components[0] == 'preload') {
                                // free text field has special handling
                                if ($field_name == 'free text' || $field_name == '<freetext>') {
                                    $free_text_preload_page = $sub_components[1];
                                } else {
                                    $preload_page = $sub_components[1];
                                }
                            } elseif ($sub_components[0] == 'show on select') {
                                // html_entity_decode() is needed to turn '&gt;' to '>'
                                $vals = explode(';', html_entity_decode($sub_components[1]));
                                foreach ($vals as $val) {
                                    $val = trim($val);
                                    if (empty($val)) {
                                        continue;
                                    }
                                    $option_div_pair = explode('=>', $val, 2);
                                    if (count($option_div_pair) > 1) {
                                        $option = $option_div_pair[0];
                                        $div_id = $option_div_pair[1];
                                        if (array_key_exists($div_id, $show_on_select)) {
                                            $show_on_select[$div_id][] = $option;
                                        } else {
                                            $show_on_select[$div_id] = array($option);
                                        }
                                    } else {
                                        $show_on_select[$val] = array();
                                    }
                                }
                            } elseif ($sub_components[0] == 'autocomplete on property') {
                                $property_name = $sub_components[1];
                                $propValue = SMWPropertyValue::makeUserProperty($property_name);
                                if ($propValue->getPropertyTypeID() == '_wpg') {
                                    $field_args['autocomplete field type'] = 'relation';
                                } else {
                                    $field_args['autocomplete field type'] = 'attribute';
                                }
                                $field_args['autocompletion source'] = $sub_components[1];
                            } elseif ($sub_components[0] == 'autocomplete on category') {
                                $field_args['autocomplete field type'] = 'category';
                                $field_args['autocompletion source'] = $sub_components[1];
                            } elseif ($sub_components[0] == 'autocomplete on concept') {
                                $field_args['autocomplete field type'] = 'concept';
                                $field_args['autocompletion source'] = $sub_components[1];
                            } elseif ($sub_components[0] == 'autocomplete on namespace') {
                                $field_args['autocomplete field type'] = 'namespace';
                                $autocompletion_source = $sub_components[1];
                                // special handling for "main" (blank) namespace
                                if ($autocompletion_source == "") {
                                    $autocompletion_source = "main";
                                }
                                $field_args['autocompletion source'] = $autocompletion_source;
                            } elseif ($sub_components[0] == 'autocomplete from url') {
                                $field_args['autocomplete field type'] = 'external_url';
                                $field_args['autocompletion source'] = $sub_components[1];
                                // 'external' autocompletion is always done remotely, i.e. via API
                                $field_args['remote autocompletion'] = true;
                            } elseif ($sub_components[0] == 'values') {
                                // Handle this one only after 'delimiter' has
                                // also been set.
                                $values = $sub_components[1];
                            } elseif ($sub_components[0] == 'values from property') {
                                $propertyName = $sub_components[1];
                                $possible_values = SFUtils::getAllValuesForProperty($propertyName);
                            } elseif ($sub_components[0] == 'values from category') {
                                $category_name = ucfirst($sub_components[1]);
                                $possible_values = SFUtils::getAllPagesForCategory($category_name, 10);
                            } elseif ($sub_components[0] == 'values from concept') {
                                $possible_values = SFUtils::getAllPagesForConcept($sub_components[1]);
                            } elseif ($sub_components[0] == 'values from namespace') {
                                $possible_values = SFUtils::getAllPagesForNamespace($sub_components[1]);
                            } elseif ($sub_components[0] == 'values dependent on') {
                                global $sfgDependentFields;
                                $sfgDependentFields[] = array($sub_components[1], $fullFieldName);
                            } elseif ($sub_components[0] == 'property') {
                                $semantic_property = $sub_components[1];
                            } elseif ($sub_components[0] == 'default filename') {
                                $default_filename = str_replace('&lt;page name&gt;', $page_name, $sub_components[1]);
                                // Parse value, so default filename can include parser functions.
                                $default_filename = $wgParser->recursiveTagParse($default_filename);
                                $field_args['default filename'] = $default_filename;
                            } elseif ($sub_components[0] == 'restricted') {
                                $is_restricted = !array_intersect($wgUser->getEffectiveGroups(), array_map('trim', explode(',', $sub_components[1])));
                            }
                        }
                    }
                    // end for
                    // Backwards compatibility
                    if ($input_type == 'datetime with timezone') {
                        $input_type = 'datetime';
                        $field_args['include timezone'] = true;
                    } elseif ($input_type == 'text' || $input_type == 'textarea') {
                        // Also for backwards compatibility,
                        // in that once b/c goes away,
                        // this will no longer be
                        // necessary.
                        $field_args['no autocomplete'] = true;
                    }
                    if ($allow_multiple) {
                        $field_args['part_of_multiple'] = $allow_multiple;
                    }
                    if (count($show_on_select) > 0) {
                        $field_args['show on select'] = $show_on_select;
                    }
                    // Get the value from the request, if
                    // it's there, and if it's not an array.
                    $cur_value = null;
                    $escaped_field_name = str_replace("'", "\\'", $field_name);
                    if (isset($template_instance_query_values) && $template_instance_query_values != null && is_array($template_instance_query_values)) {
                        // If the field name contains an
                        // apostrophe, the array sometimes
                        // has the apostrophe escaped, and
                        // sometimes not. For now, just check
                        // for both versions.
                        // @TODO - figure this out.
                        $field_query_val = null;
                        if (array_key_exists($escaped_field_name, $template_instance_query_values)) {
                            $field_query_val = $template_instance_query_values[$escaped_field_name];
                        } elseif (array_key_exists($field_name, $template_instance_query_values)) {
                            $field_query_val = $template_instance_query_values[$field_name];
                        }
                        if ($form_submitted || $field_query_val != '' && !is_array($field_query_val)) {
                            $cur_value = $field_query_val;
                        }
                    }
                    if (empty($cur_value) && !$form_submitted) {
                        if (!is_null($default_value)) {
                            // Set to the default value specified in the form, if it's there.
                            $cur_value = $default_value;
                        } elseif ($preload_page) {
                            $cur_value = SFFormUtils::getPreloadedText($preload_page);
                        }
                    }
                    // If the user is editing a page, and that page contains a call to
                    // the template being processed, get the current field's value
                    // from the template call
                    if ($source_is_page && !empty($existing_template_text)) {
                        if (isset($template_contents[$field_name])) {
                            $cur_value = $template_contents[$field_name];
                            // If the field is a placeholder, the contents of this template
                            // parameter should be treated as elements parsed by an another
                            // multiple template form.
                            // By putting that at the very end of the parsed string, we'll
                            // have it processed as a regular multiple template form.
                            if ($holds_template) {
                                $existing_page_content = $existing_page_content . $cur_value;
                            }
                            // Now remove this value
                            // from $template_contents,
                            // so that at the end we
                            // can have a list of all
                            // the fields that weren't
                            // handled by the form.
                            unset($template_contents[$field_name]);
                        } else {
                            $cur_value = '';
                        }
                    }
                    // Handle the free text field.
                    if ($field_name == '<freetext>') {
                        // Add placeholders for the free text in both the form and
                        // the page, using <free_text> tags - once all the free text
                        // is known (at the end), it will get substituted in.
                        if ($is_hidden) {
                            $new_text = Html::hidden('sf_free_text', '!free_text!');
                        } else {
                            $sfgTabIndex++;
                            $sfgFieldNum++;
                            if ($cur_value === '' || is_null($cur_value)) {
                                $default_value = '!free_text!';
                            } else {
                                $default_value = $cur_value;
                                // If the FCKeditor extension is installed and
                                // active, the default value needs to be parsed
                                // for use in the editor.
                                global $wgFCKEditorDir;
                                if ($wgFCKEditorDir && strpos($existing_page_content, '__NORICHEDITOR__') === false) {
                                    $showFCKEditor = SFFormUtils::getShowFCKEditor();
                                    if (!$form_submitted && $showFCKEditor & RTE_VISIBLE) {
                                        $default_value = SFFormUtils::prepareTextForFCK($cur_value);
                                    }
                                }
                            }
                            $new_text = SFTextAreaInput::getHTML($default_value, 'sf_free_text', false, $form_is_disabled || $is_restricted, $field_args);
                            if (in_array('edittools', $free_text_components)) {
                                // borrowed from EditPage::showEditTools()
                                $options[] = 'parse';
                                $edittools_text = $wgParser->recursiveTagParse(wfMsg('edittools', array('content')));
                                $new_text .= <<<END
\t\t<div class="mw-editTools">
\t\t{$edittools_text}
\t\t</div>

END;
                            }
                        }
                        $free_text_was_included = true;
                        // add a similar placeholder to the data text
                        $data_text .= "!free_text!\n";
                    }
                    if ($template_name === '' || $field_name == '<freetext>') {
                        $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    } else {
                        if (is_array($cur_value)) {
                            // first, check if it's a list
                            if (array_key_exists('is_list', $cur_value) && $cur_value['is_list'] == true) {
                                $cur_value_in_template = "";
                                if (array_key_exists('delimiter', $field_args)) {
                                    $delimiter = $field_args['delimiter'];
                                } else {
                                    $delimiter = ",";
                                }
                                foreach ($cur_value as $key => $val) {
                                    if ($key !== "is_list") {
                                        if ($cur_value_in_template != "") {
                                            $cur_value_in_template .= $delimiter . " ";
                                        }
                                        $cur_value_in_template .= $val;
                                    }
                                }
                            } else {
                                // otherwise:
                                // if it has 1 or 2 elements, assume it's a checkbox; if it has
                                // 3 elements, assume it's a date
                                // - this handling will have to get more complex if other
                                // possibilities get added
                                if (count($cur_value) == 1) {
                                    $cur_value_in_template = SFUtils::getWordForYesOrNo(false);
                                } elseif (count($cur_value) == 2) {
                                    $cur_value_in_template = SFUtils::getWordForYesOrNo(true);
                                    // if it's 3 or greater, assume it's a date or datetime
                                } elseif (count($cur_value) >= 3) {
                                    $month = $cur_value['month'];
                                    $day = $cur_value['day'];
                                    if ($day !== '') {
                                        global $wgAmericanDates;
                                        if ($wgAmericanDates == false) {
                                            // pad out day to always be two digits
                                            $day = str_pad($day, 2, "0", STR_PAD_LEFT);
                                        }
                                    }
                                    $year = $cur_value['year'];
                                    $hour = $minute = $second = $ampm24h = $timezone = null;
                                    if (isset($cur_value['hour'])) {
                                        $hour = $cur_value['hour'];
                                    }
                                    if (isset($cur_value['minute'])) {
                                        $minute = $cur_value['minute'];
                                    }
                                    if (isset($cur_value['second'])) {
                                        $second = $cur_value['second'];
                                    }
                                    if (isset($cur_value['ampm24h'])) {
                                        $ampm24h = $cur_value['ampm24h'];
                                    }
                                    if (isset($cur_value['timezone'])) {
                                        $timezone = $cur_value['timezone'];
                                    }
                                    if ($month !== '' && $day !== '' && $year !== '') {
                                        // special handling for American dates - otherwise, just
                                        // the standard year/month/day (where month is a number)
                                        global $wgAmericanDates;
                                        if ($wgAmericanDates == true) {
                                            $cur_value_in_template = "{$month} {$day}, {$year}";
                                        } else {
                                            $cur_value_in_template = "{$year}/{$month}/{$day}";
                                        }
                                        // include whatever time information we have
                                        if (!is_null($hour)) {
                                            $cur_value_in_template .= " " . str_pad(intval(substr($hour, 0, 2)), 2, '0', STR_PAD_LEFT) . ":" . str_pad(intval(substr($minute, 0, 2)), 2, '0', STR_PAD_LEFT);
                                        }
                                        if (!is_null($second)) {
                                            $cur_value_in_template .= ":" . str_pad(intval(substr($second, 0, 2)), 2, '0', STR_PAD_LEFT);
                                        }
                                        if (!is_null($ampm24h)) {
                                            $cur_value_in_template .= " {$ampm24h}";
                                        }
                                        if (!is_null($timezone)) {
                                            $cur_value_in_template .= " {$timezone}";
                                        }
                                    } else {
                                        $cur_value_in_template = "";
                                    }
                                }
                            }
                        } else {
                            // value is not an array
                            $cur_value_in_template = $cur_value;
                        }
                        if ($template_name == null || $template_name === '') {
                            $input_name = $field_name;
                        } elseif ($allow_multiple) {
                            // 'num' will get replaced by an actual index, either in PHP
                            // or in Javascript, later on
                            $input_name = $template_name . '[num][' . $field_name . ']';
                            $field_args['origName'] = $template_name . '[' . $field_name . ']';
                        } else {
                            $input_name = $template_name . '[' . $field_name . ']';
                        }
                        // If the 'values' parameter was set, separate it based on the
                        // 'delimiter' parameter, if any.
                        if (!empty($values)) {
                            if (array_key_exists('delimiter', $field_args)) {
                                $delimiter = $field_args['delimiter'];
                            } else {
                                $delimiter = ",";
                            }
                            // Remove whitespaces, and un-escape characters
                            $possible_values = array_map('trim', explode($delimiter, $values));
                            $possible_values = array_map('htmlspecialchars_decode', $possible_values);
                        }
                        // if we're creating the page name from a formula based on
                        // form values, see if the current input is part of that formula,
                        // and if so, substitute in the actual value
                        if ($form_submitted && $generated_page_name !== '') {
                            // this line appears to be unnecessary
                            // $generated_page_name = str_replace('.', '_', $generated_page_name);
                            $generated_page_name = str_replace(' ', '_', $generated_page_name);
                            $escaped_input_name = str_replace(' ', '_', $input_name);
                            $generated_page_name = str_ireplace("<{$escaped_input_name}>", $cur_value_in_template, $generated_page_name);
                            // once the substitution is done, replace underlines back
                            // with spaces
                            $generated_page_name = str_replace('_', ' ', $generated_page_name);
                        }
                        // disable this field if either the whole form is disabled, or
                        // it's a restricted field and user doesn't have sysop privileges
                        $is_disabled = $form_is_disabled || $is_restricted;
                        // Create an SFFormField instance based on all the parameters
                        // in the form definition, and any information from the template
                        // definition (contained in the $all_fields parameter).
                        $form_field = SFFormField::createFromDefinition($field_name, $input_name, $is_mandatory, $is_hidden, $is_uploadable, $possible_values, $is_disabled, $is_list, $input_type, $field_args, $all_fields, $strict_parsing);
                        // If a property was set in the form definition, overwrite whatever
                        // is set in the template field - this is somewhat of a hack, since
                        // parameters set in the form definition are meant to go into the
                        // SFFormField object, not the SFTemplateField object it contains;
                        // it seemed like too much work, though, to create an
                        // SFFormField::setSemanticProperty() function just for this call
                        if ($semantic_property != null) {
                            $form_field->template_field->setSemanticProperty($semantic_property);
                        }
                        $semantic_property = $form_field->template_field->getSemanticProperty();
                        if (!is_null($semantic_property)) {
                            global $sfgFieldProperties;
                            $sfgFieldProperties[$fullFieldName] = $semantic_property;
                        }
                        // call hooks - unfortunately this has to be split into two
                        // separate calls, because of the different variable names in
                        // each case
                        if ($form_submitted) {
                            wfRunHooks('sfCreateFormField', array(&$form_field, &$cur_value_in_template, true));
                        } else {
                            wfRunHooks('sfCreateFormField', array(&$form_field, &$cur_value, false));
                        }
                        // if this is not part of a 'multiple' template, increment the
                        // global tab index (used for correct tabbing)
                        if (!array_key_exists('part_of_multiple', $field_args)) {
                            $sfgTabIndex++;
                        }
                        // increment the global field number regardless
                        $sfgFieldNum++;
                        // If the field is a date field, and its default value was set
                        // to 'now', and it has no current value, set $cur_value to be
                        // the current date.
                        if ($default_value == 'now' && ($cur_value === '' || $cur_value == 'now')) {
                            if ($input_type == 'date' || $input_type == 'datetime' || $input_type == 'year' || $input_type === '' && $form_field->getTemplateField()->getPropertyType() == '_dat') {
                                // Get current time, for the time zone specified in the wiki.
                                global $wgLocaltimezone;
                                if (isset($wgLocaltimezone)) {
                                    $serverTimezone = date_default_timezone_get();
                                    date_default_timezone_set($wgLocaltimezone);
                                }
                                $cur_time = time();
                                $year = date("Y", $cur_time);
                                $month = date("n", $cur_time);
                                $day = date("j", $cur_time);
                                global $wgAmericanDates, $sfg24HourTime;
                                if ($wgAmericanDates == true) {
                                    $month_names = SFFormUtils::getMonthNames();
                                    $month_name = $month_names[$month - 1];
                                    $cur_value_in_template = "{$month_name} {$day}, {$year}";
                                } else {
                                    $cur_value_in_template = "{$year}/{$month}/{$day}";
                                }
                                if (isset($wgLocaltimezone)) {
                                    date_default_timezone_set($serverTimezone);
                                }
                                if ($input_type == 'datetime') {
                                    if ($sfg24HourTime) {
                                        $hour = str_pad(intval(substr(date("G", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                    } else {
                                        $hour = str_pad(intval(substr(date("g", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                    }
                                    $minute = str_pad(intval(substr(date("i", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                    $second = str_pad(intval(substr(date("s", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                    if ($sfg24HourTime) {
                                        $cur_value_in_template .= " {$hour}:{$minute}:{$second}";
                                    } else {
                                        $ampm = date("A", $cur_time);
                                        $cur_value_in_template .= " {$hour}:{$minute}:{$second} {$ampm}";
                                    }
                                }
                                if (array_key_exists('include timezone', $field_args)) {
                                    $timezone = date("T", $cur_time);
                                    $cur_value_in_template .= " {$timezone}";
                                }
                            }
                        }
                        // If the field is a text field, and its default value was set
                        // to 'current user', and it has no current value, set $cur_value
                        // to be the current user.
                        if ($default_value == 'current user' && ($cur_value === '' || $cur_value == 'current user')) {
                            $cur_value_in_template = $wgUser->getName();
                            $cur_value = $cur_value_in_template;
                        }
                        // Generate a hidden field with a placeholder value that will be replaced
                        // by the multiple-instances template output at form submission.
                        //// <input type="hidden" value="@replace_Town___mayors@" name="Town[town_mayors]" />
                        if ($holds_template) {
                            $cur_value = self::makePlaceholderInWikiText(self::placeholderFormat($template_name, $field_name));
                        }
                        $new_text = $this->formFieldHTML($form_field, $cur_value);
                        // Add a field just after the hidden field, within the HTML, to locate
                        // where the multiple-templates HTML, stored in $multipleTemplateString,
                        // should be inserted.
                        if ($holds_template) {
                            $new_text .= self::makePlaceholderInFormHTML(self::placeholderFormat($template_name, $field_name));
                        }
                        // If this field is disabled, add a hidden field holding
                        // the value of this field, because disabled inputs for some
                        // reason don't submit their value.
                        if ($form_field->isDisabled()) {
                            if ($field_name == 'free text' || $field_name == '<freetext>') {
                                $new_text .= Html::hidden('sf_free_text', '!free_text!');
                            } else {
                                $new_text .= Html::hidden($input_name, $cur_value);
                            }
                        }
                        if ($new_text) {
                            // Include the field name only for non-numeric field names.
                            if (is_numeric($field_name)) {
                                $template_text .= "|{$cur_value_in_template}";
                            } else {
                                // If the value is null, don't include it at all.
                                if ($cur_value_in_template !== '') {
                                    $template_text .= "\n|{$field_name}={$cur_value_in_template}";
                                }
                            }
                            $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        } else {
                            $start_position = $brackets_end_loc;
                        }
                    }
                    // =====================================================
                    // standard input processing
                    // =====================================================
                } elseif ($tag_title == 'standard input') {
                    // handle all the possible values
                    $input_name = $tag_components[1];
                    $input_label = null;
                    $attr = array();
                    // if it's a query, ignore all standard inputs except run query
                    if ($is_query && $input_name != 'run query' || !$is_query && $input_name == 'run query') {
                        $new_text = "";
                        $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                        continue;
                    }
                    // set a flag so that the standard 'form bottom' won't get displayed
                    $this->standardInputsIncluded = true;
                    // cycle through the other components
                    for ($i = 2; $i < count($tag_components); $i++) {
                        $component = $tag_components[$i];
                        $sub_components = array_map('trim', explode('=', $component));
                        if (count($sub_components) == 1) {
                            if ($sub_components[0] == 'edittools') {
                                $free_text_components[] = 'edittools';
                            }
                        } elseif (count($sub_components) == 2) {
                            switch ($sub_components[0]) {
                                case 'label':
                                    $input_label = $sub_components[1];
                                    break;
                                case 'class':
                                case 'style':
                                    $attr[$sub_components[0]] = $sub_components[1];
                                    break;
                            }
                            // free text input needs more handling than the rest
                            if ($input_name == 'free text' || $input_name == '<freetext>') {
                                if ($sub_components[0] == 'preload') {
                                    $free_text_preload_page = $sub_components[1];
                                }
                            }
                        }
                    }
                    if ($input_name == 'summary') {
                        $new_text = SFFormUtils::summaryInputHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'minor edit') {
                        $new_text = SFFormUtils::minorEditInputHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'watch') {
                        $new_text = SFFormUtils::watchInputHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'save') {
                        $new_text = SFFormUtils::saveButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'save and continue') {
                        $new_text = SFFormUtils::saveAndContinueButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'preview') {
                        $new_text = SFFormUtils::showPreviewButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'changes') {
                        $new_text = SFFormUtils::showChangesButtonHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'cancel') {
                        $new_text = SFFormUtils::cancelLinkHTML($form_is_disabled, $input_label, $attr);
                    } elseif ($input_name == 'run query') {
                        $new_text = SFFormUtils::runQueryButtonHTML($form_is_disabled, $input_label, $attr);
                    }
                    $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // page info processing
                    // =====================================================
                } elseif ($tag_title == 'info') {
                    // TODO: Generate an error message if this is included more than once
                    foreach (array_slice($tag_components, 1) as $component) {
                        $sub_components = array_map('trim', explode('=', $component, 2));
                        // Tag names are case-insensitive
                        $tag = strtolower($sub_components[0]);
                        if ($tag == 'create title' || $tag == 'add title') {
                            // Handle this only if
                            // we're adding a page.
                            if (!$is_query && !$this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'edit title') {
                            // Handle this only if
                            // we're editing a page.
                            if (!$is_query && $this->mPageTitle->exists()) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'query title') {
                            // Handle this only if
                            // we're in 'RunQuery'.
                            if ($is_query) {
                                $form_page_title = $sub_components[1];
                            }
                        } elseif ($tag == 'partial form') {
                            $form_is_partial = true;
                            // replacement pages may have minimal matches...
                            $source_page_matches_this_form = true;
                        } elseif ($tag == 'includeonly free text' || $tag == 'onlyinclude free text') {
                            $onlyinclude_free_text = true;
                        } elseif ($tag == 'query form at top') {
                            // TODO - this should be made a field of
                            // some non-static class that actually
                            // prints the form, instead of requiring
                            // a global variable.
                            global $sfgRunQueryFormAtTop;
                            $sfgRunQueryFormAtTop = true;
                        }
                    }
                    $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                    // =====================================================
                    // default outer level processing
                    // =====================================================
                } else {
                    // Tag is not one of the three allowed values -
                    // ignore the tag.
                    $start_position = $brackets_end_loc;
                }
                // end if
            }
            // end while
            if (!$all_instances_printed) {
                if ($template_text !== '') {
                    // For mostly aesthetic purposes, if the template call ends with
                    // a bunch of pipes (i.e., it's an indexed template with unused
                    // parameters at the end), remove the pipes.
                    $template_text = preg_replace('/\\|*$/', '', $template_text);
                    // add another newline before the final bracket, if this template
                    // call is already more than one line
                    if (strpos($template_text, "\n")) {
                        $template_text .= "\n";
                    }
                    // If we're editing an existing page, and there were fields in
                    // the template call not handled by this form, preserve those.
                    if (!$allow_multiple) {
                        $template_text .= SFFormUtils::addUnhandledFields($template_name);
                    }
                    $template_text .= "}}";
                    // The base $template_text will contain strings like "@replace_xxx@"
                    // in the hidden fields when the form is submitted.
                    // On the following loops, the text for the multiple-instance templates
                    // is progressively reinserted in the main data, always keeping a
                    // trailing @replace_xxx@ for a given field
                    // The trailing @replace_xxx@ is then deleted at the end.
                    // Note: this cleanup step could also be done with a regexp, instead of
                    // keeping a track array (e.g., /@replace_(.*)@/)
                    $reptmp = self::makePlaceholderInWikiText($curPlaceholder);
                    if ($curPlaceholder != null && $data_text && strpos($data_text, $reptmp, 0) !== false) {
                        $data_text = preg_replace('/' . $reptmp . '/', $template_text . $reptmp, $data_text);
                    } else {
                        $data_text .= $template_text . "\n";
                    }
                    // If there is a placeholder in the
                    // text, we know that we are
                    // doing a replace.
                    if ($existing_page_content && strpos($existing_page_content, '{{{insertionpoint}}}', 0) !== false) {
                        $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}(\\r?\\n?)/', preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "\n{{{insertionpoint}}}", $existing_page_content);
                        // otherwise, if it's a partial form, we have to add the new
                        // text somewhere
                    } elseif ($form_is_partial && $wgRequest->getCheck('partial')) {
                        $existing_page_content = preg_replace('/\\}\\}/m', '}�', preg_replace('/\\{\\{/m', '�{', $template_text)) . "\n{{{insertionpoint}}}\n" . $existing_page_content;
                    }
                }
            }
            if ($allow_multiple) {
                if ($curPlaceholder == null) {
                    // The normal process.
                    $form_text .= $this->multipleTemplateInstanceHTML($form_is_disabled, $all_instances_printed, $section, $instance_num, $add_button_text);
                } else {
                    // if ( $curPlaceholder != null ){
                    // The template text won't be appended at the end of the template like for usual multiple template forms.
                    // The HTML text will then be stored in the $multipleTemplateString variable,
                    // and then added in the right @insertHTML_".$placeHolderField."@"; position
                    // Optimization: actually, instead of separating the processes, the usual multiple
                    // template forms could also be handled this way if a fitting placeholder tag was added.
                    $multipleTemplateString .= $this->multipleTemplateInstanceHTML($form_is_disabled, $all_instances_printed, $section, $instance_num, $add_button_text);
                    // We replace the $multipleTemplateString HTML into the
                    // current placeholder tag, but also add another
                    // placeholder tag, to keep track of it.
                    $multipleTemplateString .= self::makePlaceholderInFormHTML($curPlaceholder);
                    if (isset($template_label)) {
                        $multipleTemplateString .= "</fieldset>\n";
                        unset($template_label);
                    }
                    $form_text = preg_replace('/' . self::makePlaceholderInFormHTML($curPlaceholder) . '/', $multipleTemplateString, $form_text);
                }
                if (!$all_instances_printed) {
                    // This will cause the section to be
                    // re-parsed on the next go.
                    $section_num--;
                }
            } else {
                // if ( $allow_multiple ) {
                $form_text .= $section;
            }
            $curPlaceholder = null;
            //		var_dump($wgParser->getOutput()->getModules());
        }
        // end for
        // Cleanup - everything has been browsed.
        // Remove all the remaining placeholder
        // tags in the HTML and wiki-text.
        foreach ($placeholderFields as $stringToReplace) {
            // remove the @<replacename>@ tags from the data that is submitted
            $data_text = preg_replace('/' . self::makePlaceholderInWikiText($stringToReplace) . '/', '', $data_text);
            // remove the @<insertHTML>@ tags from the generated HTML form
            $form_text = preg_replace('/' . self::makePlaceholderInFormHTML($stringToReplace) . '/', '', $form_text);
        }
        // if it wasn't included in the form definition, add the
        // 'free text' input as a hidden field at the bottom
        if (!$free_text_was_included) {
            $form_text .= Html::hidden('sf_free_text', '!free_text!');
        }
        // Get free text, and add to page data, as well as retroactively
        // inserting it into the form.
        // If $form_is_partial is true then either:
        // (a) we're processing a replacement (param 'partial' == 1)
        // (b) we're sending out something to be replaced (param 'partial' is missing)
        if ($form_is_partial) {
            if (!$wgRequest->getCheck('partial')) {
                $free_text = $original_page_content;
                $form_text .= Html::hidden('partial', 1);
            } else {
                $free_text = null;
                $existing_page_content = preg_replace(array('/�\\{/m', '/\\}�/m'), array('{{', '}}'), $existing_page_content);
                $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}/', '', $existing_page_content);
            }
        } elseif ($source_is_page) {
            // if the page is the source, free_text will just be whatever in the
            // page hasn't already been inserted into the form
            $free_text = trim($existing_page_content);
            // or get it from a form submission
        } elseif ($wgRequest->getCheck('sf_free_text')) {
            $free_text = $wgRequest->getVal('sf_free_text');
            if (!$free_text_was_included) {
                $data_text .= "!free_text!";
            }
            // or get it from the form definition
        } elseif ($free_text_preload_page != null) {
            $free_text = SFFormUtils::getPreloadedText($free_text_preload_page);
        } else {
            $free_text = null;
        }
        if ($onlyinclude_free_text) {
            // modify free text and data text to insert <onlyinclude> tags
            $free_text = str_replace("<onlyinclude>", '', $free_text);
            $free_text = str_replace("</onlyinclude>", '', $free_text);
            $free_text = trim($free_text);
            $data_text = str_replace('!free_text!', '<onlyinclude>!free_text!</onlyinclude>', $data_text);
        }
        wfRunHooks('sfModifyFreeTextField', array(&$free_text, $existing_page_content));
        // if the FCKeditor extension is installed, use that for the free text input
        global $wgFCKEditorDir;
        if ($wgFCKEditorDir && strpos($existing_page_content, '__NORICHEDITOR__') === false) {
            $showFCKEditor = SFFormUtils::getShowFCKEditor();
            if (!$form_submitted && $showFCKEditor & RTE_VISIBLE) {
                $free_text = SFFormUtils::prepareTextForFCK($free_text);
            }
        } else {
            $showFCKEditor = 0;
        }
        // now that we have it, substitute free text into the form and page
        $escaped_free_text = Sanitizer::safeEncodeAttribute($free_text);
        $form_text = str_replace('!free_text!', $escaped_free_text, $form_text);
        $data_text = str_replace('!free_text!', $free_text, $data_text);
        // Add a warning in, if we're editing an existing page and that
        // page appears to not have been created with this form.
        if (!$is_query && $this->mPageTitle->exists() && $existing_page_content !== '' && !$source_page_matches_this_form) {
            $form_text = "\t" . '<div class="warningbox">' . wfMsg('sf_formedit_formwarning', $this->mPageTitle->getFullURL()) . "</div>\n<br clear=\"both\" />\n" . $form_text;
        }
        // add form bottom, if no custom "standard inputs" have been defined
        if (!$this->standardInputsIncluded) {
            if ($is_query) {
                $form_text .= SFFormUtils::queryFormBottom($form_is_disabled);
            } else {
                $form_text .= SFFormUtils::formBottom($form_is_disabled);
            }
        }
        if (!$is_query) {
            $form_text .= Html::hidden('wpStarttime', wfTimestampNow());
            $article = new Article($this->mPageTitle, 0);
            $form_text .= Html::hidden('wpEdittime', $article->getTimestamp());
        }
        $form_text .= "\t</form>\n";
        // Add general Javascript code.
        wfRunHooks('sfAddJavascriptToForm', array(&$javascript_text));
        // @TODO The FCKeditor Javascript should be handled within
        // the FCKeditor extension itself, using the hook.
        $javascript_text = "";
        if ($free_text_was_included && $showFCKEditor > 0) {
            $javascript_text .= SFFormUtils::mainFCKJavascript($showFCKEditor, $field_args);
            if ($showFCKEditor & (RTE_TOGGLE_LINK | RTE_POPUP)) {
                $javascript_text .= SFFormUTils::FCKToggleJavascript();
            }
            if ($showFCKEditor & RTE_POPUP) {
                $javascript_text .= SFFormUTils::FCKPopupJavascript();
            }
        }
        // Send the autocomplete values to the browser, along with the
        // mappings of which values should apply to which fields.
        // If doing a replace, the data text is actually the modified original page
        if ($wgRequest->getCheck('partial')) {
            $data_text = $existing_page_content;
        }
        if (!$is_embedded) {
            $form_page_title = $wgParser->recursiveTagParse(str_replace("{{!}}", "|", $form_page_title));
        } else {
            $form_page_title = null;
        }
        // If the form has already been submitted, i.e. this is just
        // the redirect page, get rid of all the Javascript, to avoid
        // JS errors.
        if ($form_submitted) {
            $javascript_text = '';
        }
        $parserOutput = $wgParser->getOutput();
        $wgOut->addParserOutputNoText($parserOutput);
        //		$wgParser = $oldParser;
        wfProfileOut(__METHOD__);
        return array($form_text, $javascript_text, $data_text, $form_page_title, $generated_page_name);
    }
Ejemplo n.º 9
0
	function printPage( $form_name, $embedded = false ) {
		global $wgOut, $wgRequest, $sfgFormPrinter, $wgParser, $sfgRunQueryFormAtTop;

		// Get contents of form-definition page.
		$form_title = Title::makeTitleSafe( SF_NS_FORM, $form_name );

		if ( !$form_title || !$form_title->exists() ) {
			if ( $form_name === '' ) {
				$text = Html::element( 'p', array( 'class' => 'error' ), wfMsg( 'sf_runquery_badurl' ) ) . "\n";
			} else {
				$text = Html::rawElement( 'p', array( 'class' => 'error' ),
					wfMsgExt( 'sf_formstart_badform', 'parseinline', SFUtils::linkText( SF_NS_FORM, $form_name ) ) ) . "\n";
			}
			$wgOut->addHTML( $text );
			return;
		}

		// Initialize variables.
		$form_article = new Article( $form_title, 0 );
		$form_definition = $form_article->getContent();
		$submit_url = $form_title->getLocalURL( 'action=submit' );
		if ( $embedded ) {
			$run_query = false;
			$content = null;
			$raw = false;
		} else {
			$run_query = $wgRequest->getCheck( 'wpRunQuery' );
			$content = $wgRequest->getVal( 'wpTextbox1' );
			$raw = $wgRequest->getBool( 'raw', false );
		}
		$form_submitted = ( $run_query );
		if ( $raw ) {
			$wgOut->setArticleBodyOnly( true );
		}
		// If user already made some action, ignore the edited
		// page and just get data from the query string.
		if ( !$embedded && $wgRequest->getVal( 'query' ) == 'true' ) {
			$edit_content = null;
			$is_text_source = false;
		} elseif ( $content != null ) {
			$edit_content = $content;
			$is_text_source = true;
		} else {
			$edit_content = null;
			$is_text_source = true;
		}
		list ( $form_text, $javascript_text, $data_text, $form_page_title ) =
			$sfgFormPrinter->formHTML( $form_definition, $form_submitted, $is_text_source, $form_article->getID(), $edit_content, null, null, true, $embedded );
		$text = "";

		if ( $form_submitted ) {
			global $wgUser, $wgTitle, $wgOut;
			$wgParser->mOptions = ParserOptions::newFromUser( $wgUser );
			// @TODO - fix RunQuery's parsing so that this check
			// isn't needed.
			if ( $wgParser->getOutput() == null ) {
				$headItems = array();
			} else {
				$headItems = $wgParser->getOutput()->getHeadItems();
			}
			foreach ( $headItems as $key => $item ) {
				$wgOut->addHeadItem( $key, "\t\t" . $item . "\n" );
			}
		}

		// Get the text of the results.
		$resultsText = '';
		if ( $form_submitted ) {
			$resultsText = $wgParser->parse( $data_text, $wgTitle, $wgParser->mOptions )->getText();
		}

		// Get the full text of the form.
		$fullFormText = '';
		$additionalQueryHeader = '';
		$dividerText = '';
		if ( !$raw ) {
			// Create the "additional query" header, and the
			// divider text - one of these (depending on whether
			// the query form is at the top or bottom) is displayed
			// if the form has already been submitted.
			if ( $form_submitted ) {
				$additionalQueryHeader = "\n" . Html::element( 'h2', null, wfMsg( 'sf_runquery_additionalquery' ) ) . "\n";
				$dividerText = "\n<hr style=\"margin: 15px 0;\" />\n";
			}
			$action = htmlspecialchars( $this->getTitle( $form_name )->getLocalURL() );
			$fullFormText .= <<<END
	<form id="sfForm" name="createbox" action="$action" method="post" class="createbox">

END;
			$fullFormText .= SFFormUtils::hiddenFieldHTML( 'query', 'true' );
			$fullFormText .= $form_text;
		}

		// Either display the query form at the top, and the results at
		// the bottom, or the other way around, depending on the
		// settings - the display is slightly different in each case.
		if ( $sfgRunQueryFormAtTop ) {
			$text .= $fullFormText;
			$text .= $dividerText;
			$text .= $resultsText;
		} else {
			$text .= $resultsText;
			$text .= $additionalQueryHeader;
			$text .= $fullFormText;
		}

		if ( $embedded ) {
			$text = "<div class='runQueryEmbedded'>$text</div>";
		}

		// Armor against doBlockLevels()
		$text = preg_replace( '/^ +/m', '', $text );
		// Now write everything to the screen.
		$wgOut->addHTML( $text );
		SFUtils::addJavascriptAndCSS( $embedded ? $wgParser : null );
		$script = "\t\t" . '<script type="text/javascript">' . "\n" . $javascript_text . '</script>' . "\n";
		if ( $embedded ) {
			$wgParser->getOutput()->addHeadItem( $script );
		} else {
			$wgOut->addScript( $script );
			$po = $wgParser->getOutput();
			if ( $po ) {
				$wgOut->addParserOutputNoText( $po );
			}
		}

		// Finally, set the page title - for MW 1.16, this has to be
		// called after addParserOutputNoText() for it to take effect.
		if ( !$embedded ) {
			if ( $form_page_title != null ) {
				$wgOut->setPageTitle( $form_page_title );
			} else {
				$s = wfMsg( 'sf_runquery_title', $form_title->getText() );
				$wgOut->setPageTitle( $s );
			}
		}
	}
 function getCurrentValue($template_instance_query_values, $form_submitted, $source_is_page)
 {
     // Get the value from the request, if
     // it's there, and if it's not an array.
     $cur_value = null;
     $field_name = $this->template_field->getFieldName();
     $delimiter = $this->mFieldArgs['delimiter'];
     $escaped_field_name = str_replace("'", "\\'", $field_name);
     if (isset($template_instance_query_values) && $template_instance_query_values != null && is_array($template_instance_query_values)) {
         // If the field name contains an apostrophe, the array
         // sometimes has the apostrophe escaped, and sometimes
         // not. For now, just check for both versions.
         // @TODO - figure this out.
         $field_query_val = null;
         if (array_key_exists($escaped_field_name, $template_instance_query_values)) {
             $field_query_val = $template_instance_query_values[$escaped_field_name];
         } elseif (array_key_exists($field_name, $template_instance_query_values)) {
             $field_query_val = $template_instance_query_values[$field_name];
         }
         if ($form_submitted && $field_query_val != '') {
             $map_field = false;
             if (array_key_exists('map_field', $template_instance_query_values) && array_key_exists($field_name, $template_instance_query_values['map_field'])) {
                 $map_field = true;
             }
             if (is_array($field_query_val)) {
                 $cur_values = array();
                 if ($map_field && !is_null($this->mPossibleValues)) {
                     $cur_values = array();
                     foreach ($field_query_val as $key => $val) {
                         $val = trim($val);
                         if ($key === 'is_list') {
                             $cur_values[$key] = $val;
                         } else {
                             $cur_values[] = SFUtils::labelToValue($val, $this->mPossibleValues);
                         }
                     }
                 } else {
                     foreach ($field_query_val as $key => $val) {
                         $cur_values[$key] = $val;
                     }
                 }
                 return SFFormPrinter::getStringFromPassedInArray($cur_values, $delimiter);
             } else {
                 $field_query_val = trim($field_query_val);
                 if ($map_field && !is_null($this->mPossibleValues)) {
                     // this should be replaced with an input type neutral way of
                     // figuring out if this scalar input type is a list
                     if ($this->mInputType == "tokens") {
                         $is_list = true;
                     }
                     if ($is_list) {
                         $cur_values = array_map('trim', explode($delimiter, $field_query_val));
                         foreach ($cur_values as $key => $value) {
                             $cur_values[$key] = SFUtils::labelToValue($value, $this->mPossibleValues);
                         }
                         return implode($delimiter, $cur_values);
                     }
                     return SFUtils::labelToValue($field_query_val, $this->mPossibleValues);
                 }
                 return $field_query_val;
             }
         }
         if (!$form_submitted && $field_query_val != '') {
             if (is_array($field_query_val)) {
                 return SFFormPrinter::getStringFromPassedInArray($field_query_val, $delimiter);
             }
             return $field_query_val;
         }
     }
     if (!$source_is_page && empty($cur_value) && !$form_submitted) {
         if (!is_null($this->mDefaultValue)) {
             // Set to the default value specified in the form, if it's there.
             return $this->mDefaultValue;
         } elseif ($this->mPreloadPage) {
             return SFFormUtils::getPreloadedText($this->mPreloadPage);
         }
     }
     return $cur_value;
     // null
 }
 private static function getAllValuesForCargoField($cargoTable, $cargoField, $fieldIsArray, $substring, $baseCargoTable = null, $baseCargoField = null, $baseValue = null)
 {
     global $sfgMaxAutocompleteValues, $sfgCacheAutocompleteValues, $sfgAutocompleteCacheTimeout;
     global $sfgAutocompleteOnAllChars;
     $values = array();
     $tablesStr = $cargoTable;
     $fieldsStr = $cargoField;
     $joinOnStr = '';
     $whereStr = '';
     // Use cache if allowed
     if ($sfgCacheAutocompleteValues) {
         $cache = SFFormUtils::getFormCache();
         // Remove trailing whitespace to avoid unnecessary database selects
         $cacheKeyString = $cargoTable . '|' . $cargoField . '|' . rtrim($substring);
         if (!is_null($baseCargoTable)) {
             $cacheKeyString .= '|' . $baseCargoTable . '|' . $baseCargoField . '|' . $baseValue;
         }
         $cacheKey = wfMemcKey('sf-autocomplete', md5($cacheKeyString));
         $values = $cache->get($cacheKey);
         if (!empty($values)) {
             // Return with results immediately
             return $values;
         }
     }
     if (!is_null($baseCargoTable) && !is_null($baseCargoField)) {
         if ($baseCargoTable != $cargoTable) {
             $tablesStr .= ", {$baseCargoTable}";
             $joinOnStr = "{$cargoTable}._pageName = {$baseCargoTable}._pageName";
         }
         $whereStr = "{$baseCargoTable}.{$baseCargoField} = \"{$baseValue}\"";
     }
     if (!is_null($substring)) {
         if ($whereStr != '') {
             $whereStr .= " AND ";
         }
         $operator = $fieldIsArray ? "HOLDS LIKE" : "LIKE";
         if ($sfgAutocompleteOnAllChars) {
             $whereStr .= "({$cargoField} {$operator} \"%{$substring}%\")";
         } else {
             $whereStr .= "({$cargoField} {$operator} \"{$substring}%\" OR {$cargoField} {$operator} \"% {$substring}%\")";
         }
     }
     $sqlQuery = CargoSQLQuery::newFromValues($tablesStr, $fieldsStr, $whereStr, $joinOnStr, $cargoField, $havingStr = null, $cargoField, $sfgMaxAutocompleteValues);
     $cargoFieldAlias = str_replace('_', ' ', $cargoField);
     $queryResults = $sqlQuery->run();
     foreach ($queryResults as $row) {
         // @TODO - this check should not be neceaary.
         if (($value = $row[$cargoFieldAlias]) != '') {
             $values[] = $value;
         }
     }
     if ($sfgCacheAutocompleteValues) {
         // Save to cache.
         $cache->set($cacheKey, $values, $sfgAutocompleteCacheTimeout);
     }
     return $values;
 }
Ejemplo n.º 12
0
 public function formSerialize($form_def = '', $source_is_page = false, $existing_page_content = null, $page_title = null)
 {
     //	public function formSerialize($form_def, $source_is_page, $existing_page_content = null, $page_title = null, $page_name_formula = null) {
     global $wgRequest, $wgUser, $wgParser;
     global $sfgTabIndex;
     // used to represent the current tab index in the form
     global $sfgFieldNum;
     // used for setting various HTML IDs
     global $sfgJSValidationCalls;
     // array of Javascript calls to determine if page can be saved
     # define a var for all fields
     $__fields = array();
     // initialize some variables
     $sfgTabIndex = 1;
     $sfgFieldNum = 1;
     $source_page_matches_this_form = false;
     $form_page_title = NULL;
     // $form_is_partial is true if:
     // (a) 'partial' == 1 in the arguments
     // (b) 'partial form' is found in the form definition
     // in the latter case, it may remain false until close to the end of
     // the parsing, so we have to assume that it will become a possibility
     $form_is_partial = false;
     $new_text = "";
     // if we have existing content and we're not in an active replacement
     // situation, preserve the original content. We do this because we want
     // to pass the original content on IF this is a partial form
     // TODO: A better approach here would be to pass the revision id of the
     // existing page content through the replace value, which would
     // minimize the html traffic and would allow us to do a concurrent
     // update check.  For now, we pass it through the hidden text field...
     if (!$wgRequest->getCheck('partial')) {
         $original_page_content = $existing_page_content;
     } else {
         $original_page_content = null;
         if ($wgRequest->getCheck('free_text')) {
             $existing_page_content = $wgRequest->getVal('free_text');
             $form_is_partial = true;
         }
     }
     // disable all form elements if user doesn't have edit permission -
     // two different checks are needed, because editing permissions can be
     // set in different ways
     // HACK - sometimes we don't know the page name in advance, but we still
     // need to set a title here for testing permissions
     if ($page_title == '') {
         $this->mPageTitle = Title::newFromText("Semantic Forms permissions test");
     } else {
         $this->mPageTitle = Title::newFromText($page_title);
     }
     if ($wgUser->isAllowed('edit') && $this->mPageTitle->userCanEdit()) {
         $form_is_disabled = false;
         $form_text = "";
         // show "Your IP address will be recorded" warning if user is
         // anonymous - wikitext for bolding has to be replaced with HTML
         if ($wgUser->isAnon()) {
             $anon_edit_warning = preg_replace("/'''(.*)'''/", "<strong>\$1</strong>", wfMsg('anoneditwarning'));
             $form_text .= "<p>{$anon_edit_warning}</p>\n";
         }
     } else {
         $form_is_disabled = true;
         // display a message to the user explaining why they can't edit the
         // page - borrowed heavily from EditPage.php
         if ($wgUser->isAnon()) {
             $skin = $wgUser->getSkin();
             $loginTitle = SpecialPage::getTitleFor('Userlogin');
             $loginLink = $skin->makeKnownLinkObj($loginTitle, wfMsgHtml('loginreqlink'));
             $form_text = wfMsgWikiHtml('whitelistedittext', $loginLink);
         } else {
             $form_text = wfMsg('protectedpagetext');
         }
     }
     $javascript_text = "";
     $sfgJSValidationCalls = array();
     $fields_javascript_text = "";
     // Remove <noinclude> sections and <includeonly> tags from form definition
     $form_def = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $form_def);
     $form_def = strtr($form_def, array('<includeonly>' => '', '</includeonly>' => ''));
     // parse wiki-text
     // add '<nowiki>' tags around every triple-bracketed form definition
     // element, so that the wiki parser won't touch it - the parser will
     // remove the '<nowiki>' tags, leaving us with what we need
     global $sfgDisableWikiTextParsing;
     if (!$sfgDisableWikiTextParsing) {
         $form_def = "__NOEDITSECTION__" . strtr($form_def, array('{{{' => '<nowiki>{{{', '}}}' => '}}}</nowiki>'));
         $wgParser->mOptions = new ParserOptions();
         $wgParser->mOptions->initialiseFromUser($wgUser);
         $form_def = $wgParser->parse($form_def, $this->mPageTitle, $wgParser->mOptions)->getText();
     }
     // turn form definition file into an array of sections, one for each
     // template definition (plus the first section)
     $form_def_sections = array();
     $start_position = 0;
     $section_start = 0;
     $free_text_was_included = false;
     $free_text_preload_page = null;
     $all_values_for_template = array();
     // unencode and HTML-encoded representations of curly brackets and
     // pipes - this is a hack to allow for forms to include templates
     // that themselves contain form elements - the escaping is needed
     // to make sure that those elements don't get parsed too early
     $form_def = str_replace(array('&#123;', '&#124;', '&#125;'), array('{', '|', '}'), $form_def);
     // and another hack - replace the 'free text' standard input with
     // a field declaration to get it to be handled as a field
     $form_def = str_replace('standard input|free text', 'field|<freetext>', $form_def);
     while ($brackets_loc = strpos($form_def, "{{{", $start_position)) {
         $brackets_end_loc = strpos($form_def, "}}}", $brackets_loc);
         $bracketed_string = substr($form_def, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
         $tag_components = explode('|', $bracketed_string);
         $tag_title = trim($tag_components[0]);
         if ($tag_title == 'for template' || $tag_title == 'end template') {
             // create a section for everything up to here
             $section = substr($form_def, $section_start, $brackets_loc - $section_start);
             $form_def_sections[] = $section;
             $section_start = $brackets_loc;
         }
         $start_position = $brackets_loc + 1;
     }
     // end while
     $form_def_sections[] = trim(substr($form_def, $section_start));
     // cycle through form definition file (and possibly an existing article
     // as well), finding template and field declarations and replacing them
     // with form elements, either blank or pre-populated, as appropriate
     $all_fields = array();
     $data_text = "";
     $template_name = "";
     $allow_multiple = false;
     $instance_num = 0;
     $all_instances_printed = false;
     $strict_parsing = false;
     // initialize list of choosers (dropdowns with available templates)
     $choosers = array();
     for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
         $tif = new SFTemplateInForm();
         $start_position = 0;
         $template_text = "";
         // the append is there to ensure that the original array doesn't get
         // modified; is it necessary?
         $section = " " . $form_def_sections[$section_num];
         while ($brackets_loc = strpos($section, '{{{', $start_position)) {
             $brackets_end_loc = strpos($section, "}}}", $brackets_loc);
             $bracketed_string = substr($section, $brackets_loc + 3, $brackets_end_loc - ($brackets_loc + 3));
             $tag_components = explode('|', $bracketed_string);
             $tag_title = trim($tag_components[0]);
             // =====================================================
             // for template processing
             // =====================================================
             if ($tag_title == 'for template') {
                 $old_template_name = $template_name;
                 $template_name = trim($tag_components[1]);
                 $tif->template_name = $template_name;
                 $query_template_name = str_replace(' ', '_', $template_name);
                 // also replace periods with underlines, since that's what
                 // POST does to strings anyway
                 $query_template_name = str_replace('.', '_', $query_template_name);
                 $chooser_name = false;
                 $chooser_caption = false;
                 // cycle through the other components
                 for ($i = 2; $i < count($tag_components); $i++) {
                     $component = $tag_components[$i];
                     if ($component == 'multiple') {
                         $allow_multiple = true;
                     }
                     if ($component == 'strict') {
                         $strict_parsing = true;
                     }
                     $sub_components = explode('=', $component);
                     if (count($sub_components) == 2) {
                         if ($sub_components[0] == 'label') {
                             $template_label = $sub_components[1];
                         } elseif ($sub_components[0] == 'chooser') {
                             $allow_multiple = true;
                             $chooser_name = $sub_components[1];
                         } elseif ($sub_components[0] == 'chooser caption') {
                             $chooser_caption = $sub_components[1];
                         }
                     }
                 }
                 // if this is the first instance, add the label in the form
                 if ($old_template_name != $template_name && isset($template_label)) {
                     // add a placeholder to the form text so the fieldset can be
                     // hidden if chooser support demands it
                     if ($chooser_name !== false) {
                         $form_text .= "<fieldset [[placeholder]] haschooser=true>\n";
                     } else {
                         $form_text .= "<fieldset>\n";
                     }
                     $form_text .= "<legend>{$template_label}</legend>\n";
                 }
                 $template_text .= "{{" . $tif->template_name;
                 # reads all the fields of the template definition page
                 $all_fields = $tif->getAllFields();
                 // remove template tag
                 $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                 $template_instance_query_values = $wgRequest->getArray($query_template_name);
                 // if we are editing a page, and this template can be found more than
                 // once in that page, and multiple values are allowed, repeat this
                 // section
                 $existing_template_text = null;
                 // replace underlines with spaces in template name, to allow for
                 // searching on either
                 $search_template_str = str_replace('_', ' ', $tif->template_name);
                 if ($source_is_page || $form_is_partial) {
                     if ($allow_multiple) {
                         // find instances of this template in the page -
                         // if there's at least one, re-parse this section of the
                         // definition form for the subsequent template instances in
                         // this page; if there's none, don't include fields at all.
                         // there has to be a more efficient way to handle multiple
                         // instances of templates, one that doesn't involve re-parsing
                         // the same tags, but I don't know what it is.
                         if (stripos(str_replace('_', ' ', $existing_page_content), '{{' . $search_template_str) !== false) {
                             $instance_num++;
                         } else {
                             $all_instances_printed = true;
                         }
                     }
                     // get the first instance of this template on the page being edited,
                     // even if there are more
                     if (($start_char = stripos(str_replace('_', ' ', $existing_page_content), '{{' . $search_template_str)) !== false) {
                         $fields_start_char = $start_char + 2 + strlen($search_template_str);
                         // skip ahead to the first real character
                         while (in_array($existing_page_content[$fields_start_char], array(' ', '\\n', '|'))) {
                             $fields_start_char++;
                         }
                         $template_contents = array('0' => '');
                         // cycle through template call, splitting it up by pipes ('|'),
                         // except when that pipe is part of a piped link
                         $field = "";
                         $uncompleted_square_brackets = 0;
                         $uncompleted_curly_brackets = 2;
                         $template_ended = false;
                         for ($i = $fields_start_char; !$template_ended && $i < strlen($existing_page_content); $i++) {
                             $c = $existing_page_content[$i];
                             if ($c == '[') {
                                 $uncompleted_square_brackets++;
                             } elseif ($c == ']' && $uncompleted_square_brackets > 0) {
                                 $uncompleted_square_brackets--;
                             } elseif ($c == '{') {
                                 $uncompleted_curly_brackets++;
                             } elseif ($c == '}' && $uncompleted_curly_brackets > 0) {
                                 $uncompleted_curly_brackets--;
                             }
                             // handle an end to a field and/or template declaration
                             $template_ended = $uncompleted_curly_brackets == 0 && $uncompleted_square_brackets == 0;
                             $field_ended = $c == '|' && $uncompleted_square_brackets == 0;
                             if ($template_ended || $field_ended) {
                                 // if this was the last character in the template, remove
                                 // the closing curly brackets
                                 if ($template_ended) {
                                     $field = substr($field, 0, -1);
                                 }
                                 // either there's an equals sign near the beginning or not -
                                 // handling is similar in either way; if there's no equals
                                 // sign, the index of this field becomes the key
                                 $sub_fields = explode('=', $field, 2);
                                 if (count($sub_fields) > 1) {
                                     $template_contents[trim($sub_fields[0])] = trim($sub_fields[1]);
                                 } else {
                                     $template_contents[] = trim($sub_fields[0]);
                                 }
                                 $field = '';
                             } else {
                                 $field .= $c;
                             }
                         }
                         $existing_template_text = substr($existing_page_content, $start_char, $i - $start_char);
                         // now remove this template from the text being edited
                         // if this is a partial form, establish a new insertion point
                         if ($existing_page_content && $form_is_partial && $wgRequest->getCheck('partial')) {
                             // if something already exists, set the new insertion point
                             // to its position; otherwise just let it lie
                             if (strpos($existing_page_content, $existing_template_text) !== false) {
                                 $existing_page_content = str_replace('{{{insertionpoint}}}', '', $existing_page_content);
                                 $existing_page_content = str_replace($existing_template_text, '{{{insertionpoint}}}', $existing_page_content);
                             }
                         } else {
                             $existing_page_content = str_replace($existing_template_text, '', $existing_page_content);
                         }
                         // if this is not a multiple-instance template, and we've found
                         // a match in the source page, there's a good chance that this
                         // page was created with this form - note that, so we don't
                         // send the user a warning
                         // (multiple-instance templates have a greater chance of
                         // getting repeated from one form to the next)
                         if (!$allow_multiple) {
                             $source_page_matches_this_form = true;
                         }
                     }
                 }
                 // if the input is from the form (meaning the user has hit one
                 // of the bottom row of buttons), and we're dealing with a
                 // multiple template, get the values for this instance of this
                 // template, then delete them from the array, so we can get the
                 // next group next time - the next() command for arrays doesn't
                 // seem to work here
                 if (!$source_is_page && $allow_multiple && $wgRequest) {
                     $all_instances_printed = true;
                     if ($old_template_name != $template_name) {
                         $all_values_for_template = $wgRequest->getArray($query_template_name);
                     }
                     if ($all_values_for_template) {
                         $cur_key = key($all_values_for_template);
                         // skip the input coming in from the "starter" div
                         if ($cur_key == 'num') {
                             unset($all_values_for_template[$cur_key]);
                             $cur_key = key($all_values_for_template);
                         }
                         if ($template_instance_query_values = current($all_values_for_template)) {
                             $all_instances_printed = false;
                             unset($all_values_for_template[$cur_key]);
                         }
                     }
                 }
                 //  save the template name
                 $field = array();
                 $field['tmpl_name'] = $tif->template_name;
                 // =====================================================
                 // end template processing
                 // =====================================================
             } elseif ($tag_title == 'end template') {
                 // remove this tag, reset some variables, and close off form HTML tag
                 $section = substr_replace($section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                 $template_name = null;
                 if (isset($template_label)) {
                     $form_text .= "</fieldset>\n";
                     unset($template_label);
                 }
                 $allow_multiple = false;
                 $all_instances_printed = false;
                 $instance_num = 0;
                 // if the hiding placeholder is still around, this fieldset should
                 // be hidden because it is empty and choosers are being used. So,
                 // hide it.
                 $form_text = str_replace("[[placeholder]]", "style='display:none'", $form_text);
                 $__fields["template" . count($__fields)] = $field;
                 // =====================================================
                 // field processing
                 // =====================================================
             } elseif ($tag_title == 'field') {
                 $field_name = trim($tag_components[1]);
                 // cycle through the other components
                 $is_mandatory = false;
                 $is_hidden = false;
                 $is_restricted = false;
                 $is_uploadable = false;
                 $is_list = false;
                 $input_type = null;
                 $field_args = array();
                 $default_value = "";
                 $possible_values = null;
                 $preload_page = null;
                 for ($i = 2; $i < count($tag_components); $i++) {
                     $component = trim($tag_components[$i]);
                     if ($component == 'mandatory') {
                         $is_mandatory = true;
                     } elseif ($component == 'hidden') {
                         $is_hidden = true;
                     } elseif ($component == 'restricted') {
                         $is_restricted = true;
                     } elseif ($component == 'uploadable') {
                         $field_args['is_uploadable'] = true;
                     } elseif ($component == 'list') {
                         $is_list = true;
                     } elseif ($component == 'autocomplete') {
                         $field_args['autocomplete'] = true;
                     } elseif ($component == 'no autocomplete') {
                         $field_args['no autocomplete'] = true;
                     } elseif ($component == 'remote autocompletion') {
                         $field_args['remote autocompletion'] = true;
                     } else {
                         $sub_components = explode('=', $component);
                         if (count($sub_components) == 2) {
                             if ($sub_components[0] == 'input type') {
                                 $input_type = $sub_components[1];
                             } elseif ($sub_components[0] == 'default') {
                                 $default_value = $sub_components[1];
                             } elseif ($sub_components[0] == 'preload') {
                                 // free text field has special handling
                                 if ($field_name == 'free text' || ($field_name = '<freetext>')) {
                                     $free_text_preload_page = $sub_components[1];
                                 } else {
                                     // this variable is not used
                                     $preload_page = $sub_components[1];
                                 }
                             } elseif ($sub_components[0] == 'values') {
                                 $possible_values = explode(',', $sub_components[1]);
                             } elseif ($sub_components[0] == 'values from category') {
                                 $possible_values = SFUtils::getAllPagesForCategory($sub_components[1], 10);
                             } elseif ($sub_components[0] == 'values from concept') {
                                 $possible_values = SFUtils::getAllPagesForConcept($sub_components[1]);
                             } else {
                                 $field_args[$sub_components[0]] = $sub_components[1];
                             }
                             // for backwards compatibility
                             if ($sub_components[0] == 'autocomplete on' && $sub_components[1] == null) {
                                 $field_args['no autocomplete'] = true;
                             }
                         }
                     }
                 }
                 $field_args['part_of_multiple'] = $allow_multiple;
                 // get the value from the request, if it's there, and if it's not
                 // an array
                 $escaped_field_name = str_replace("'", "\\'", $field_name);
                 if (isset($template_instance_query_values) && $template_instance_query_values != null && array_key_exists($escaped_field_name, $template_instance_query_values)) {
                     $field_query_val = $template_instance_query_values[$escaped_field_name];
                     if ($field_query_val && !is_array($field_query_val)) {
                         $cur_value = $field_query_val;
                     }
                 } else {
                     $cur_value = '';
                 }
                 if ($cur_value && !is_array($cur_value)) {
                     # no escaping needed
                     // $cur_value = str_replace('"', '&quot;', $cur_value);
                 }
                 if ($cur_value == null) {
                     // set to default value specified in the form, if it's there
                     $cur_value = $default_value;
                 }
                 // if the user is starting to edit a page, and that page contains
                 // the current template being processed, get the current template
                 // field's value in the existing page
                 if ($source_is_page && !empty($existing_template_text)) {
                     if (isset($template_contents[$field_name])) {
                         $cur_value = $template_contents[$field_name];
                     } else {
                         $cur_value = '';
                     }
                     if ($cur_value) {
                         # no escaping needed
                         // $cur_value = str_replace('"', '&quot;', $cur_value);
                     }
                 }
                 // handle the free text field - if it was declared as
                 // "field|free text" (a deprecated usage), it has to be outside
                 // of a template
                 if ($template_name == '' && $field_name == 'free text' || $field_name == '<freetext>') {
                     // add placeholders for the free text in both the form and
                     // the page, using <free_text> tags - once all the free text
                     // is known (at the end), it will get substituted in
                     if ($is_hidden) {
                         $new_text = SFFormUtils::hiddenFieldHTML('free_text', '<free_text>');
                     } else {
                         if (!array_key_exists('rows', $field_args)) {
                             $field_args['rows'] = 5;
                         }
                         if (!array_key_exists('cols', $field_args)) {
                             $field_args['cols'] = 80;
                         }
                         $sfgTabIndex++;
                         $sfgFieldNum++;
                         list($new_text, $new_javascript_text) = SFFormInputs::textAreaHTML('<free_text>', 'free_text', false, $form_is_disabled || $is_restricted, $field_args);
                         $fields_javascript_text .= $new_javascript_text;
                     }
                     $free_text_was_included = true;
                     // add a similar placeholder to the data text
                     $data_text .= "<free_text>\n";
                 }
                 if ($template_name == '') {
                     $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                 } else {
                     if (is_array($cur_value)) {
                         // first, check if it's a list
                         if (array_key_exists('is_list', $cur_value) && $cur_value['is_list'] == true) {
                             $cur_value_in_template = "";
                             if (array_key_exists('delimiter', $field_args)) {
                                 $delimiter = $field_args['delimiter'];
                             } else {
                                 $delimiter = ",";
                             }
                             foreach ($cur_value as $key => $val) {
                                 if ($key !== "is_list") {
                                     if ($cur_value_in_template != "") {
                                         $cur_value_in_template .= $delimiter . " ";
                                     }
                                     $cur_value_in_template .= $val;
                                 }
                             }
                         } else {
                             // otherwise:
                             // if it has 1 or 2 elements, assume it's a checkbox; if it has
                             // 3 elements, assume it's a date
                             // - this handling will have to get more complex if other
                             // possibilities get added
                             if (count($cur_value) == 1) {
                                 // manually load SMW's message values here, in case they
                                 // didn't get loaded before
                                 wfLoadExtensionMessages('SemanticMediaWiki');
                                 $words_for_false = explode(',', wfMsgForContent('smw_false_words'));
                                 // for each language, there's a series of words that are
                                 // equal to false - get the word in the series that matches
                                 // "no"; generally, that's the third word
                                 $index_of_no = 2;
                                 if (count($words_for_false) > $index_of_no) {
                                     $no = ucwords($words_for_false[$index_of_no]);
                                 } elseif (count($words_for_false) == 0) {
                                     $no = "0";
                                     // some safe value if no words are found
                                 } else {
                                     $no = ucwords($words_for_false[0]);
                                 }
                                 $cur_value_in_template = $no;
                             } elseif (count($cur_value) == 2) {
                                 wfLoadExtensionMessages('SemanticMediaWiki');
                                 $words_for_true = explode(',', wfMsgForContent('smw_true_words'));
                                 // get the value in the 'true' series that tends to be "yes",
                                 // and go with that one - generally, that's the third word
                                 $index_of_yes = 2;
                                 if (count($words_for_true) > $index_of_yes) {
                                     $yes = ucwords($words_for_true[$index_of_yes]);
                                 } elseif (count($words_for_true) == 0) {
                                     $yes = "1";
                                     // some safe value if no words are found
                                 } else {
                                     $yes = ucwords($words_for_true[0]);
                                 }
                                 $cur_value_in_template = $yes;
                                 // if it's 3 or greater, assume it's a date or datetime
                             } elseif (count($cur_value) >= 3) {
                                 $month = $cur_value['month'];
                                 $day = $cur_value['day'];
                                 if ($day != '') {
                                     global $wgAmericanDates;
                                     if ($wgAmericanDates == false) {
                                         // pad out day to always be two digits
                                         $day = str_pad($day, 2, "0", STR_PAD_LEFT);
                                     }
                                 }
                                 $year = $cur_value['year'];
                                 if (isset($cur_value['hour'])) {
                                     $hour = $cur_value['hour'];
                                 }
                                 if (isset($cur_value['minute'])) {
                                     $minute = $cur_value['minute'];
                                 }
                                 if (isset($cur_value['second'])) {
                                     $second = $cur_value['second'];
                                 }
                                 if (isset($cur_value['ampm24h'])) {
                                     $ampm24h = $cur_value['ampm24h'];
                                 }
                                 if (isset($cur_value['timezone'])) {
                                     $timezone = $cur_value['timezone'];
                                 }
                                 if ($month != '' && $day != '' && $year != '') {
                                     // special handling for American dates - otherwise, just
                                     // the standard year/month/day (where month is a number)
                                     global $wgAmericanDates;
                                     if ($wgAmericanDates == true) {
                                         $cur_value_in_template = "{$month} {$day}, {$year}";
                                     } else {
                                         $cur_value_in_template = "{$year}/{$month}/{$day}";
                                     }
                                     // include whatever time information we have
                                     if (isset($hour)) {
                                         $cur_value_in_template .= " " . str_pad(intval(substr($hour, 0, 2)), 2, '0', STR_PAD_LEFT) . ":" . str_pad(intval(substr($minute, 0, 2)), 2, '0', STR_PAD_LEFT);
                                     }
                                     if (isset($second)) {
                                         $cur_value_in_template .= ":" . str_pad(intval(substr($second, 0, 2)), 2, '0', STR_PAD_LEFT);
                                     }
                                     if (isset($ampm24h)) {
                                         $cur_value_in_template .= " {$ampm24h}";
                                     }
                                     if (isset($timezone)) {
                                         $cur_value_in_template .= " {$timezone}";
                                     }
                                 } else {
                                     $cur_value_in_template = "";
                                 }
                             }
                         }
                     } else {
                         // value is not an array
                         $cur_value_in_template = $cur_value;
                     }
                     if ($query_template_name == null || $query_template_name == '') {
                         $input_name = $field_name;
                     } elseif ($allow_multiple) {
                         // 'num' will get replaced by an actual index, either in PHP
                         // or in Javascript, later on
                         $input_name = $query_template_name . '[num][' . $field_name . ']';
                     } else {
                         $input_name = $query_template_name . '[' . $field_name . ']';
                     }
                     // disable this field if either the whole form is disabled, or
                     // it's a restricted field and user doesn't have sysop privileges
                     $is_disabled = $form_is_disabled || $is_restricted && (!$wgUser || !$wgUser->isAllowed('editrestrictedfields'));
                     // create an SFFormTemplateField instance based on all the
                     // parameters in the form definition, and any information from
                     // the template definition (contained in the $all_fields parameter)
                     # creation of a form field from the definition page
                     $possible_values['_element'] = "value";
                     $form_field = $this->createFromDefinitionForSerialization($field_name, $input_name, $is_mandatory, $is_hidden, $is_uploadable, $possible_values, $is_disabled, $is_list, $input_type, $field_args, $all_fields, $strict_parsing);
                     // if this is not part of a 'multiple' template, incrememt the
                     // global tab index (used for correct tabbing)
                     if (!$field_args['part_of_multiple']) {
                         $sfgTabIndex++;
                     }
                     // increment the global field number regardless
                     $sfgFieldNum++;
                     // if the field is a date field, and its default value was set
                     // to 'now', and it has no current value, set $cur_value to be
                     // the current date
                     if ($default_value == 'now' && ($cur_value == '' || $cur_value == 'now')) {
                         if ($input_type == 'date' || $input_type == 'datetime' || $input_type == 'datetime with timezone' || $input_type == '' && $form_field->template_field->field_type == 'Date') {
                             $cur_time = time();
                             $year = date("Y", $cur_time);
                             $month = date("n", $cur_time);
                             $day = date("j", $cur_time);
                             global $wgAmericanDates, $sfg24HourTime;
                             if ($wgAmericanDates == true) {
                                 $month_names = SFFormUtils::getMonthNames();
                                 $month_name = $month_names[$month - 1];
                                 $cur_value_in_template = "{$month_name} {$day}, {$year}";
                             } else {
                                 $cur_value_in_template = "{$year}/{$month}/{$day}";
                             }
                             if ($input_type == 'datetime' || $input_type == 'datetime with timezone') {
                                 if ($sfg24HourTime) {
                                     $hour = str_pad(intval(substr(date("G", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 } else {
                                     $hour = str_pad(intval(substr(date("g", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 }
                                 $minute = str_pad(intval(substr(date("i", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 $second = str_pad(intval(substr(date("s", $cur_time), 0, 2)), 2, '0', STR_PAD_LEFT);
                                 if ($sfg24HourTime) {
                                     $cur_value_in_template .= " {$hour}:{$minute}:{$second}";
                                 } else {
                                     $ampm = date("A", $cur_time);
                                     $cur_value_in_template .= " {$hour}:{$minute}:{$second} {$ampm}";
                                 }
                             }
                             if ($input_type == 'datetime with timezone') {
                                 $timezone = date("T", $cur_time);
                                 $cur_value_in_template .= " {$timezone}";
                             }
                         }
                     }
                     // if the field is a text field, and its default value was set
                     // to 'current user', and it has no current value, set $cur_value
                     // to be the current user
                     if ($default_value == 'current user' && ($cur_value == '' || $cur_value == 'current user')) {
                         if ($input_type == 'text' || $input_type == '') {
                             $cur_value_in_template = $wgUser->getName();
                             $cur_value = $cur_value_in_template;
                         }
                     }
                     # field + field value
                     $form_field->cur_value = $cur_value;
                     # possible_values hack
                     $__tmpValues = $form_field->template_field->possible_values;
                     $form_field->template_field->possible_values = array();
                     if ($__tmpValues != NULL) {
                         foreach ($__tmpValues as $key => $value) {
                             $form_field->template_field->possible_values["value" . $key] = $value;
                         }
                     }
                     $field["field" . count($field)] = $this->toArrayForSerialize($form_field);
                     $new_text = "dummy";
                     // set only in order to break
                     if ($new_text) {
                         $section = substr_replace($section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc);
                     } else {
                         $start_position = $brackets_end_loc;
                     }
                 }
             } else {
                 // tag is not one of the three allowed values
                 // ignore tag
                 $start_position = $brackets_end_loc;
             }
             // end if
         }
         // end while
     }
     // end for
     // get free text, and add to page data, as well as retroactively
     // inserting it into the form
     // If $form_is_partial is true then either:
     // (a) we're processing a replacement (param 'partial' == 1)
     // (b) we're sending out something to be replaced (param 'partial' is missing)
     if ($form_is_partial) {
         if (!$wgRequest->getCheck('partial')) {
             $free_text = $original_page_content;
             $form_text .= SFFormUtils::hiddenFieldHTML('partial', 1);
         } else {
             $free_text = null;
             $existing_page_content = preg_replace('/²\\{(.*?)\\}²/s', '{{\\1}}', $existing_page_content);
             $existing_page_content = preg_replace('/\\{\\{\\{insertionpoint\\}\\}\\}/', '', $existing_page_content);
             $existing_page_content = Sanitizer::safeEncodeAttribute($existing_page_content);
         }
     } elseif ($source_is_page) {
         // if the page is the source, free_text will just be whatever in the
         // page hasn't already been inserted into the form
         $free_text = trim($existing_page_content);
         // or get it from a form submission
     } elseif ($wgRequest->getCheck('free_text')) {
         $free_text = $wgRequest->getVal('free_text');
         if (!$free_text_was_included) {
             $data_text .= "<free_text>";
         }
         // or get it from the form definition
     } elseif ($free_text_preload_page != null) {
         $free_text = SFFormUtils::getPreloadedText($free_text_preload_page);
     } else {
         $free_text = null;
     }
     # the free text is set here
     // if the FCKeditor extension is installed, use that for the free text input
     global $wgFCKEditorDir;
     if ($wgFCKEditorDir) {
         $showFCKEditor = SFFormUtils::getShowFCKEditor();
         $free_text = htmlspecialchars($free_text);
         if ($showFCKEditor & RTE_VISIBLE) {
             $free_text = SFFormUtils::prepareTextForFCK($free_text);
         }
     } else {
         $showFCKEditor = 0;
         $free_text = Sanitizer::safeEncodeAttribute($free_text);
     }
     // now that we have it, substitute free text into the form and page
     $form_text = str_replace('<free_text>', $free_text, $form_text);
     $data_text = str_replace('<free_text>', $free_text, $data_text);
     # return the fields
     return $__fields;
 }
	public static function getHTML( $cur_value, $input_name, $is_mandatory, $is_disabled, $other_args ) {
		global $sfgTabIndex, $sfgFieldNum, $sfgShowOnSelect;

		$checkbox_class = ( $is_mandatory ) ? 'mandatoryField' : 'createboxInput';
		$span_class = 'checkboxSpan';
		if ( array_key_exists( 'class', $other_args ) ) {
			$span_class .= ' ' . $other_args['class'];
		}
		$input_id = "input_$sfgFieldNum";
		// get list delimiter - default is comma
		if ( array_key_exists( 'delimiter', $other_args ) ) {
			$delimiter = $other_args['delimiter'];
		} else {
			$delimiter = ',';
		}
		$cur_values = SFUtils::getValuesArray( $cur_value, $delimiter );

		if ( ( $possible_values = $other_args['possible_values'] ) == null ) {
			$possible_values = array();
		}
		$text = '';
		foreach ( $possible_values as $key => $possible_value ) {
			$cur_input_name = $input_name . '[' . $key . ']';

			if (
				array_key_exists( 'value_labels', $other_args ) &&
				is_array( $other_args['value_labels'] ) &&
				array_key_exists( $possible_value, $other_args['value_labels'] )
			)
			{
				$label = $other_args['value_labels'][$possible_value];
			} else {
				$label = $possible_value;
			}

			$checkbox_attrs = array(
				'id' => $input_id,
				'tabindex' => $sfgTabIndex,
				'class' => $checkbox_class,
			);
			if ( in_array( $possible_value, $cur_values ) ) {
				$checkbox_attrs['checked'] = 'checked';
			}
			if ( $is_disabled ) {
				$checkbox_attrs['disabled'] = 'disabled';
			}
			$checkbox_input = Html::input( $cur_input_name, $possible_value, 'checkbox', $checkbox_attrs );

			// Make a span around each checkbox, for CSS purposes.
			$text .= "\t" . Html::rawElement( 'span',
				array( 'class' => $span_class ),
				$checkbox_input . ' ' . $label
			) . "\n";
			$sfgTabIndex++;
			$sfgFieldNum++;
		}

		$outerSpanID = "span_$sfgFieldNum";
		$outerSpanClass = 'checkboxesSpan';
		if ( $is_mandatory ) {
			$outerSpanClass .= ' mandatoryFieldSpan';
		}

		if ( array_key_exists( 'show on select', $other_args ) ) {
			$outerSpanClass .= ' sfShowIfChecked';
			foreach ( $other_args['show on select'] as $div_id => $options ) {
				if ( array_key_exists( $outerSpanID, $sfgShowOnSelect ) ) {
					$sfgShowOnSelect[$outerSpanID][] = array( $options, $div_id );
				} else {
					$sfgShowOnSelect[$outerSpanID] = array( array( $options, $div_id ) );
				}
			}
		}

		$text .= SFFormUtils::hiddenFieldHTML( $input_name . '[is_list]', 1 );
		$outerSpanAttrs = array( 'id' => $outerSpanID, 'class' => $outerSpanClass );
		$text = "\t" . Html::rawElement( 'span', $outerSpanAttrs, $text ) . "\n";

		return $text;
	}
	public static function getHTML( $cur_value, $input_name, $is_mandatory, $is_disabled, $other_args ) {
		// escape if CategoryTree extension isn't included
		if ( !function_exists( 'efCategoryTreeParserHook' ) ) {
			return null;
		}

		global $sfgTabIndex, $sfgFieldNum, $wgCapitalLinks;

		$input_id = "input_$sfgFieldNum";
		// get list delimiter - default is comma
		if ( array_key_exists( 'delimiter', $other_args ) ) {
			$delimiter = $other_args['delimiter'];
		} else {
			$delimiter = ',';
		}
		$cur_values = SFUtils::getValuesArray( $cur_value, $delimiter );
		if ( array_key_exists( 'top category', $other_args ) ) {
			$top_category = $other_args['top category'];
		} else {
			// escape - we can't do anything
			return null;
		}
		$hideroot = array_key_exists( 'hideroot', $other_args );
		if ( array_key_exists( 'height', $other_args ) ) {
			$height = $other_args['height'];
		} else {
			$height = '100';
		}
		if ( array_key_exists( 'width', $other_args ) ) {
			$width = $other_args['width'];
		} else {
			$width = '500';
		}

		global $wgCategoryTreeMaxDepth;
		$wgCategoryTreeMaxDepth = 10;
		$tree = efCategoryTreeParserHook(
			$top_category, array(
				'mode' => 'categories',
				'namespaces' => array( NS_CATEGORY ),
				'depth' => 10,
				'hideroot' => $hideroot,
			)
		);
		// Some string that will hopefully never show up in a category,
		// template or field name.
		$dummy_str = 'REPLACE THIS STRING!';
		$tree = preg_replace(
			'/(<a class="CategoryTreeLabel.*>)(.*)(<\/a>)/',
			'<input id="' . $input_id . '" tabindex="' . $sfgTabIndex .
				'" name="' . $input_name . '[' . $dummy_str .
				']" value="$2" type="checkbox"> $1$2$3',
			$tree
		);
		// replace values one at a time, by an incrementing index -
		// inspired by http://bugs.php.net/bug.php?id=11457
		$i = 0;
		while ( ( $a = strpos( $tree, $dummy_str ) ) > 0 ) {
			$tree = substr( $tree, 0, $a ) . $i++ . substr( $tree, $a + strlen( $dummy_str ) );
		}
		// set all checkboxes matching $cur_values to checked
		foreach ( $cur_values as $value ) {
			// Capitalize the first letter, if first letters
			// always get capitalized.
			if ( $wgCapitalLinks ) {
				global $wgContLang;
				$value = $wgContLang->ucfirst( $value );
			}

			$tree = str_replace( "value=\"$value\"", "value=\"$value\" checked=\"checked\"", $tree );
		}
		// if it's disabled, set all to disabled
		if ( $is_disabled ) {
			$tree = str_replace( 'type="checkbox"', 'type="checkbox" disabled', $tree );
		}

		// Get rid of all the 'no subcategories' messages.
		$tree = str_replace(
			'<div class="CategoryTreeChildren" style="display:block"><i class="CategoryTreeNotice">' .
				wfMsg( 'categorytree-no-subcategories' ) . '</i></div>',
			'',
			$tree
		);

		$text = '<div style="overflow: auto; padding: 5px; border: 1px #aaaaaa solid; max-height: ' . $height . 'px; width: ' . $width . 'px;">' . $tree . '</div>';

		$text .= SFFormUtils::hiddenFieldHTML( $input_name . '[is_list]', 1 );
		$spanClass = 'checkboxesSpan';
		if ( $is_mandatory ) {
			$spanClass .= ' mandatoryFieldSpan';
		}
		$text = "\n" . Html::rawElement( 'span', array( 'class' => $spanClass ), $text ) . "\n";

		return $text;
	}
	static function renderFormInput ( &$parser ) {
		global $wgVersion;

		$params = func_get_args();
		array_shift( $params ); // don't need the parser
		// set defaults
		$inFormName = $inValue = $inButtonStr = $inQueryStr = '';
		$inAutocompletionSource = '';
		$inRemoteAutocompletion = false;
		$inSize = 25;
		$classStr = "";
		// assign params - support unlabelled params, for backwards compatibility
		foreach ( $params as $i => $param ) {
			$elements = explode( '=', $param, 2 );
			$param_name = null;
			$value = trim( $param );
			if ( count( $elements ) > 1 ) {
				$param_name = trim( $elements[0] );
				$value = trim( $parser->recursiveTagParse( $elements[1] ) );
			}
			if ( $param_name == 'form' )
				$inFormName = $value;
			elseif ( $param_name == 'size' )
				$inSize = $value;
			elseif ( $param_name == 'default value' )
				$inValue = $value;
			elseif ( $param_name == 'button text' )
				$inButtonStr = $value;
			elseif ( $param_name == 'query string' )
				$inQueryStr = $value;
			elseif ( $param_name == 'autocomplete on category' ) {
				$inAutocompletionSource = $value;
				$autocompletion_type = 'category';
			} elseif ( $param_name == 'autocomplete on namespace' ) {
				$inAutocompletionSource = $value;
				$autocompletion_type = 'namespace';
			} elseif ( $param_name == 'remote autocompletion' ) {
				$inRemoteAutocompletion = true;
			} elseif ( $param_name == null && $value == 'popup' ) {
				self::loadScriptsForPopupForm( $parser );
				$classStr = 'popupforminput';
			}
			elseif ( $i == 0 )
				$inFormName = $param;
			elseif ( $i == 1 )
				$inSize = $param;
			elseif ( $i == 2 )
				$inValue = $param;
			elseif ( $i == 3 )
				$inButtonStr = $param;
			elseif ( $i == 4 )
				$inQueryStr = $param;
		}

		$fs = SFUtils::getSpecialPage( 'FormStart' );

		$fs_url = $fs->getTitle()->getLocalURL();
		$str = <<<END
			<form name="createbox" action="$fs_url" method="get" class="$classStr">
			<p>

END;
		$formInputAttrs = array( 'size' => $inSize );

		// Now apply the necessary settings and Javascript, depending
		// on whether or not there's autocompletion (and whether the
		// autocompletion is local or remote).
		$input_num = 1;
		if ( empty( $inAutocompletionSource ) ) {
			$formInputAttrs['class'] = 'formInput';
		} else {
			self::$num_autocompletion_inputs++;
			$input_num = self::$num_autocompletion_inputs;
			// place the necessary Javascript on the page, and
			// disable the cache (so the Javascript will show up) -
			// if there's more than one autocompleted #forminput
			// on the page, we only need to do this the first time
			if ( $input_num == 1 ) {
				$parser->disableCache();
				SFUtils::addJavascriptAndCSS();
			}

			$inputID = 'input_' . $input_num;
			$formInputAttrs['id'] = $inputID;
			$formInputAttrs['class'] = 'autocompleteInput createboxInput formInput';
			if ( $inRemoteAutocompletion ) {
				$formInputAttrs['autocompletesettings'] = $inAutocompletionSource;
				$formInputAttrs['autocompletedatatype'] = $autocompletion_type;
			} else {
				$autocompletion_values = SFUtils::getAutocompleteValues( $inAutocompletionSource, $autocompletion_type );
				global $sfgAutocompleteValues;
				$sfgAutocompleteValues[$inputID] = $autocompletion_values;
				$formInputAttrs['autocompletesettings'] = $inputID;
			}
		}

		$str .= "\t" . Html::input( 'page_name', $inValue, 'text', $formInputAttrs ) . "\n";

		// if the form start URL looks like "index.php?title=Special:FormStart"
		// (i.e., it's in the default URL style), add in the title as a
		// hidden value
		if ( ( $pos = strpos( $fs_url, "title=" ) ) > - 1 ) {
			$str .= SFFormUtils::hiddenFieldHTML( "title", urldecode( substr( $fs_url, $pos + 6 ) ) );
		}
		if ( $inFormName == '' ) {
			$str .= SFUtils::formDropdownHTML();
		} else {
			$str .= SFFormUtils::hiddenFieldHTML( "form", $inFormName );
		}
		// Recreate the passed-in query string as a set of hidden
		// variables.
		// Change HTML-encoded ampersands to URL-encoded ampersands, so
		// that the string doesn't get split up on the '&'.
		$inQueryStr = str_replace( '&amp;', '%26', $inQueryStr );
		$query_components = explode( '&', $inQueryStr );
		foreach ( $query_components as $component ) {
			// change URL-encoded ampersands back
			$component = str_replace( '%26', '&', $component );
			$subcomponents = explode( '=', $component, 2 );
			$key = ( isset( $subcomponents[0] ) ) ? $subcomponents[0] : '';
			$val = ( isset( $subcomponents[1] ) ) ? $subcomponents[1] : '';
			if ( ! empty( $key ) ) {
				$str .= '\t\t\t' .  Html::hidden( $key, $val ) . "\n";
			}
		}
		$button_str = ( $inButtonStr != '' ) ? $inButtonStr : wfMsg( 'sf_formstart_createoredit' );
		$str .= <<<END
			<input type="submit" value="$button_str" /></p>
			</form>

END;
		if ( ! empty( $inAutocompletionSource ) ) {
			$str .= "\t\t\t" .
				Html::element( 'div',
					array(
						'class' => 'page_name_auto_complete',
						'id' => "div_$input_num",
					),
					// it has to be <div></div>, not
					// <div />, to work properly - stick
					// in a space as the content
					' '
				) . "\n";
		}

		// hack to remove newline from beginning of output, thanks to
		// http://jimbojw.com/wiki/index.php?title=Raw_HTML_Output_from_a_MediaWiki_Parser_Function
		return $parser->insertStripItem( $str, $parser->mStripState );
	}
Ejemplo n.º 16
0
    static function formBottom($is_disabled)
    {
        global $wgUser;
        $summary_text = SFFormUtils::summaryInputHTML($is_disabled);
        $text = <<<END
\t<br /><br />
\t<div class='editOptions'>
{$summary_text}\t<br />

END;
        if ($wgUser->isAllowed('minoredit')) {
            $text .= SFFormUtils::minorEditInputHTML($is_disabled);
        }
        if ($wgUser->isLoggedIn()) {
            $text .= SFFormUtils::watchInputHTML($is_disabled);
        }
        $text .= <<<END
\t<br />
\t<div class='editButtons'>

END;
        $text .= SFFormUtils::saveButtonHTML($is_disabled);
        $text .= SFFormUtils::showPreviewButtonHTML($is_disabled);
        $text .= SFFormUtils::showChangesButtonHTML($is_disabled);
        $text .= SFFormUtils::cancelLinkHTML($is_disabled);
        $text .= <<<END
\t</div><!-- editButtons -->
\t</div><!-- editOptions -->

END;
        return $text;
    }
	function execute( $query ) {
		global $wgOut, $wgRequest, $wgUser, $sfgScriptPath;

		$this->setHeaders();

		// Cycle through the query values, setting the appropriate
		// local variables.
		$category_name = $wgRequest->getVal( 'category_name' );
		$default_form = $wgRequest->getVal( 'default_form' );
		$parent_category = $wgRequest->getVal( 'parent_category' );

		$category_name_error_str = null;
		$save_page = $wgRequest->getCheck( 'wpSave' );
		$preview_page = $wgRequest->getCheck( 'wpPreview' );
		if ( $save_page || $preview_page ) {
			// Validate category name
			if ( $category_name === '' ) {
				$category_name_error_str = wfMsg( 'sf_blank_error' );
			} else {
				// Redirect to wiki interface
				$wgOut->setArticleBodyOnly( true );
				$title = Title::makeTitleSafe( NS_CATEGORY, $category_name );
				$full_text = SFCreateCategory::createCategoryText( $default_form, $category_name, $parent_category );
				$text = SFUtils::printRedirectForm( $title, $full_text, "", $save_page, $preview_page, false, false, false, null, null );
				$wgOut->addHTML( $text );
				return;
			}
		}

		$all_forms = SFUtils::getAllForms();

		// Set 'title' as hidden field, in case there's no URL niceness
		global $wgContLang;
		$mw_namespace_labels = $wgContLang->getNamespaces();
		$special_namespace = $mw_namespace_labels[NS_SPECIAL];
		$text = <<<END
	<form action="" method="get">

END;
		$text .= SFFormUtils::hiddenFieldHTML( 'title', "$special_namespace:CreateCategory" );
		$firstRow = wfMsg( 'sf_createcategory_name' ) . ' ' .
			Html::input( 'category_name', null, 'text',
				array( 'size' => 25 ) ) . "\n";
		if ( !is_null( $category_name_error_str ) ) {
			$firstRow .= Html::element( 'span',
				array( 'style' => 'color: red;' ),
				$category_name_error_str ) . "\n";
		}
		$firstRow .= "\t" . wfMsg( 'sf_createcategory_defaultform' ) . "\n";
		$formSelector = "\t" . Html::element( 'option', null, null ). "\n";
		foreach ( $all_forms as $form ) {
			$formSelector .= "\t" . Html::element( 'option', null, $form ) . "\n";
		}

		$firstRow .= Html::rawElement( 'select',
			array( 'id' => 'form_dropdown', 'name' => 'default_form' ),
			$formSelector );
		$text .= Html::rawElement( 'p', null, $firstRow );
		$subcategory_label = wfMsg( 'sf_createcategory_makesubcategory' );
		$text .= <<<END
	<p>$subcategory_label
	<select id="category_dropdown" name="parent_category">
	<option></option>

END;
		$categories = SFUtils::getCategoriesForPage();
		foreach ( $categories as $category ) {
			$category = str_replace( '_', ' ', $category );
			$text .= "\t" . Html::element( 'option', null, $category ) . "\n";
		}
		$text .= "\t</select>\n";
		$editButtonsText = "\t" . Html::input( 'wpSave', wfMsg( 'savearticle' ), 'submit', array( 'id' => 'wpSave' ) ) . "\n";
		$editButtonsText .= "\t" . Html::input( 'wpPreview', wfMsg( 'preview' ), 'submit', array( 'id' => 'wpPreview' ) ) . "\n";
		$text .= "\t" . Html::rawElement( 'div', array( 'class' => 'editButtons' ), $editButtonsText ) . "\n";
		$text .= <<<END
	<br /><hr /<br />

END;

		$sk = $wgUser->getSkin();
		$create_form_link = SFUtils::linkForSpecialPage( $sk, 'CreateForm' );
		$text .= "\t" . Html::rawElement( 'p', null, $create_form_link . '.' ) . "\n";
		$text .= "\t</form>\n";

		$wgOut->addExtensionStyle( $sfgScriptPath . "/skins/SemanticForms.css" );
		$wgOut->addHTML( $text );
	}
	function printCreateTemplateForm() {
		global $wgOut, $wgRequest, $wgUser, $sfgScriptPath;

		self::addJavascript();

		$text = '';
		$save_page = $wgRequest->getCheck( 'wpSave' );
		$preview_page = $wgRequest->getCheck( 'wpPreview' );
		if ( $save_page || $preview_page ) {
			$fields = array();
			// Cycle through the query values, setting the
			// appropriate local variables.
			foreach ( $wgRequest->getValues() as $var => $val ) {
				$var_elements = explode( "_", $var );
				// we only care about query variables of the form "a_b"
				if ( count( $var_elements ) != 2 )
					continue;
				list ( $field_field, $id ) = $var_elements;
				if ( $field_field == 'name' && $id != 'starter' ) {
					$field = SFTemplateField::create( $val, $wgRequest->getVal( 'label_' . $id ), $wgRequest->getVal( 'semantic_property_' . $id ), $wgRequest->getCheck( 'is_list_' . $id ) );
					$fields[] = $field;
				}
			}

			// Assemble the template text, and submit it as a wiki
			// page.
			$wgOut->setArticleBodyOnly( true );
			$template_name = $wgRequest->getVal( 'template_name' );
			$title = Title::makeTitleSafe( NS_TEMPLATE, $template_name );
			$category = $wgRequest->getVal( 'category' );
			$aggregating_property = $wgRequest->getVal( 'semantic_property_aggregation' );
			$aggregation_label = $wgRequest->getVal( 'aggregation_label' );
			$template_format = $wgRequest->getVal( 'template_format' );
			$full_text = SFTemplateField::createTemplateText( $template_name, $fields, null, $category, $aggregating_property, $aggregation_label, $template_format );
			$text = SFUtils::printRedirectForm( $title, $full_text, "", $save_page, $preview_page, false, false, false, null, null );
			$wgOut->addHTML( $text );
			return;
		}

		$text .= '	<form id="createTemplateForm" action="" method="post">' . "\n";
		// Set 'title' field, in case there's no URL niceness
		$text .= SFFormUtils::hiddenFieldHTML( 'title', $this->getTitle()->getPrefixedText() );
		$text .= "\t<p id=\"template_name_p\">" . wfMsg( 'sf_createtemplate_namelabel' ) . ' <input size="25" id="template_name" name="template_name" /></p>' . "\n";
		$text .= "\t<p>" . wfMsg( 'sf_createtemplate_categorylabel' ) . ' <input size="25" name="category" /></p>' . "\n";
		$text .= "\t<fieldset>\n";
		$text .= "\t" . Html::element( 'legend', null, wfMsg( 'sf_createtemplate_templatefields' ) ) . "\n";
		$text .= "\t" . Html::element( 'p', null, wfMsg( 'sf_createtemplate_fieldsdesc' ) ) . "\n";

		$all_properties = self::getAllPropertyNames();
		$text .= '<div id="fieldsList">' . "\n";
		$text .= self::printFieldEntryBox( "1", $all_properties );
		$text .= self::printFieldEntryBox( "starter", $all_properties, false );
		$text .= "</div>\n";

		$add_field_button = Html::input(
			null,
			wfMsg( 'sf_createtemplate_addfield' ),
			'button',
			array( 'onclick' => "createTemplateAddField()" )
		);
		$text .= Html::rawElement( 'p', null, $add_field_button ) . "\n";
		$text .= "\t</fieldset>\n";
		$text .= "\t<fieldset>\n";
		$text .= "\t" . Html::element( 'legend', null, wfMsg( 'sf_createtemplate_aggregation' ) ) . "\n";
		$text .= "\t" . Html::element( 'p', null, wfMsg( 'sf_createtemplate_aggregationdesc' ) ) . "\n";
		$text .= "\t<p>" . wfMsg( 'sf_createtemplate_semanticproperty' ) . ' ' .
			self::printPropertiesDropdown( $all_properties, "aggregation" ) . "</p>\n";
		$text .= "\t<p>" . wfMsg( 'sf_createtemplate_aggregationlabel' ) . ' ' .
			Html::input( 'aggregation_label', null, 'text',
				array( 'size' => '25' ) ) .
			"</p>\n";
		$text .= "\t</fieldset>\n";
		$text .= "\t<p>" . wfMsg( 'sf_createtemplate_outputformat' ) . "\n";
		$text .= "\t" . Html::input( 'template_format', 'standard', 'radio', array(
			'checked' => true,
		), null ) . ' ' . wfMsg( 'sf_createtemplate_standardformat' ) . "\n";
		$text .= "\t" . Html::input( 'template_format', 'infobox', 'radio', null ) .
			' ' . wfMsg( 'sf_createtemplate_infoboxformat' ) . "</p>\n";
		$save_button_text = wfMsg( 'savearticle' );
		$preview_button_text = wfMsg( 'preview' );
		$text .= <<<END
	<div class="editButtons">
	<input type="submit" id="wpSave" name="wpSave" value="$save_button_text" />
	<input type="submit" id="wpPreview" name="wpPreview" value="$preview_button_text" />
	</div>
	</form>

END;
		$sk = $wgUser->getSkin();
		$create_property_link = SFUtils::linkForSpecialPage( $sk, 'CreateProperty' );
		$text .= "\t<br /><hr /><br />\n";
		$text .= "\t" . Html::rawElement( 'p', null, $create_property_link . '.' ) . "\n";

		$wgOut->addExtensionStyle( $sfgScriptPath . "/skins/SemanticForms.css" );
		$wgOut->addHTML( $text );
	}
Ejemplo n.º 19
0
 private function printForm(&$parameters, WebRequest &$request)
 {
     global $wgOut, $sfgFormPrinter;
     // Prepare parameters for SFFormPrinter::formHTML
     // there is no ONE target page
     $targetTitle = null;
     // formDefinition
     $formName = $request->getText('form');
     // if query string did not contain these variables, try the URL
     if ($formName === '') {
         $queryparts = explode('/', $parameters);
         $formName = isset($queryparts[0]) ? $queryparts[0] : null;
         // if the form name wasn't in the URL either, throw an error
         if (is_null($formName) || $formName === '') {
             throw new SPSException(SPSUtils::buildMessage('spserror-noformname'));
         }
     }
     $formTitle = Title::makeTitleSafe(SF_NS_FORM, $formName);
     if (!$formTitle->exists()) {
         throw new SPSException(SPSUtils::buildMessage('spserror-formunknown', $formName));
     }
     $formArticle = new Article($formTitle);
     $formDefinition = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $formArticle->getContent());
     // formSubmitted
     $formSubmitted = false;
     // pageContents
     $pageContents = null;
     // get 'preload' query value, if it exists
     if ($request->getCheck('preload')) {
         $pageContents = SFFormUtils::getPreloadedText($request->getVal('preload'));
     } else {
         // let other extensions preload the page, if they want
         wfRunHooks('sfEditFormPreloadText', array(&$pageContents, $targetTitle, $formTitle));
     }
     // pageIsSource
     $pageIsSource = $pageContents != null;
     // pageNameFormula
     // parse the form to see if it has a 'page name' value set
     $matches;
     if (preg_match('/{{{info.*page name\\s*=\\s*(.*)}}}/m', $formDefinition, $matches)) {
         $pageNameElements = SFUtils::getFormTagComponents($matches[1]);
         $pageNameFormula = $pageNameElements[0];
     } else {
         return 'sf_formedit_badurl';
     }
     // get the iterator parameters
     $iteratorData = $this->buildIteratorParameters($request);
     // Call SFFormPrinter::formHTML
     list($formText, $javascriptText, $dataText, $formPageTitle, $generatedPageName) = $sfgFormPrinter->formHTML($formDefinition, $formSubmitted, $pageIsSource, $formArticle->getID(), $pageContents, '', $pageNameFormula);
     // Set Special page main header;
     // override the default title for this page if a title was specified in the form
     if ($formPageTitle != null) {
         $wgOut->setPageTitle($formPageTitle);
     } else {
         $wgOut->setPageTitle(SPSUtils::buildMessage('sf_formedit_createtitlenotarget', $formTitle->getText()));
     }
     $preFormHtml = '';
     wfRunHooks('sfHTMLBeforeForm', array(&$targetTitle, &$preFormHtml));
     $text = '<form name="createbox" id="sfForm" action="" method="post" class="createbox">' . $preFormHtml . "\n" . SFFormUtils::hiddenFieldHTML('iteratordata', $iteratorData) . $formText;
     SFUtils::addJavascriptAndCSS();
     if (!empty($javascriptText)) {
         $wgOut->addScript('		<script type="text/javascript">' . "\n{$javascriptText}\n" . '</script>' . "\n");
     }
     $wgOut->addHTML($text);
     return null;
 }
	public static function getHTML( $cur_value, $input_name, $is_mandatory, $is_disabled, $other_args ) {
		global $sfgTabIndex, $sfgFieldNum, $sfgShowOnSelect;

		$className = ( $is_mandatory ) ? 'mandatoryField' : 'createboxInput';
		if ( array_key_exists( 'class', $other_args ) ) {
			$className .= ' ' . $other_args['class'];
		}
		$input_id = "input_$sfgFieldNum";
		// get list delimiter - default is comma
		if ( array_key_exists( 'delimiter', $other_args ) ) {
			$delimiter = $other_args['delimiter'];
		} else {
			$delimiter = ',';
		}
		$cur_values = SFUtils::getValuesArray( $cur_value, $delimiter );
		$className .= ' sfShowIfSelected';

		if ( ( $possible_values = $other_args['possible_values'] ) == null ) {
			$possible_values = array();
		}
		$optionsText = '';
		foreach ( $possible_values as $possible_value ) {
			if (
				array_key_exists( 'value_labels', $other_args ) &&
				is_array( $other_args['value_labels'] ) &&
				array_key_exists( $possible_value, $other_args['value_labels'] )
			)
			{
				$optionLabel = $other_args['value_labels'][$possible_value];
			} else {
				$optionLabel = $possible_value;
			}
			$optionAttrs = array( 'value' => $possible_value );
			if ( in_array( $possible_value, $cur_values ) ) {
				$optionAttrs['selected'] = 'selected';
			}
			$optionsText .= Html::element( 'option', $optionAttrs, $optionLabel );
		}
		$selectAttrs = array(
			'id' => $input_id,
			'tabindex' => $sfgTabIndex,
			'name' => $input_name . '[]',
			'class' => $className,
			'multiple' => 'multiple'
		);
		if ( array_key_exists( 'size', $other_args ) ) {
			$selectAttrs['size'] = $other_args['size'];
		}
		if ( $is_disabled ) {
			$selectAttrs['disabled'] = 'disabled';
		}
		$text = Html::rawElement( 'select', $selectAttrs, $optionsText );
		$text .= SFFormUtils::hiddenFieldHTML( $input_name . '[is_list]', 1 );
		if ( $is_mandatory ) {
			$text = Html::rawElement( 'span', array( 'class' => 'inputSpan mandatoryFieldSpan' ), $text );
		}

		if ( array_key_exists( 'show on select', $other_args ) ) {
			foreach ( $other_args['show on select'] as $div_id => $options ) {
				if ( array_key_exists( $input_id, $sfgShowOnSelect ) ) {
					$sfgShowOnSelect[$input_id][] = array( $options, $div_id );
				} else {
					$sfgShowOnSelect[$input_id] = array( array( $options, $div_id ) );
				}
			}
		}

		return $text;
	}
Ejemplo n.º 21
0
	function doSpecialCreateForm() {
		global $wgOut, $wgRequest, $wgUser, $sfgScriptPath;
		$db = wfGetDB( DB_SLAVE );

		// Create Javascript to populate fields to let the user input
		// parameters for the field, based on the input type selected
		// in the dropdown.
		$skin = $wgUser->getSkin();
		$url = $skin->makeSpecialUrl( 'CreateForm', "showinputtypeoptions=' + this.val() + '&formfield=' + this.attr('formfieldid') + '" );
		foreach ( $wgRequest->getValues() as $param => $value ) {
			$url .= '&params[' . Xml::escapeJsString( $param ) . ']=' . Xml::escapeJsString( $value );
		}

		// Only add 'collapsible' ability if the ResourceLoader exists,
		// i.e. for MW 1.17 - adding backwards compatibility doesn't
		// seem worth it for this relatively minor piece of
		// functionality.
		if ( method_exists( $wgOut, 'addModules' ) ) {
			$wgOut->addModules( 'ext.semanticforms.collapsible' );
		}

		$wgOut->addScript("<script>
jQuery.fn.displayInputParams = function() {
	inputParamsDiv = this.closest('.formField').find('.otherInputParams');
	jQuery.ajax({
		url: '$url',
		context: document.body,
		success: function(data){
			inputParamsDiv.html(data);
		}
	});
};
jQuery(document).ready(function() {
	jQuery('.inputTypeSelector').change( function() {
		jQuery(this).displayInputParams();
	});
});
</script>");


		// Get the names of all templates on this site.
		$all_templates = array();
		$res = $db->select(
			'page',
			'page_title',
			array( 'page_namespace' => NS_TEMPLATE, 'page_is_redirect' => 0 ),
			array( 'ORDER BY' => 'page_title' )
		);

		if ( $db->numRows( $res ) > 0 ) {
			while ( $row = $db->fetchRow( $res ) ) {
				$template_name = str_replace( '_', ' ', $row[0] );
				$all_templates[] = $template_name;
			}
		}

		$form_templates = array();
		$i = 1;
		$deleted_template_loc = null;

		# handle inputs
		$form_name = $wgRequest->getVal( 'form_name' );
		foreach ( $wgRequest->getValues() as $var => $val ) {
			# ignore variables that are not of the right form
			if ( strpos( $var, "_" ) != false ) {
				# get the template declarations and work from there
				list ( $action, $id ) = explode( "_", $var, 2 );
				if ( $action == "template" ) {
					// If the button was pressed to remove
					// this template, just don't add it to
					// the array.
					if ( $wgRequest->getVal( "del_$id" ) != null ) {
						$deleted_template_loc = $id;
					} else {
						$form_template = SFTemplateInForm::create( $val,
							$wgRequest->getVal( "label_$id" ),
							$wgRequest->getVal( "allow_multiple_$id" ) );
						$form_templates[] = $form_template;
					}
				}
			}
		}
		if ( $wgRequest->getVal( 'add_field' ) != null ) {
			$form_template = SFTemplateInForm::create( $wgRequest->getVal( 'new_template' ), "", false );
			$new_template_loc = $wgRequest->getVal( 'before_template' );
			if ( $new_template_loc === null ) { $new_template_loc = 0; }
			// @HACK - array_splice() doesn't work for objects, so
			// we have to first insert a stub element into the
			// array, then replace that with the actual object.
			array_splice( $form_templates, $new_template_loc, 0, "stub" );
			$form_templates[$new_template_loc] = $form_template;
		} else {
			$new_template_loc = null;
		}

		// Now cycle through the templates and fields, modifying each
		// one per the query variables.
		foreach ( $form_templates as $i => $ft ) {
			foreach ( $ft->getFields() as $j => $field ) {
				// handle the change in indexing if a new template was
				// inserted before the end, or one was deleted
				$old_i = $i;
				if ( $new_template_loc != null ) {
					if ( $i > $new_template_loc ) {
						$old_i = $i - 1;
					} elseif ( $i == $new_template_loc ) {
						// it's the new template; it shouldn't
						// get any query-string data
						$old_i = - 1;
					}
				} elseif ( $deleted_template_loc != null ) {
					if ( $i >= $deleted_template_loc ) {
						$old_i = $i + 1;
					}
				}
				foreach ( $wgRequest->getValues() as $key => $value ) {
					if ( ( $pos = strpos( $key, '_' . $old_i . '_' . $j ) ) != false ) {
						$paramName = substr( $key, 0, $pos );
						// Spaces got replaced by
						// underlines in the query.
						$paramName = str_replace( '_', ' ', $paramName );
					} else {
						continue;
					}

					if ( $paramName == 'label' ) {
						$field->template_field->setLabel( $value );
					} elseif ( $paramName == 'input type' ) {
						$input_type = $wgRequest->getVal( "input_type_" . $old_i . "_" . $j );
						if ( $input_type == 'hidden' ) {
							$field->template_field->setInputType( $input_type );
							$field->setIsHidden( true );
						} elseif ( substr( $input_type, 0, 1 ) == '.' ) {
							// It's the default input type -
							// don't do anything.
						} else {
							$field->template_field->setInputType( $input_type );
						}
					} else {
						if ( ! empty( $value ) ) {
							if ( $value == 'on' ) {
								$value = true;
							}
							$field->setFieldArg( $paramName, $value );
						}
					}
				}
			}
		}
		$form = SFForm::create( $form_name, $form_templates );

		// If a submit button was pressed, create the form-definition
		// file, then redirect.
		$save_page = $wgRequest->getCheck( 'wpSave' );
		$preview_page = $wgRequest->getCheck( 'wpPreview' );
		if ( $save_page || $preview_page ) {
			// Validate form name
			if ( $form->getFormName() == "" ) {
				$form_name_error_str = wfMsg( 'sf_blank_error' );
			} else {
				// Redirect to wiki interface
				$wgOut->setArticleBodyOnly( true );
				$title = Title::makeTitleSafe( SF_NS_FORM, $form->getFormName() );
				$full_text = $form->createMarkup();
				$text = SFUtils::printRedirectForm( $title, $full_text, "", $save_page, $preview_page, false, false, false, null, null );
				$wgOut->addHTML( $text );
				return;
			}
		}

		$text = "\t" . '<form action="" method="post">' . "\n";
		// Set 'title' field, in case there's no URL niceness
		$text .= SFFormUtils::hiddenFieldHTML( 'title', $this->getTitle()->getPrefixedText() );
		$text .= "\t<p>" . wfMsg( 'sf_createform_nameinput' ) . ' ' . wfMsg( 'sf_createform_nameinputdesc' ) . ' <input size=25 name="form_name" value="' . $form_name . '" />';
		if ( ! empty( $form_name_error_str ) )
			$text .= "\t" . Html::element( 'font', array( 'color' => 'red' ), $form_name_error_str );
		$text .= "</p>\n";

		$text .= $form->creationHTML();

		$text .= "\t<p>" . wfMsg( 'sf_createform_addtemplate' ) . "\n";

		$select_body = "";
		foreach ( $all_templates as $template ) {
			$select_body .= "	" . Html::element( 'option', array( 'value' => $template ), $template ) . "\n";
		}
		$text .= "\t" . Html::rawElement( 'select', array( 'name' => 'new_template' ), $select_body ) . "\n";
		// If a template has already been added, show a dropdown letting
		// the user choose where in the list to add a new dropdown.
		if ( count( $form_templates ) > 0 ) {
			$before_template_msg = wfMsg( 'sf_createform_beforetemplate' );
			$text .= $before_template_msg;
			$select_body = "";
			foreach ( $form_templates as $i => $ft ) {
				$select_body .= "\t" . Html::element( 'option', array( 'value' => $i ), $ft->getTemplateName() ) . "\n";
			}
			$final_index = count( $form_templates );
			$at_end_msg = wfMsg( 'sf_createform_atend' );
			$select_body .= "\t" . Html::element( 'option', array( 'value' => $final_index, 'selected' => 'selected' ), $at_end_msg );
			$text .= Html::rawElement( 'select', array( 'name' => 'before_template' ), $select_body ) . "\n";
		}

		// Disable 'save' and 'preview' buttons if user has not yet
		// added any templates.
		$disabled_text = ( count( $form_templates ) == 0 ) ? "disabled" : "";
		$add_button_text = wfMsg( 'sf_createform_add' );
		$sk = $wgUser->getSkin();
		$create_template_link = SFUtils::linkForSpecialPage( $sk, 'CreateTemplate' );
		$text .= "\t" . Html::input( 'add_field', $add_button_text, 'submit' );
		$text .= <<<END
</p>
	<br />

END;
		$saveAttrs = array( 'id' => 'wpSave' );
		if ( count( $form_templates ) == 0 ) {
			$saveAttrs['disabled'] = true;
		}
		$editButtonsText = "\t" . Html::input( 'wpSave', wfMsg( 'savearticle' ), 'submit', $saveAttrs ) . "\n";
		$previewAttrs = array( 'id' => 'wpPreview' );
		if ( count( $form_templates ) == 0 ) {
			$previewAttrs['disabled'] = true;
		}
		$editButtonsText .= "\t" . Html::input( 'wpPreview',  wfMsg( 'preview' ), 'submit', $previewAttrs ) . "\n";
		$text .= "\t" . Html::rawElement( 'div', array( 'class' => 'editButtons' ),
			Html::rawElement( 'p', array(), $editButtonsText ) . "\n" ) . "\n";
		// Explanatory message if buttons are disabled because no
		// templates have been added.
		if ( count( $form_templates ) == 0 ) {
			$text .= "\t" . Html::element( 'p', null, "(" . wfMsg( 'sf_createtemplate_addtemplatebeforesave' ) . ")" );
		}
		$text .= <<<END
	</form>
	<hr /><br />

END;
		$text .= "\t" . Html::rawElement( 'p', null, $create_template_link . '.' );

		$wgOut->addExtensionStyle( $sfgScriptPath . "/skins/SemanticForms.css" );
		$wgOut->addHTML( $text );
	}
Ejemplo n.º 22
0
 private static function getAllValuesForProperty($property_name, $substring, $base_property_name = null, $base_value = null)
 {
     global $sfgMaxAutocompleteValues, $sfgCacheAutocompleteValues, $sfgAutocompleteCacheTimeout;
     $values = array();
     $db = wfGetDB(DB_SLAVE);
     $sql_options = array();
     $sql_options['LIMIT'] = $sfgMaxAutocompleteValues;
     $property = SMWPropertyValue::makeUserProperty($property_name);
     $is_relation = $property->getPropertyTypeID() == '_wpg';
     $property_name = str_replace(' ', '_', $property_name);
     $conditions = array('p_ids.smw_title' => $property_name);
     // Use cache if allowed
     if ($sfgCacheAutocompleteValues) {
         $cache = SFFormUtils::getFormCache();
         // Remove trailing whitespace to avoid unnecessary database selects
         $cacheKeyString = $property_name . '::' . rtrim($substring);
         if (!is_null($base_property_name)) {
             $cacheKeyString .= ',' . $base_property_name . ',' . $base_value;
         }
         $cacheKey = wfMemcKey('sf-autocomplete', md5($cacheKeyString));
         $values = $cache->get($cacheKey);
         if (!empty($values)) {
             // Return with results immediately
             return $values;
         }
     }
     if ($is_relation) {
         $value_field = 'o_ids.smw_title';
         $from_clause = $db->tableName('smw_rels2') . " r JOIN " . $db->tableName('smw_ids') . " p_ids ON r.p_id = p_ids.smw_id JOIN " . $db->tableName('smw_ids') . " o_ids ON r.o_id = o_ids.smw_id";
     } else {
         $value_field = 'a.value_xsd';
         $from_clause = $db->tableName('smw_atts2') . " a JOIN " . $db->tableName('smw_ids') . " p_ids ON a.p_id = p_ids.smw_id";
     }
     if (!is_null($base_property_name)) {
         $base_property = SMWPropertyValue::makeUserProperty($base_property_name);
         $base_is_relation = $base_property->getPropertyTypeID() == '_wpg';
         $base_property_name = str_replace(' ', '_', $base_property_name);
         $conditions['base_p_ids.smw_title'] = $base_property_name;
         $main_prop_alias = $is_relation ? 'r' : 'a';
         if ($base_is_relation) {
             $from_clause .= " JOIN " . $db->tableName('smw_rels2') . " r_base ON {$main_prop_alias}.s_id = r_base.s_id";
             $from_clause .= " JOIN " . $db->tableName('smw_ids') . " base_p_ids ON r_base.p_id = base_p_ids.smw_id JOIN " . $db->tableName('smw_ids') . " base_o_ids ON r_base.o_id = base_o_ids.smw_id";
             $base_value = str_replace(' ', '_', $base_value);
             $conditions['base_o_ids.smw_title'] = $base_value;
         } else {
             $from_clause .= " JOIN " . $db->tableName('smw_atts2') . " a_base ON {$main_prop_alias}.s_id = a_base.s_id";
             $from_clause .= " JOIN " . $db->tableName('smw_ids') . " base_p_ids ON a_base.p_id = base_p_ids.smw_id";
             $conditions['a_base.value_xsd'] = $base_value;
         }
     }
     if (!is_null($substring)) {
         $conditions[] = SFUtils::getSQLConditionForAutocompleteInColumn($value_field, $substring);
     }
     $sql_options['ORDER BY'] = $value_field;
     $res = $db->select($from_clause, "DISTINCT {$value_field}", $conditions, __METHOD__, $sql_options);
     while ($row = $db->fetchRow($res)) {
         $values[] = str_replace('_', ' ', $row[0]);
     }
     $db->freeResult($res);
     if ($sfgCacheAutocompleteValues) {
         // Save to cache.
         $cache->set($cacheKey, $values, $sfgAutocompleteCacheTimeout);
     }
     return $values;
 }
Ejemplo n.º 23
0
	function execute( $query ) {
		global $wgOut, $wgRequest, $wgUser, $sfgScriptPath;
		global $wgLang, $smwgContLang;

		# Check permissions
		if ( !$wgUser->isAllowed( 'createclass' ) ) {
			$this->displayRestrictionError();
			return;
		}

		$this->setHeaders();
		$wgOut->addExtensionStyle( $sfgScriptPath . "/skins/SemanticForms.css" );
		$numStartingRows = 10;
		self::addJavascript( $numStartingRows );

		$property_name_error_str = '';
		$save_page = $wgRequest->getCheck( 'save' );
		if ( $save_page ) {
			$template_name = trim( $wgRequest->getVal( "template_name" ) );
			$form_name = trim( $wgRequest->getVal( "form_name" ) );
			$category_name = trim( $wgRequest->getVal( "category_name" ) );
			if ( $template_name === '' | $form_name === '' || $category_name === '' ) {
				$wgOut->addWikiMsg( 'sf_createclass_missingvalues' );
				return;
			}
			$fields = array();
			$jobs = array();
			// cycle through all the rows passed in
			for ( $i = 1; $wgRequest->getCheck( "property_name_$i" ); $i++ ) {
				// go through the query values, setting the appropriate local variables
				$property_name = trim( $wgRequest->getVal( "property_name_$i" ) );
				if ( empty( $property_name ) ) continue;
				$field_name = trim( $wgRequest->getVal( "field_name_$i" ) );
				if ( $field_name === '' )
					$field_name = $property_name;
				$property_type = $wgRequest->getVal( "property_type_$i" );
				$allowed_values = $wgRequest->getVal( "allowed_values_$i" );
				$is_list = $wgRequest->getCheck( "is_list_$i" );
				// create an SFTemplateField based on these
				// values, and add it to the $fields array
				$field = SFTemplateField::create( $field_name, $field_name, $property_name, $is_list );
				$fields[] = $field;

				// create the property, and make a job for it
				$full_text = SFCreateProperty::createPropertyText( $property_type, '', $allowed_values );
				$property_title = Title::makeTitleSafe( SMW_NS_PROPERTY, $property_name );
				$params = array();
				$params['user_id'] = $wgUser->getId();
				$params['page_text'] = $full_text;
				$jobs[] = new SFCreatePageJob( $property_title, $params );
			}

			// create the template, and save it
			$full_text = SFTemplateField::createTemplateText( $template_name, $fields, null, $category_name, null, null, null );
			$template_title = Title::makeTitleSafe( NS_TEMPLATE, $template_name );
			$template_article = new Article( $template_title, 0 );
			$edit_summary = '';
			$template_article->doEdit( $full_text, $edit_summary );

			// create the form, and make a job for it
			$form_template = SFTemplateInForm::create( $template_name, '', false );
			$form_templates = array( $form_template );
			$form = SFForm::create( $form_name, $form_templates );
			$full_text = $form->createMarkup();
			$form_title = Title::makeTitleSafe( SF_NS_FORM, $form_name );
			$params = array();
			$params['user_id'] = $wgUser->getId();
			$params['page_text'] = $full_text;
			$jobs[] = new SFCreatePageJob( $form_title, $params );

			// create the category, and make a job for it
			$full_text = SFCreateCategory::createCategoryText( $form_name, $category_name, '' );
			$category_title = Title::makeTitleSafe( NS_CATEGORY, $category_name );
			$params = array();
			$params['user_id'] = $wgUser->getId();
			$params['page_text'] = $full_text;
			$jobs[] = new SFCreatePageJob( $category_title, $params );
			Job::batchInsert( $jobs );

			$wgOut->addWikiMsg( 'sf_createclass_success' );
			return;
		}

		$datatype_labels = $smwgContLang->getDatatypeLabels();

		// make links to all the other 'Create...' pages, in order to
		// link to them at the top of the page
		$sk = $wgUser->getSkin();
		$creation_links = array();
		$creation_links[] = SFUtils::linkForSpecialPage( $sk, 'CreateProperty' );
		$creation_links[] = SFUtils::linkForSpecialPage( $sk, 'CreateTemplate' );
		$creation_links[] = SFUtils::linkForSpecialPage( $sk, 'CreateForm' );
		$creation_links[] = SFUtils::linkForSpecialPage( $sk, 'CreateCategory' );
		$create_class_docu = wfMsg( 'sf_createclass_docu', $wgLang->listToText( $creation_links ) );
		$leave_field_blank = wfMsg( 'sf_createclass_leavefieldblank' );
		$form_name_label = wfMsg( 'sf_createclass_nameinput' );
		$template_name_label = wfMsg( 'sf_createtemplate_namelabel' );
		$category_name_label = wfMsg( 'sf_createcategory_name' );
		$property_name_label = wfMsg( 'sf_createproperty_propname' );
		$field_name_label = wfMsg( 'sf_createtemplate_fieldname' );
		$type_label = wfMsg( 'sf_createproperty_proptype' );
		$allowed_values_label = wfMsg( 'sf_createclass_allowedvalues' );
		$list_of_values_label = wfMsg( 'sf_createclass_listofvalues' );

		$text = <<<END
<form action="" method="post">
	<p>$create_class_docu</p>
	<p>$leave_field_blank</p>
	<p>$template_name_label <input type="text" size="30" name="template_name"></p>
	<p>$form_name_label <input type="text" size="30" name="form_name"></p>
	<p>$category_name_label <input type="text" size="30" name="category_name"></p>
	<div>
		<table id="mainTable">
		<tr>
			<th colspan="2">$property_name_label</th>
			<th>$field_name_label</th>
			<th>$type_label</th>
			<th>$allowed_values_label</th>
			<th>$list_of_values_label</th>
		</tr>

END;
		// Make one more row than what we're displaying - use the
		// last row as a "starter row", to be cloned when the
		// "Add another" button is pressed.
		for ( $i = 1; $i <= $numStartingRows + 1; $i++ ) {
			if ( $i == $numStartingRows + 1 ) {
				$rowString = 'id="starterRow" style="display: none"';
				$n = 'starter';
			} else {
				$rowString = '';
				$n = $i;
			}
			$text .= <<<END
		<tr $rowString>
			<td>$n.</td>
			<td><input type="text" size="25" name="property_name_$n" /></td>
			<td><input type="text" size="25" name="field_name_$n" /></td>
			<td>
			<select name="property_type_$n">

END;
			$optionsStr ="";
			foreach ( $datatype_labels as $label ) {
				$text .= "				<option>$label</option>\n";
				$optionsStr .= $label . ",";
			}
			$text .= <<<END
			</select>
			</td>
			<td><input type="text" size="25" name="allowed_values_$n" /></td>
			<td><input type="checkbox" name="is_list_$n" /></td>

END;
		}
		$text .= <<<END
		</tr>
		</table>
	</div>

END;
		$add_another_button = Html::element( 'input',
			array(
				'type' => 'button',
				'value' => wfMsg( 'sf_formedit_addanother' ),
				'onclick' => "createClassAddRow()"
			)
		);
		$text .= Html::rawElement( 'p', null, $add_another_button ) . "\n";
		// Set 'title' as hidden field, in case there's no URL niceness
		$cc = $this->getTitle();
		$text .= SFFormUtils::hiddenFieldHTML( 'title', SFUtils::titleURLString( $cc ) );
		$text .= Html::element( 'input',
			array(
				'type' => 'submit',
				'name' => 'save',
				'value' => wfMsg( 'sf_createclass_create' )
			)
		);
		$text .= "</form>\n";
		$wgOut->addHTML( $text );
	}
Ejemplo n.º 24
0
	/**
	 * Prints the mini-form contained at the bottom of various pages, that
	 * allows pages to spoof a normal edit page, that can preview, save,
	 * etc.
	 */
	public static function printRedirectForm( $title, $page_contents, $edit_summary, $is_save, $is_preview, $is_diff, $is_minor_edit, $watch_this, $start_time, $edit_time ) {
		global $wgUser, $sfgScriptPath;

		if ( $is_save ) {
			$action = "wpSave";
		} elseif ( $is_preview ) {
			$action = "wpPreview";
		} else { // $is_diff
			$action = "wpDiff";
		}

		$text = <<<END
	<p style="position: absolute; left: 45%; top: 45%;"><img src="$sfgScriptPath/skins/loading.gif" /></p>

END;
		$form_body = SFFormUtils::hiddenFieldHTML( 'wpTextbox1', $page_contents );
		$form_body .= SFFormUtils::hiddenFieldHTML( 'wpSummary', $edit_summary );
		$form_body .= SFFormUtils::hiddenFieldHTML( 'wpStarttime', $start_time );
		$form_body .= SFFormUtils::hiddenFieldHTML( 'wpEdittime', $edit_time );
		$form_body .= SFFormUtils::hiddenFieldHTML( 'wpEditToken', $wgUser->isLoggedIn() ? $wgUser->editToken() : EDIT_TOKEN_SUFFIX );
		$form_body .= SFFormUtils::hiddenFieldHTML( $action, null );

		if ( $is_minor_edit ) {
			$form_body .= SFFormUtils::hiddenFieldHTML( 'wpMinoredit' , null );
		}
		if ( $watch_this ) {
			$form_body .= SFFormUtils::hiddenFieldHTML( 'wpWatchthis', null );
		}
		$text .= Html::rawElement(
			'form',
			array(
				'id' => 'editform',
				'name' => 'editform',
				'method' => 'post',
				'action' => $title instanceof Title ? $title->getLocalURL( 'action=submit' ) : $title
			),
			$form_body
		);

		$text .= <<<END
	<script type="text/javascript">
	window.onload = function() {
		document.editform.submit();
	}
	</script>

END;
		wfRunHooks( 'sfPrintRedirectForm', array( $is_save, $is_preview, $is_diff, &$text ) );
		return $text;
	}