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 .= Html::hidden($input_name . '[is_list]', 1);
     $outerSpanAttrs = array('id' => $outerSpanID, 'class' => $outerSpanClass);
     $text = "\t" . Html::rawElement('span', $outerSpanAttrs, $text) . "\n";
     return $text;
 }
Beispiel #2
0
 public static function uploadableHTML($input_id, $delimiter = null, $default_filename = null, $cur_value = '', $other_args = array())
 {
     $upload_window_page = SFUtils::getSpecialPage('UploadWindow');
     $query_string = "sfInputID={$input_id}";
     if ($delimiter != null) {
         $query_string .= "&sfDelimiter={$delimiter}";
     }
     if ($default_filename != null) {
         $query_string .= "&wpDestFile={$default_filename}";
     }
     $upload_window_url = $upload_window_page->getTitle()->getFullURL($query_string);
     $upload_label = wfMsg('upload');
     // We need to set the size by default.
     $style = "width:650 height:500";
     $cssClasses = array('sfFancyBox', 'sfUploadable');
     $showPreview = array_key_exists('image preview', $other_args);
     if ($showPreview) {
         $cssClasses[] = 'sfImagePreview';
     }
     $linkAttrs = array('href' => $upload_window_url, 'class' => implode(' ', $cssClasses), 'title' => $upload_label, 'rev' => $style, 'data-input-id' => $input_id);
     $text = "\t" . Html::element('a', $linkAttrs, $upload_label) . "\n";
     if ($showPreview) {
         $text .= Html::rawElement('div', array('id' => $input_id . '_imagepreview', 'class' => 'sfImagePreviewWrapper'), self::getPreviewImage($cur_value));
     }
     return $text;
 }
Beispiel #3
0
 function setTypeAndPossibleValues()
 {
     $proptitle = Title::makeTitleSafe(SMW_NS_PROPERTY, $this->mSemanticProperty);
     if ($proptitle === null) {
         return;
     }
     $store = smwfGetStore();
     // this returns an array of objects
     $allowed_values = SFUtils::getSMWPropertyValues($store, $proptitle, "Allows value");
     $label_formats = SFUtils::getSMWPropertyValues($store, $proptitle, "Has field label format");
     $propValue = SMWDIProperty::newFromUserLabel($this->mSemanticProperty);
     $this->mPropertyType = $propValue->findPropertyTypeID();
     foreach ($allowed_values as $allowed_value) {
         // HTML-unencode each value
         $this->mPossibleValues[] = html_entity_decode($allowed_value);
         if (count($label_formats) > 0) {
             $label_format = $label_formats[0];
             $prop_instance = SMWDataValueFactory::findTypeID($this->mPropertyType);
             $label_value = SMWDataValueFactory::newTypeIDValue($prop_instance, $wiki_value);
             $label_value->setOutputFormat($label_format);
             $this->mValueLabels[$wiki_value] = html_entity_decode($label_value->getWikiValue());
         }
     }
     // HACK - if there were any possible values, set the property
     // type to be 'enumeration', regardless of what the actual type is
     if (count($this->mPossibleValues) > 0) {
         $this->mPropertyType = 'enumeration';
     }
 }
 function setTypeAndPossibleValues()
 {
     // The presence of "-" at the beginning of a property name
     // (which happens if SF tries to parse an inverse query)
     // leads to an error in SMW - just exit if that's the case.
     if (strpos($this->mSemanticProperty, '-') === 0) {
         return;
     }
     $proptitle = Title::makeTitleSafe(SMW_NS_PROPERTY, $this->mSemanticProperty);
     if ($proptitle === null) {
         return;
     }
     $store = SFUtils::getSMWStore();
     // this returns an array of objects
     $allowed_values = SFUtils::getSMWPropertyValues($store, $proptitle, "Allows value");
     $label_formats = SFUtils::getSMWPropertyValues($store, $proptitle, "Has field label format");
     $propValue = SMWDIProperty::newFromUserLabel($this->mSemanticProperty);
     $this->mPropertyType = $propValue->findPropertyTypeID();
     foreach ($allowed_values as $allowed_value) {
         // HTML-unencode each value
         $this->mPossibleValues[] = html_entity_decode($allowed_value);
         if (count($label_formats) > 0) {
             $label_format = $label_formats[0];
             $prop_instance = SMWDataValueFactory::findTypeID($this->mPropertyType);
             $label_value = SMWDataValueFactory::newTypeIDValue($prop_instance, $wiki_value);
             $label_value->setOutputFormat($label_format);
             $this->mValueLabels[$wiki_value] = html_entity_decode($label_value->getWikiValue());
         }
     }
     // HACK - if there were any possible values, set the property
     // type to be 'enumeration', regardless of what the actual type is
     if (count($this->mPossibleValues) > 0) {
         $this->mPropertyType = 'enumeration';
     }
 }
Beispiel #5
0
 function getPageHeader()
 {
     global $wgUser;
     $sk = $wgUser->getSkin();
     $create_form_link = SFUtils::linkForSpecialPage($sk, 'CreateForm');
     $header = "<p>" . $create_form_link . ".</p>\n";
     $header .= '<p>' . wfMsg('sf_forms_docu') . "</p><br />\n";
     return $header;
 }
Beispiel #6
0
    function createMarkup()
    {
        $title = Title::makeTitle(SF_NS_FORM, $this->mFormName);
        $fs = SFUtils::getSpecialPage('FormStart');
        $form_start_url = SFUtils::titleURLString($fs->getTitle()) . "/" . $title->getPartialURL();
        $form_description = wfMsgForContent('sf_form_docu', $this->mFormName, $form_start_url);
        $form_input = "{{#forminput:form=" . $this->mFormName;
        if (!is_null($this->mAssociatedCategory)) {
            $form_input .= "|autocomplete on category=" . $this->mAssociatedCategory;
        }
        $form_input .= "}}\n";
        $text = <<<END
<noinclude>
{$form_description}


{$form_input}
</noinclude><includeonly>

END;
        if (!empty($this->mPageNameFormula) || !empty($this->mCreateTitle) || !empty($this->mEditTitle)) {
            $text .= "{{{info";
            if (!empty($this->mPageNameFormula)) {
                $text .= "|page name=" . $this->mPageNameFormula;
            }
            if (!empty($this->mCreateTitle)) {
                $text .= "|create title=" . $this->mCreateTitle;
            }
            if (!empty($this->mEditTitle)) {
                $text .= "|edit title=" . $this->mEditTitle;
            }
            $text .= "}}}\n";
        }
        $text .= <<<END
<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div>

END;
        foreach ($this->mTemplates as $template) {
            $text .= $template->createMarkup() . "\n";
        }
        $free_text_label = wfMsgForContent('sf_form_freetextlabel');
        $text .= <<<END
'''{$free_text_label}:'''

{{{standard input|free text|rows=10}}}


{{{standard input|summary}}}

{{{standard input|minor edit}}} {{{standard input|watch}}}

{{{standard input|save}}} {{{standard input|preview}}} {{{standard input|changes}}} {{{standard input|cancel}}}
</includeonly>

END;
        return $text;
    }
Beispiel #7
0
 /**
  * Returns the HTML code to be included in the output page for this input.
  */
 public function getHtmlText()
 {
     global $sfgTabIndex, $sfgFieldNum, $sfgShowOnSelect;
     $className = $this->mIsMandatory ? 'mandatoryField' : 'createboxInput';
     if (array_key_exists('class', $this->mOtherArgs)) {
         $className .= ' ' . $this->mOtherArgs['class'];
     }
     $input_id = "input_{$sfgFieldNum}";
     // get list delimiter - default is comma
     if (array_key_exists('delimiter', $this->mOtherArgs)) {
         $delimiter = $this->mOtherArgs['delimiter'];
     } else {
         $delimiter = ',';
     }
     $cur_values = SFUtils::getValuesArray($this->mCurrentValue, $delimiter);
     $className .= ' sfShowIfSelected';
     if (($possible_values = $this->mOtherArgs['possible_values']) == null) {
         $possible_values = array();
     }
     $optionsText = '';
     foreach ($possible_values as $possible_value) {
         if (array_key_exists('value_labels', $this->mOtherArgs) && is_array($this->mOtherArgs['value_labels']) && array_key_exists($possible_value, $this->mOtherArgs['value_labels'])) {
             $optionLabel = $this->mOtherArgs['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' => $this->mInputName . '[]', 'class' => $className, 'multiple' => 'multiple');
     if (array_key_exists('size', $this->mOtherArgs)) {
         $selectAttrs['size'] = $this->mOtherArgs['size'];
     }
     if ($this->mIsDisabled) {
         $selectAttrs['disabled'] = 'disabled';
     }
     $text = Html::rawElement('select', $selectAttrs, $optionsText);
     $text .= Html::hidden($this->mInputName . '[is_list]', 1);
     if ($this->mIsMandatory) {
         $text = Html::rawElement('span', array('class' => 'inputSpan mandatoryFieldSpan'), $text);
     }
     if (array_key_exists('show on select', $this->mOtherArgs)) {
         foreach ($this->mOtherArgs['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;
 }
Beispiel #8
0
 public static function getHTML($cur_value, $input_name, $is_mandatory, $is_disabled, $other_args)
 {
     // For backward compatibility with pre-SF-2.1 forms
     if (array_key_exists('no autocomplete', $other_args) && $other_args['no autocomplete'] == true) {
         unset($other_args['autocompletion source']);
         return SFTextInput::getHTML($cur_value, $input_name, $is_mandatory, $is_disabled, $other_args);
     }
     global $sfgTabIndex, $sfgFieldNum;
     $className = 'sfComboBox';
     if ($is_mandatory) {
         $className .= ' mandatoryField';
     }
     if (array_key_exists('class', $other_args)) {
         $className .= ' ' . $other_args['class'];
     }
     if (array_key_exists('size', $other_args)) {
         $size = $other_args['size'];
     } else {
         $size = '35';
     }
     // There's no direct correspondence between the 'size='
     // attribute for text inputs and the number of pixels, but
     // multiplying by 6 seems to be about right for the major
     // browsers.
     $pixel_width = $size * 6 . 'px';
     list($autocompleteFieldType, $autocompletionSource) = SFTextWithAutocompleteInput::getAutocompletionTypeAndSource($other_args);
     // @TODO - that count() check shouldn't be necessary
     if (array_key_exists('possible_values', $other_args) && count($other_args['possible_values']) > 0) {
         $values = $other_args['possible_values'];
     } elseif ($autocompleteFieldType == 'values') {
         $values = explode(',', $other_args['values']);
     } else {
         $values = SFUtils::getAutocompleteValues($autocompletionSource, $autocompleteFieldType);
     }
     $autocompletionSource = str_replace("'", "\\'", $autocompletionSource);
     $optionsText = Html::element('option', array('value' => $cur_value), null, false) . "\n";
     foreach ($values as $value) {
         $optionsText .= Html::element('option', array('value' => $value), $value) . "\n";
     }
     $selectAttrs = array('id' => "input_{$sfgFieldNum}", 'name' => $input_name, 'class' => $className, 'tabindex' => $sfgTabIndex, 'autocompletesettings' => $autocompletionSource, 'comboboxwidth' => $pixel_width);
     if (array_key_exists('origName', $other_args)) {
         $selectAttrs['origname'] = $other_args['origName'];
     }
     if (array_key_exists('existing values only', $other_args)) {
         $selectAttrs['existingvaluesonly'] = 'true';
     }
     $selectText = Html::rawElement('select', $selectAttrs, $optionsText);
     $divClass = 'ui-widget';
     if ($is_mandatory) {
         $divClass .= ' mandatory';
     }
     $text = Html::rawElement('div', array('class' => $divClass), $selectText);
     return $text;
 }
 protected function showContentForm()
 {
     $target_title = $this->mArticle->getTitle();
     $target_name = SFUtils::titleString($target_title);
     if ($target_title->exists()) {
         SFEditData::printEditForm($this->form_name, $target_name, $this->textbox1);
     } else {
         SFAddData::printAddForm($this->form_name, $target_name, array(), $this->textbox1);
     }
     // @todo This needs a proper form builder
 }
	public function execute() {
		$params = $this->extractRequestParams();
		$substr = $params['substr'];
		$namespace = $params['namespace'];
		$property = $params['property'];
		$category = $params['category'];
		$concept = $params['concept'];
		$external_url = $params['external_url'];
		$baseprop = $params['baseprop'];
		$basevalue = $params['basevalue'];
		//$limit = $params['limit'];

		if ( is_null( $baseprop ) && strlen( $substr ) == 0 ) {
			$this->dieUsage( 'The substring must be specified', 'param_substr' );
		}

		if ( !is_null( $baseprop ) ) {
			if ( !is_null( $property ) ) {
				$data = self::getAllValuesForProperty( $property, null, $baseprop, $basevalue );
			}
		} elseif ( !is_null( $property ) ) {
			$data = self::getAllValuesForProperty( $property, $substr );
		} elseif ( !is_null( $category ) ) {
			$data = SFUtils::getAllPagesForCategory( $category, 3, $substr );
		} elseif ( !is_null( $concept ) ) {
			$data = SFUtils::getAllPagesForConcept( $concept, $substr );
		} elseif ( !is_null( $namespace ) ) {
			$data = SFUtils::getAllPagesForNamespace( $namespace, $substr );
		} elseif ( !is_null( $external_url ) ) {
			$data = SFUtils::getValuesFromExternalURL( $external_url, $substr );
		} else {
			$data = array();
		}

		// to prevent JS parsing problems, display should be the same
		// even if there are no results
		/*
		if ( count( $data ) <= 0 ) {
			return;
		}
		 */

		// Format data as the API requires it.
		$formattedData = array();
		foreach ( $data as $value ) {
			$formattedData[] = array( 'title' => $value );
		}

		// Set top-level elements.
		$result = $this->getResult();
		$result->setIndexedTagName( $formattedData, 'p' );
		$result->addValue( null, $this->getModuleName(), $formattedData );
	}
Beispiel #11
0
 /**
  * @param Parser $parser
  * @return mixed
  */
 public static function formlink($parser)
 {
     $params = func_get_args();
     array_shift($params);
     // We don't need the parser.
     $original = SFUtils::createFormLink($parser, $params, 'formlink');
     if (strpos($original, 'class="new"') !== false) {
         $original = str_replace('class="new"', 'class="btn btn-primary pull-right"', $original);
     } else {
         $original = str_replace('href=', 'class="btn btn-primary pull-right" href=', $original);
     }
     $original = str_replace('self">', 'self"><i class="fa fa-edit"></i> ', $original);
     return $parser->insertStripItem($original);
 }
Beispiel #12
0
 /**
  * Loads skin and user CSS files.
  * @param OutputPage $out
  */
 function setupSkinUserCss(OutputPage $out)
 {
     parent::setupSkinUserCss($out);
     $title = $out->getTitle();
     $isCard = false;
     if ($title && $title->exists()) {
         $categoris = SFUtils::getCategoriesForPage($title);
         if (in_array('Card', $categoris)) {
             if (!$out->getRequest()->getVal('action') || $out->getRequest()->getVal('action') == 'view') {
                 $isCard = true;
             }
         }
     }
     if ($title && $title->exists() && $title->getNamespace() == NS_MAIN) {
         if ($title->getArticleID() === Title::newMainPage()->getArticleID()) {
             $styles = array('skins.settlein.styles');
         } else {
             if ($isCard) {
                 $styles = array('skins.settlein.page.styles');
             } else {
                 $styles = array('skins.settlein.styles');
             }
         }
     } else {
         if ($isCard) {
             $styles = array('skins.settlein.page.styles');
         } else {
             $styles = array('skins.settlein.styles');
         }
     }
     if ($out->getRequest()->getVal('color')) {
         global $wgServer, $wgScriptPath;
         $color = htmlspecialchars($out->getRequest()->getVal('color'));
         $out->addStyle($wgServer . $wgScriptPath . '/skins/SettleIn/assets/colors/' . $color . '.css');
     }
     if ($out->getRequest()->getVal('beta_font')) {
         global $wgServer, $wgScriptPath;
         $font = htmlspecialchars($out->getRequest()->getVal('beta_font'));
         $out->addStyle($wgServer . $wgScriptPath . '/skins/SettleIn/assets/fonts/' . $font . '.css');
     }
     if ($this->getUser() && $this->getUser()->isLoggedIn()) {
         $out->addModuleStyles('ext.settlegeoforminput.foo');
     }
     $out->addModuleStyles($styles);
 }
Beispiel #13
0
 /**
  * Renders the #serieslink parser function.
  * 
  * @param Parser $parser
  * @return string the unique tag which must be inserted into the stripped text 
  */
 public static function renderSeriesLink(&$parser)
 {
     global $wgTitle;
     $params = func_get_args();
     array_shift($params);
     // We don't need the parser.
     // remove the target parameter should it be present
     foreach ($params as $key => $value) {
         $elements = explode('=', $value, 2);
         if ($elements[0] === 'target') {
             unset($params[$key]);
         }
     }
     // set the origin parameter
     // This will block it from use as iterator parameter. Oh well.
     $params[] = "origin=" . $parser->getTitle()->getArticleId();
     // 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(SFUtils::createFormLink($parser, 'SeriesEdit', $params), $parser->mStripState);
 }
 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;
 }
 /**
  * Get the form(s) used to edit this page - either:
  * - the default form(s) for the page itself, if there are any; or
  * - the default form(s) for a category that this article belongs to,
  * if there are any; or
  * - the default form(s) for the article's namespace, if there are any.
  */
 static function getDefaultFormsForPage($title)
 {
     // See if the page itself has a default form (or forms), and
     // return it/them if so.
     // (Disregard category pages for this check.)
     if ($title->getNamespace() != NS_CATEGORY) {
         $default_form = self::getDefaultForm($title);
         if ($default_form != '') {
             return array($default_form);
         }
     }
     $default_forms = self::getFormsThatPagePointsTo($title->getText(), $title->getNamespace(), self::PAGE_DEFAULT_FORM);
     if (count($default_forms) > 0) {
         return $default_forms;
     }
     // If this is not a category page, look for a default form
     // for its parent category or categories.
     $namespace = $title->getNamespace();
     if (NS_CATEGORY !== $namespace) {
         $default_forms = array();
         $categories = SFUtils::getCategoriesForPage($title);
         foreach ($categories as $category) {
             if (class_exists('PSSchema')) {
                 // Check the Page Schema, if one exists.
                 $psSchema = new PSSchema($category);
                 if ($psSchema->isPSDefined()) {
                     $formName = SFPageSchemas::getFormName($psSchema);
                     if (!is_null($formName)) {
                         $default_forms[] = $formName;
                     }
                 }
             }
             $categoryPage = Title::makeTitleSafe(NS_CATEGORY, $category);
             $defaultFormForCategory = self::getDefaultForm($categoryPage);
             if ($defaultFormForCategory != '') {
                 $default_forms[] = $defaultFormForCategory;
             }
             $default_forms = array_merge($default_forms, self::getFormsThatPagePointsTo($category, NS_CATEGORY, self::DEFAULT_FORM));
         }
         if (count($default_forms) > 0) {
             // It is possible for two categories to have the same default form, so purge any
             // duplicates from the array to avoid a "more than one default form" warning.
             return array_unique($default_forms);
         }
     }
     // All that's left is checking for the namespace. If this is
     // a subpage, exit out - default forms for namespaces don't
     // apply to subpages.
     if ($title->isSubpage()) {
         return array();
     }
     // If we're still here, just return the default form for the
     // namespace, which may well be null.
     if (NS_MAIN === $namespace) {
         // If it's in the main (blank) namespace, check for the
         // file named with the word for "Main" in this language.
         $namespace_label = wfMessage('sf_blank_namespace')->inContentLanguage()->text();
     } else {
         global $wgContLang;
         $namespace_labels = $wgContLang->getNamespaces();
         $namespace_label = $namespace_labels[$namespace];
     }
     $namespacePage = Title::makeTitleSafe(NS_PROJECT, $namespace_label);
     $default_form = self::getDefaultForm($namespacePage);
     if ($default_form != '') {
         return array($default_form);
     }
     $default_forms = self::getFormsThatPagePointsTo($namespace_label, NS_PROJECT, self::DEFAULT_FORM);
     return $default_forms;
 }
	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 );
	}
Beispiel #17
0
 function formatResult($skin, $result)
 {
     $title = Title::makeTitle(NS_TEMPLATE, $result->value);
     $text = Linker::link($title, htmlspecialchars($title->getText()));
     $category = $this->getCategoryDefinedByTemplate($title);
     if ($category !== '') {
         $text .= ' ' . wfMessage('sf_templates_definescat', SFUtils::linkText(NS_CATEGORY, $category))->parse();
     }
     return $text;
 }
    function printPage($form_name, $embedded = false)
    {
        global $wgOut, $wgRequest, $sfgFormPrinter, $wgParser, $sfgRunQueryFormAtTop;
        global $wgUser;
        // 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'), wfMessage('sf_runquery_badurl')->text()) . "\n";
            } else {
                $text = Html::rawElement('p', array('class' => 'error'), wfMessage('sf_formstart_badform', SFUtils::linkText(SF_NS_FORM, $form_name))->parse()) . "\n";
            }
            $wgOut->addHTML($text);
            return;
        }
        // Initialize variables.
        $form_definition = SFUtils::getPageText($form_title);
        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_title->getArticleID(), $edit_content, null, null, true, $embedded);
        $text = "";
        // Get the text of the results.
        $resultsText = '';
        if ($form_submitted) {
            // @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");
            }
            $wgParser->mOptions = ParserOptions::newFromUser($wgUser);
            $resultsText = $wgParser->parse($data_text, $this->getTitle(), $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, wfMessage('sf_runquery_additionalquery')->text()) . "\n";
                $dividerText = "\n<hr style=\"margin: 15px 0;\" />\n";
            }
            $action = htmlspecialchars($this->getTitle($form_name)->getLocalURL());
            $fullFormText .= <<<END
\t<form id="sfForm" name="createbox" action="{$action}" method="post" class="createbox">

END;
            $fullFormText .= Html::hidden('query', 'true');
            $fullFormText .= $form_text;
        }
        // Either don't display a query form at all, or display the
        // query form at the top, and the results at the bottom, or the
        // other way around, depending on the settings.
        if ($wgRequest->getVal('additionalquery') == 'false') {
            $text .= $resultsText;
        } elseif ($sfgRunQueryFormAtTop) {
            $text .= Html::openElement('div', array('class' => 'sf-runquery-formcontent'));
            $text .= $fullFormText;
            $text .= $dividerText;
            $text .= Html::closeElement('div');
            $text .= $resultsText;
        } else {
            $text .= $resultsText;
            $text .= Html::openElement('div', array('class' => 'sf-runquery-formcontent'));
            $text .= $additionalQueryHeader;
            $text .= $fullFormText;
            $text .= Html::closeElement('div');
        }
        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::addFormRLModules($embedded ? $wgParser : null);
        $script = "\t\t" . '<script type="text/javascript">' . "\n" . $javascript_text . '</script>' . "\n";
        if ($embedded) {
            if (method_exists('ResourceLoader', 'makeInlineScript')) {
                // MW 1.25+
                $wgParser->getOutput()->addHeadItem(ResourceLoader::makeInlineScript($javascript_text));
            } else {
                $wgParser->getOutput()->addHeadItem($script);
            }
        } else {
            if (method_exists('ResourceLoader', 'makeInlineScript')) {
                // MW 1.25+
                $wgOut->addScript(ResourceLoader::makeInlineScript($javascript_text));
            } else {
                $wgOut->addScript($script);
            }
            $po = $wgParser->getOutput();
            if ($po) {
                // addParserOutputMetadata was introduced in 1.24 when addParserOutputNoText was deprecated
                if (method_exists($wgOut, 'addParserOutputMetadata')) {
                    $wgOut->addParserOutputMetadata($po);
                } else {
                    $wgOut->addParserOutputNoText($po);
                }
            }
        }
        // Finally, set the page title - previously, this had to be
        // called after addParserOutputNoText() for it to take effect;
        // now the order doesn't matter.
        if (!$embedded) {
            if ($form_page_title != null) {
                $wgOut->setPageTitle($form_page_title);
            } else {
                $s = wfMessage('sf_runquery_title', $form_title->getText())->text();
                $wgOut->setPageTitle($s);
            }
        }
    }
    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
\t<form action="" method="get">

END;
        $text .= "\t" . Html::hidden('title', "{$special_namespace}:CreateCategory") . "\n";
        $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
\t<p>{$subcategory_label}
\t<select id="category_dropdown" name="parent_category">
\t<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
\t<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);
    }
Beispiel #20
0
 static function renderAutoEdit(&$parser)
 {
     // set defaults
     $formcontent = '';
     $linkString = null;
     $linkType = 'span';
     $summary = null;
     $classString = 'autoedit-trigger';
     $inQueryArr = array();
     $editTime = null;
     // parse parameters
     $params = func_get_args();
     array_shift($params);
     // don't need the parser
     foreach ($params as $param) {
         $elements = explode('=', $param, 2);
         $key = trim($elements[0]);
         $value = count($elements) > 1 ? trim($elements[1]) : '';
         switch ($key) {
             case 'link text':
                 $linkString = $parser->recursiveTagParse($value);
                 break;
             case 'link type':
                 $linkType = $parser->recursiveTagParse($value);
                 break;
             case 'reload':
                 $classString .= ' reload';
                 break;
             case 'summary':
                 $summary = $parser->recursiveTagParse($value);
                 break;
             case 'query string':
                 // Change HTML-encoded ampersands directly to
                 // URL-encoded ampersands, so that the string
                 // doesn't get split up on the '&'.
                 $inQueryStr = str_replace('&amp;', '%26', $value);
                 parse_str($inQueryStr, $arr);
                 $inQueryArr = SFUtils::array_merge_recursive_distinct($inQueryArr, $arr);
                 break;
             case 'ok text':
             case 'error text':
                 // do not parse ok text or error text yet. Will be parsed on api call
                 $arr = array($key => $value);
                 $inQueryArr = SFUtils::array_merge_recursive_distinct($inQueryArr, $arr);
                 break;
             case 'target':
             case 'title':
                 $value = $parser->recursiveTagParse($value);
                 $arr = array($key => $value);
                 $inQueryArr = SFUtils::array_merge_recursive_distinct($inQueryArr, $arr);
                 $targetTitle = Title::newFromText($value);
                 if ($targetTitle !== null) {
                     $targetArticle = new Article($targetTitle);
                     $targetArticle->clear();
                     $editTime = $targetArticle->getTimestamp();
                 }
             default:
                 $value = $parser->recursiveTagParse($value);
                 $arr = array($key => $value);
                 $inQueryArr = SFUtils::array_merge_recursive_distinct($inQueryArr, $arr);
         }
     }
     // query string has to be turned into hidden inputs.
     if (!empty($inQueryArr)) {
         $query_components = explode('&', http_build_query($inQueryArr, '', '&'));
         foreach ($query_components as $query_component) {
             $var_and_val = explode('=', $query_component, 2);
             if (count($var_and_val) == 2) {
                 $formcontent .= Html::hidden(urldecode($var_and_val[0]), urldecode($var_and_val[1]));
             }
         }
     }
     if ($linkString == null) {
         return null;
     }
     if ($linkType == 'button') {
         // Html::rawElement() before MW 1.21 or so drops the type attribute
         // do not use Html::rawElement() for buttons!
         $linkElement = '<button ' . Html::expandAttributes(array('type' => 'submit', 'class' => $classString)) . '>' . $linkString . '</button>';
     } elseif ($linkType == 'link') {
         $linkElement = Html::rawElement('a', array('class' => $classString, 'href' => "#"), $linkString);
     } else {
         $linkElement = Html::rawElement('span', array('class' => $classString), $linkString);
     }
     if ($summary == null) {
         $summary = wfMessage('sf_autoedit_summary', "[[{$parser->getTitle()}]]")->text();
     }
     $formcontent .= Html::hidden('wpSummary', $summary);
     if ($editTime !== null) {
         $formcontent .= Html::hidden('wpEdittime', $editTime);
     }
     $form = Html::rawElement('form', array('class' => 'autoedit-data'), $formcontent);
     // ensure loading of jQuery and style sheets
     self::loadScriptsForAutoEdit($parser);
     $output = Html::rawElement('div', array('class' => 'autoedit'), $linkElement . Html::rawElement('span', array('class' => "autoedit-result"), null) . $form);
     // return output HTML
     return $parser->insertStripItem($output, $parser->mStripState);
 }
 /**
  * returns an array of pages that are result of the semantic query
  * @param $rawQueryString string - the query string like [[Category:Trees]][[age::>1000]]
  * @return array of SMWDIWikiPage objects representing the result
  */
 public static function getAllPagesForQuery($rawQuery)
 {
     $rawQueryArray = array($rawQuery);
     SMWQueryProcessor::processFunctionParams($rawQueryArray, $queryString, $processedParams, $printouts);
     SMWQueryProcessor::addThisPrintout($printouts, $processedParams);
     $processedParams = SMWQueryProcessor::getProcessedParams($processedParams, $printouts);
     $queryObj = SMWQueryProcessor::createQuery($queryString, $processedParams, SMWQueryProcessor::SPECIAL_PAGE, '', $printouts);
     $res = SFUtils::getSMWStore()->getQueryResult($queryObj);
     $pages = $res->getResults();
     return $pages;
 }
Beispiel #22
0
    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) {
            $validToken = $this->getUser()->matchEditToken($wgRequest->getVal('csrf'), 'CreateTemplate');
            if (!$validToken) {
                $text = "This appears to be a cross-site request forgery; canceling save.";
                $wgOut->addHTML($text);
                return;
            }
            $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 .= Html::hidden('title', $this->getTitle()->getPrefixedText()) . "\n";
        $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";
        $text .= "\t" . Html::hidden('csrf', $this->getUser()->getEditToken('CreateTemplate')) . "\n";
        $save_button_text = wfMsg('savearticle');
        $preview_button_text = wfMsg('preview');
        $text .= <<<END
\t<div class="editButtons">
\t<input type="submit" id="wpSave" name="wpSave" value="{$save_button_text}" />
\t<input type="submit" id="wpPreview" name="wpPreview" value="{$preview_button_text}" />
\t</div>
\t</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);
    }
	/**
	 * Get the form(s) used to edit this page - either:
	 * - the default form(s) for the page itself, if there are any; or
	 * - the default form(s) for a category that this article belongs to,
	 * if there are any; or
	 * - the default form(s) for the article's namespace, if there are any.
	 */
	static function getDefaultFormsForPage( $title ) {
		// See if the page itself has a default form (or forms), and
		// return it/them if so.
		$default_forms = self::getFormsThatPagePointsTo( $title->getText(), $title->getNamespace(), self::PAGE_DEFAULT_FORM );
		if ( count( $default_forms ) > 0 ) {
			return $default_forms;
		}
		// If this is not a category page, look for a default form
		// for its parent category or categories.
		$namespace = $title->getNamespace();
		if ( NS_CATEGORY !== $namespace ) {
			$default_forms = array();
			$categories = SFUtils::getCategoriesForPage( $title );
			foreach ( $categories as $category ) {
				if ( class_exists( 'PSSchema' ) ) {
					// Check the Page Schema, if one exists.
					$psSchema = new PSSchema( $category );
					if ( $psSchema->isPSDefined() ) {
						$formName = SFPageSchemas::getFormName( $psSchema );
						if ( !is_null( $formName ) ) {
							$default_forms[] = $formName;
						}
					}
				}
				$default_forms = array_merge( $default_forms, self::getFormsThatPagePointsTo( $category, NS_CATEGORY, self::DEFAULT_FORM ) );
			}
			if ( count( $default_forms ) > 0 ) {
				return $default_forms;
			}
		}

		// All that's left is checking for the namespace. If this is
		// a subpage, exit out - default forms for namespaces don't
		// apply to subpages.
		if ( $title->isSubpage() ) {
			return array();
		}

		// If we're still here, just return the default form for the
		// namespace, which may well be null.
		if ( NS_MAIN === $namespace ) {
			// If it's in the main (blank) namespace, check for the
			// file named with the word for "Main" in this language.
			$namespace_label = wfMsgForContent( 'sf_blank_namespace' );
		} else {
			global $wgContLang;
			$namespace_labels = $wgContLang->getNamespaces();
			$namespace_label = $namespace_labels[$namespace];
		}
		$default_forms = self::getFormsThatPagePointsTo( $namespace_label, NS_PROJECT, self::DEFAULT_FORM );
		return $default_forms;
	}
Beispiel #24
0
 static function createFormLink(&$parser, $specialPageName, $params)
 {
     // Set defaults.
     $inFormName = $inLinkStr = $inLinkType = $inTooltip = $inQueryStr = $inTargetName = '';
     if ($specialPageName == 'RunQuery') {
         $inLinkStr = wfMessage('runquery')->text();
     }
     $classStr = "";
     $inQueryArr = array();
     $positionalParameters = false;
     // assign params
     // - support unlabelled params, for backwards compatibility
     // - parse and sanitize all parameter values
     foreach ($params as $i => $param) {
         $elements = explode('=', $param, 2);
         // set param_name and value
         if (count($elements) > 1 && !$positionalParameters) {
             $param_name = trim($elements[0]);
             // parse (and sanitize) parameter values
             $value = trim($parser->recursiveTagParse($elements[1]));
         } else {
             $param_name = null;
             // parse (and sanitize) parameter values
             $value = trim($parser->recursiveTagParse($param));
         }
         if ($param_name == 'form') {
             $inFormName = $value;
         } elseif ($param_name == 'link text') {
             $inLinkStr = $value;
         } elseif ($param_name == 'link type') {
             $inLinkType = $value;
         } elseif ($param_name == 'query string') {
             // Change HTML-encoded ampersands directly to
             // URL-encoded ampersands, so that the string
             // doesn't get split up on the '&'.
             $inQueryStr = str_replace('&amp;', '%26', $value);
             parse_str($inQueryStr, $arr);
             $inQueryArr = self::array_merge_recursive_distinct($inQueryArr, $arr);
         } elseif ($param_name == 'tooltip') {
             $inTooltip = Sanitizer::decodeCharReferences($value);
         } elseif ($param_name == 'target') {
             $inTargetName = $value;
         } elseif ($param_name == null && $value == 'popup') {
             self::loadScriptsForPopupForm($parser);
             $classStr = 'popupformlink';
         } elseif ($param_name !== null && !$positionalParameters) {
             $value = urlencode($value);
             parse_str("{$param_name}={$value}", $arr);
             $inQueryArr = self::array_merge_recursive_distinct($inQueryArr, $arr);
         } elseif ($i == 0) {
             $inFormName = $value;
             $positionalParameters = true;
         } elseif ($i == 1) {
             $inLinkStr = $value;
         } elseif ($i == 2) {
             $inLinkType = $value;
         } elseif ($i == 3) {
             // Change HTML-encoded ampersands directly to
             // URL-encoded ampersands, so that the string
             // doesn't get split up on the '&'.
             $inQueryStr = str_replace('&amp;', '%26', $value);
             parse_str($inQueryStr, $arr);
             $inQueryArr = self::array_merge_recursive_distinct($inQueryArr, $arr);
         }
     }
     $ad = SFUtils::getSpecialPage($specialPageName);
     $link_url = $ad->getTitle()->getLocalURL() . "/{$inFormName}";
     if (!empty($inTargetName)) {
         $link_url .= "/{$inTargetName}";
     }
     $link_url = str_replace(' ', '_', $link_url);
     $hidden_inputs = "";
     if (!empty($inQueryArr)) {
         // Special handling for the buttons - query string
         // has to be turned into hidden inputs.
         if ($inLinkType == 'button' || $inLinkType == 'post button') {
             $query_components = explode('&', http_build_query($inQueryArr, '', '&'));
             foreach ($query_components as $query_component) {
                 $var_and_val = explode('=', $query_component, 2);
                 if (count($var_and_val) == 2) {
                     $hidden_inputs .= Html::hidden(urldecode($var_and_val[0]), urldecode($var_and_val[1]));
                 }
             }
         } else {
             $link_url .= strstr($link_url, '?') ? '&' : '?';
             $link_url .= str_replace('+', '%20', http_build_query($inQueryArr, '', '&'));
         }
     }
     if ($inLinkType == 'button' || $inLinkType == 'post button') {
         $formMethod = $inLinkType == 'button' ? 'get' : 'post';
         $str = Html::rawElement('form', array('action' => $link_url, 'method' => $formMethod, 'class' => $classStr), '<button ' . Html::expandAttributes(array('type' => 'submit', 'value' => $inLinkStr)) . '>' . $inLinkStr . '</button>' . $hidden_inputs);
     } else {
         // If a target page has been specified but it doesn't
         // exist, make it a red link.
         if (!empty($inTargetName)) {
             $targetTitle = Title::newFromText($inTargetName);
             if (is_null($targetTitle) || !$targetTitle->exists()) {
                 $classStr .= " new";
             }
         }
         $str = Html::rawElement('a', array('href' => $link_url, 'class' => $classStr, 'title' => $inTooltip), $inLinkStr);
     }
     return $str;
 }
 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;
 }
 function getAllFieldsCargo($templateTitle)
 {
     $cargoFieldsOfTemplateParams = array();
     $templateFields = array();
     // First, get the table name, and fields, declared for this
     // template.
     $templatePageID = $templateTitle->getArticleID();
     $tableSchemaString = CargoUtils::getPageProp($templatePageID, 'CargoFields');
     // See if there even is DB storage for this template - if not,
     // exit.
     if (is_null($tableSchemaString)) {
         return null;
     }
     $tableSchema = CargoTableSchema::newFromDBString($tableSchemaString);
     $tableName = CargoUtils::getPageProp($templatePageID, 'CargoTableName');
     // Then, match template params to Cargo table fields, by
     // parsing call(s) to #cargo_store.
     $templateText = SFUtils::getPageText($templateTitle);
     // Ignore 'noinclude' sections and 'includeonly' tags.
     $templateText = StringUtils::delimiterReplace('<noinclude>', '</noinclude>', '', $templateText);
     $templateText = strtr($templateText, array('<includeonly>' => '', '</includeonly>' => ''));
     // Let's find every #cargo_store tag.
     // Unfortunately, it doesn't seem possible to use a regexp
     // search for this, because it's hard to know which set of
     // double brackets represents the end of such a call. Instead,
     // we'll do some manual parsing.
     $cargoStoreLocations = array();
     $curPos = 0;
     while (true) {
         $newPos = strpos($templateText, "#cargo_store:", $curPos);
         if ($newPos === false) {
             break;
         }
         $curPos = $newPos + 13;
         $cargoStoreLocations[] = $curPos;
     }
     $cargoStoreCalls = array();
     foreach ($cargoStoreLocations as $locNum => $startPos) {
         $numUnclosedBrackets = 2;
         if ($locNum < count($cargoStoreLocations) - 1) {
             $lastPos = $cargoStoreLocations[$locNum + 1];
         } else {
             $lastPos = strlen($templateText) - 1;
         }
         $curCargoStoreCall = '';
         $curPos = $startPos;
         while ($curPos <= $lastPos) {
             $curChar = $templateText[$curPos];
             $curCargoStoreCall .= $curChar;
             if ($curChar == '}') {
                 $numUnclosedBrackets--;
             } elseif ($curChar == '{') {
                 $numUnclosedBrackets++;
             }
             if ($numUnclosedBrackets == 0) {
                 break;
             }
             $curPos++;
         }
         $cargoStoreCalls[] = $curCargoStoreCall;
     }
     foreach ($cargoStoreCalls as $cargoStoreCall) {
         if (preg_match_all('/([^|{]*?)=\\s*{{{([^|}]*)/mis', $cargoStoreCall, $matches)) {
             foreach ($matches[1] as $i => $cargoFieldName) {
                 $templateParameter = trim($matches[2][$i]);
                 $cargoFieldsOfTemplateParams[$templateParameter] = $cargoFieldName;
             }
         }
     }
     // Now, combine the two sets of information into an array of
     // SFTemplateFields objects.
     $fieldDescriptions = $tableSchema->mFieldDescriptions;
     foreach ($cargoFieldsOfTemplateParams as $templateParameter => $cargoField) {
         $templateField = SFTemplateField::create($templateParameter, $templateParameter);
         if (array_key_exists($cargoField, $fieldDescriptions)) {
             $fieldDescription = $fieldDescriptions[$cargoField];
             $templateField->setCargoFieldData($tableName, $cargoField, $fieldDescription);
         }
         $templateFields[] = $templateField;
     }
     return $templateFields;
 }
	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 );
	}
 function execute($query)
 {
     global $wgOut, $wgRequest, $sfgScriptPath;
     $this->setHeaders();
     // Cycle through the query values, setting the appropriate
     // local variables.
     if (!is_null($query)) {
         $presetCategoryName = str_replace('_', ' ', $query);
         $wgOut->setPageTitle(wfMessage('sf-createcategory-with-name', $presetCategoryName)->text());
         $category_name = $presetCategoryName;
     } else {
         $presetCategoryName = null;
         $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) {
         // Guard against cross-site request forgeries (CSRF).
         $validToken = $this->getUser()->matchEditToken($wgRequest->getVal('csrf'), 'CreateCategory');
         if (!$validToken) {
             $text = "This appears to be a cross-site request forgery; canceling save.";
             $wgOut->addHTML($text);
             return;
         }
         // Validate category name
         if ($category_name === '') {
             $category_name_error_str = wfMessage('sf_blank_error')->text();
         } 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();
     $text = "\t" . '<form action="" method="post">' . "\n";
     $firstRow = '';
     if (is_null($presetCategoryName)) {
         $text .= "\t" . Html::hidden('title', $this->getTitle()->getPrefixedText()) . "\n";
         $firstRow .= wfMessage('sf_createcategory_name')->text() . ' ' . 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" . wfMessage('sf_createcategory_defaultform')->text() . "\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) . "\n";
     $secondRow = wfMessage('sf_createcategory_makesubcategory')->text() . ' ';
     $selectBody = "\t" . Html::element('option', null, null) . "\n";
     $categories = SFUtils::getCategoriesForPage();
     foreach ($categories as $category) {
         $category = str_replace('_', ' ', $category);
         $selectBody .= "\t" . Html::element('option', null, $category) . "\n";
     }
     $secondRow .= Html::rawElement('select', array('id' => 'category_dropdown', 'name' => 'parent_category'), $selectBody);
     $text .= Html::rawElement('p', null, $secondRow) . "\n";
     $text .= "\t" . Html::hidden('csrf', $this->getUser()->getEditToken('CreateCategory')) . "\n";
     $editButtonsText = "\t" . Html::input('wpSave', wfMessage('savearticle')->text(), 'submit', array('id' => 'wpSave')) . "\n";
     $editButtonsText .= "\t" . Html::input('wpPreview', wfMessage('preview')->text(), 'submit', array('id' => 'wpPreview')) . "\n";
     $text .= "\t" . Html::rawElement('div', array('class' => 'editButtons'), $editButtonsText) . "\n";
     $text .= "\t</form>\n";
     $wgOut->addExtensionStyle($sfgScriptPath . "/skins/SemanticForms.css");
     $wgOut->addHTML($text);
 }
    function creationHTML($template_num)
    {
        $field_form_text = $template_num . "_" . $this->mNum;
        $template_field = $this->template_field;
        $text = '<h3>' . wfMessage('sf_createform_field')->escaped() . " '" . $template_field->getFieldName() . "'</h3>\n";
        $prop_link_text = SFUtils::linkText(SMW_NS_PROPERTY, $template_field->getSemanticProperty());
        // TODO - remove this probably-unnecessary check?
        if ($template_field->getSemanticProperty() == "") {
            // Print nothing if there's no semantic property.
        } elseif ($template_field->getPropertyType() == "") {
            $text .= '<p>' . wfMessage('sf_createform_fieldpropunknowntype', $prop_link_text)->parseAsBlock() . "</p>\n";
        } else {
            if ($template_field->isList()) {
                $propDisplayMsg = 'sf_createform_fieldproplist';
            } else {
                $propDisplayMsg = 'sf_createform_fieldprop';
            }
            // Get the display label for this property type.
            global $smwgContLang;
            $propertyTypeStr = '';
            if ($smwgContLang != null) {
                $datatypeLabels = $smwgContLang->getDatatypeLabels();
                $datatypeLabels['enumeration'] = 'enumeration';
                $propTypeID = $template_field->getPropertyType();
                // Special handling for SMW 1.9
                if ($propTypeID == '_str' && !array_key_exists('_str', $datatypeLabels)) {
                    $propTypeID = '_txt';
                }
                $propertyTypeStr = $datatypeLabels[$propTypeID];
            }
            $text .= Html::rawElement('p', null, wfMessage($propDisplayMsg, $prop_link_text, $propertyTypeStr)->parse()) . "\n";
        }
        // If it's not a semantic field - don't add any text.
        $form_label_text = wfMessage('sf_createform_formlabel')->text();
        $form_label_input = Html::input('label_' . $field_form_text, $template_field->getLabel(), 'text', array('size' => 20));
        $input_type_text = wfMessage('sf_createform_inputtype')->escaped();
        $text .= <<<END
\t<div class="formField">
\t<p>{$form_label_text} {$form_label_input}
\t&#160; {$input_type_text}

END;
        global $sfgFormPrinter;
        if (is_null($template_field->getPropertyType())) {
            $default_input_type = null;
            $possible_input_types = $sfgFormPrinter->getAllInputTypes();
        } else {
            $default_input_type = $sfgFormPrinter->getDefaultInputType($template_field->isList(), $template_field->getPropertyType());
            $possible_input_types = $sfgFormPrinter->getPossibleInputTypes($template_field->isList(), $template_field->getPropertyType());
        }
        $text .= $this->inputTypeDropdownHTML($field_form_text, $default_input_type, $possible_input_types, $template_field->getInputType());
        if (!is_null($template_field->getInputType())) {
            $cur_input_type = $template_field->getInputType();
        } elseif (!is_null($default_input_type)) {
            $cur_input_type = $default_input_type;
        } else {
            $cur_input_type = $possible_input_types[0];
        }
        global $wgRequest;
        $paramValues = array();
        foreach ($wgRequest->getValues() as $key => $value) {
            if (($pos = strpos($key, '_' . $field_form_text)) != false) {
                $paramName = substr($key, 0, $pos);
                // Spaces got replaced by underlines in the
                // query.
                $paramName = str_replace('_', ' ', $paramName);
                $paramValues[$paramName] = $value;
            }
        }
        $other_param_text = wfMessage('sf_createform_otherparameters')->escaped();
        $text .= "<fieldset class=\"sfCollapsibleFieldset\"><legend>{$other_param_text}</legend>\n";
        $text .= Html::rawElement('div', array('class' => 'otherInputParams'), SFCreateForm::showInputTypeOptions($cur_input_type, $field_form_text, $paramValues)) . "\n";
        $text .= "</fieldset>\n";
        $text .= <<<END
\t</p>
\t</div>
\t<hr>

END;
        return $text;
    }
	/**
	 * 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( '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 ( $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 === '' ) {
			$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, as of 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 );
			$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
		$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 .= "<legend>$template_label</legend>\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[$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 || ( ! empty( $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 = SFFormUtils::hiddenFieldHTML( '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, '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 = wfMsgExt( 'edittools', array( 'parse' ), array( 'content' ) );

								$new_text .= <<<END
		<div class="mw-editTools">
		$edittools_text
		</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' &&
								// if the date is hidden, cur_value will already be set
								// to the default value
								( $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' &&
							// if the date is hidden, cur_value will already be set
							// to the default value
							( $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 .= SFFormUtils::hiddenFieldHTML( 'free_text', '!free_text!' );
							} else {
								$new_text .= SFFormUtils::hiddenFieldHTML( $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;
		} // 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 .= SFFormUtils::hiddenFieldHTML( '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 .= SFFormUtils::hiddenFieldHTML( '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( '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;
		}
		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 );
		}

		$page_article = new Article( $this->mPageTitle, 0 );

		if ( !$is_query ) {
			$form_text .= SFFormUtils::hiddenFieldHTML( 'wpStarttime', wfTimestampNow() );
			$form_text .= SFFormUtils::hiddenFieldHTML( 'wpEdittime', $page_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 );
	}