r83571 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r83570‎ | r83571 | r83572 >
Date:07:53, 9 March 2011
Author:jeroendedauw
Status:deferred
Tags:
Comment:
made methods explicity public and fixed indenting
Modified paths:
  • /trunk/extensions/SemanticForms/includes/SF_FormPrinter.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticForms/includes/SF_FormPrinter.php
@@ -11,217 +11,217 @@
1212
1313 class SFFormPrinter {
1414
15 - var $mSemanticTypeHooks;
16 - var $mInputTypeHooks;
17 - var $standardInputsIncluded;
18 - var $mPageTitle;
 15+ var $mSemanticTypeHooks;
 16+ var $mInputTypeHooks;
 17+ var $standardInputsIncluded;
 18+ var $mPageTitle;
1919
20 - function __construct() {
21 - global $smwgContLang;
 20+ public function __construct() {
 21+ global $smwgContLang;
2222
23 - // Initialize variables.
24 - $this->mSemanticTypeHooks = array();
25 - $this->mInputTypeHooks = array();
26 - $this->mInputTypeClasses = array();
27 - $this->mDefaultInputForPropType = array();
28 - $this->mDefaultInputForPropTypeList = array();
29 - $this->mPossibleInputsForPropType = array();
30 - $this->mPossibleInputsForPropTypeList = array();
 23+ // Initialize variables.
 24+ $this->mSemanticTypeHooks = array();
 25+ $this->mInputTypeHooks = array();
 26+ $this->mInputTypeClasses = array();
 27+ $this->mDefaultInputForPropType = array();
 28+ $this->mDefaultInputForPropTypeList = array();
 29+ $this->mPossibleInputsForPropType = array();
 30+ $this->mPossibleInputsForPropTypeList = array();
3131
32 - $this->standardInputsIncluded = false;
 32+ $this->standardInputsIncluded = false;
3333
34 - $this->registerInputType( 'SFTextInput' );
35 - $this->registerInputType( 'SFTextWithAutocompleteInput' );
36 - $this->registerInputType( 'SFTextAreaInput' );
37 - $this->registerInputType( 'SFTextAreaWithAutocompleteInput' );
38 - $this->registerInputType( 'SFDateInput' );
39 - $this->registerInputType( 'SFDateTimeInput' );
40 - $this->registerInputType( 'SFYearInput' );
41 - $this->registerInputType( 'SFCheckboxInput' );
42 - $this->registerInputType( 'SFDropdownInput' );
43 - $this->registerInputType( 'SFRadioButtonInput' );
44 - $this->registerInputType( 'SFCheckboxesInput' );
45 - $this->registerInputType( 'SFListBoxInput' );
46 - $this->registerInputType( 'SFComboBoxInput' );
47 - $this->registerInputType( 'SFCategoryInput' );
48 - $this->registerInputType( 'SFCategoriesInput' );
49 - }
 34+ $this->registerInputType( 'SFTextInput' );
 35+ $this->registerInputType( 'SFTextWithAutocompleteInput' );
 36+ $this->registerInputType( 'SFTextAreaInput' );
 37+ $this->registerInputType( 'SFTextAreaWithAutocompleteInput' );
 38+ $this->registerInputType( 'SFDateInput' );
 39+ $this->registerInputType( 'SFDateTimeInput' );
 40+ $this->registerInputType( 'SFYearInput' );
 41+ $this->registerInputType( 'SFCheckboxInput' );
 42+ $this->registerInputType( 'SFDropdownInput' );
 43+ $this->registerInputType( 'SFRadioButtonInput' );
 44+ $this->registerInputType( 'SFCheckboxesInput' );
 45+ $this->registerInputType( 'SFListBoxInput' );
 46+ $this->registerInputType( 'SFComboBoxInput' );
 47+ $this->registerInputType( 'SFCategoryInput' );
 48+ $this->registerInputType( 'SFCategoriesInput' );
 49+ }
5050
51 - function setSemanticTypeHook( $type, $is_list, $function_name, $default_args ) {
52 - $this->mSemanticTypeHooks[$type][$is_list] = array( $function_name, $default_args );
53 - }
 51+ public function setSemanticTypeHook( $type, $is_list, $function_name, $default_args ) {
 52+ $this->mSemanticTypeHooks[$type][$is_list] = array( $function_name, $default_args );
 53+ }
5454
55 - function setInputTypeHook( $input_type, $function_name, $default_args ) {
56 - $this->mInputTypeHooks[$input_type] = array( $function_name, $default_args );
57 - }
 55+ public function setInputTypeHook( $input_type, $function_name, $default_args ) {
 56+ $this->mInputTypeHooks[$input_type] = array( $function_name, $default_args );
 57+ }
5858
59 - /**
60 - * Register all information about the passed-in form input class.
61 - */
62 - function registerInputType( $inputTypeClass ) {
63 - global $smwgContLang;
64 - global $sfgInitJSFunctions, $sfgValidationJSFunctions;
 59+ /**
 60+ * Register all information about the passed-in form input class.
 61+ */
 62+ public function registerInputType( $inputTypeClass ) {
 63+ global $smwgContLang;
 64+ global $sfgInitJSFunctions, $sfgValidationJSFunctions;
6565
66 - $inputTypeName = call_user_func( array( $inputTypeClass, 'getName' ) );
67 - $this->mInputTypeClasses[$inputTypeName] = $inputTypeClass;
68 - $this->setInputTypeHook( $inputTypeName, array( $inputTypeClass, 'getHTML' ), array() );
 66+ $inputTypeName = call_user_func( array( $inputTypeClass, 'getName' ) );
 67+ $this->mInputTypeClasses[$inputTypeName] = $inputTypeClass;
 68+ $this->setInputTypeHook( $inputTypeName, array( $inputTypeClass, 'getHTML' ), array() );
6969
70 - $defaultProperties = call_user_func( array( $inputTypeClass, 'getDefaultPropTypes' ) );
71 - foreach ( $defaultProperties as $propertyTypeID => $additionalValues ) {
72 - if ( $smwgContLang != null ) {
73 - $datatypeLabels = $smwgContLang->getDatatypeLabels();
74 - $datatypeLabels['enumeration'] = 'enumeration';
75 - $propertyType = $datatypeLabels[$propertyTypeID];
76 - $this->setSemanticTypeHook( $propertyType, false, array( $inputTypeClass, 'getHTML' ), $additionalValues );
77 - }
78 - $this->mDefaultInputForPropType[$propertyTypeID] = $inputTypeName;
79 - }
80 - $defaultPropertyLists = call_user_func( array( $inputTypeClass, 'getDefaultPropTypeLists' ) );
81 - foreach ( $defaultPropertyLists as $propertyTypeID => $additionalValues ) {
82 - if ( $smwgContLang != null ) {
83 - $datatypeLabels = $smwgContLang->getDatatypeLabels();
84 - $datatypeLabels['enumeration'] = 'enumeration';
85 - $propertyType = $datatypeLabels[$propertyTypeID];
86 - $this->setSemanticTypeHook( $propertyType, true, array( $inputTypeClass, 'getHTML' ), $additionalValues );
87 - }
88 - $this->mDefaultInputForPropTypeList[$propertyTypeID] = $inputTypeName;
89 - }
 70+ $defaultProperties = call_user_func( array( $inputTypeClass, 'getDefaultPropTypes' ) );
 71+ foreach ( $defaultProperties as $propertyTypeID => $additionalValues ) {
 72+ if ( $smwgContLang != null ) {
 73+ $datatypeLabels = $smwgContLang->getDatatypeLabels();
 74+ $datatypeLabels['enumeration'] = 'enumeration';
 75+ $propertyType = $datatypeLabels[$propertyTypeID];
 76+ $this->setSemanticTypeHook( $propertyType, false, array( $inputTypeClass, 'getHTML' ), $additionalValues );
 77+ }
 78+ $this->mDefaultInputForPropType[$propertyTypeID] = $inputTypeName;
 79+ }
 80+ $defaultPropertyLists = call_user_func( array( $inputTypeClass, 'getDefaultPropTypeLists' ) );
 81+ foreach ( $defaultPropertyLists as $propertyTypeID => $additionalValues ) {
 82+ if ( $smwgContLang != null ) {
 83+ $datatypeLabels = $smwgContLang->getDatatypeLabels();
 84+ $datatypeLabels['enumeration'] = 'enumeration';
 85+ $propertyType = $datatypeLabels[$propertyTypeID];
 86+ $this->setSemanticTypeHook( $propertyType, true, array( $inputTypeClass, 'getHTML' ), $additionalValues );
 87+ }
 88+ $this->mDefaultInputForPropTypeList[$propertyTypeID] = $inputTypeName;
 89+ }
9090
91 - $otherProperties = call_user_func( array( $inputTypeClass, 'getOtherPropTypesHandled' ) );
92 - foreach ( $otherProperties as $propertyTypeID ) {
93 - if ( array_key_exists( $propertyTypeID, $this->mPossibleInputsForPropType ) ) {
94 - $this->mPossibleInputsForPropType[$propertyTypeID][] = $inputTypeName;
95 - } else {
96 - $this->mPossibleInputsForPropType[$propertyTypeID] = array( $inputTypeName );
97 - }
98 - }
99 - $otherPropertyLists = call_user_func( array( $inputTypeClass, 'getOtherPropTypeListsHandled' ) );
100 - foreach ( $otherPropertyLists as $propertyTypeID ) {
101 - if ( array_key_exists( $propertyTypeID, $this->mPossibleInputsForPropTypeList ) ) {
102 - $this->mPossibleInputsForPropTypeList[$propertyTypeID][] = $inputTypeName;
103 - } else {
104 - $this->mPossibleInputsForPropTypeList[$propertyTypeID] = array( $inputTypeName );
105 - }
106 - }
 91+ $otherProperties = call_user_func( array( $inputTypeClass, 'getOtherPropTypesHandled' ) );
 92+ foreach ( $otherProperties as $propertyTypeID ) {
 93+ if ( array_key_exists( $propertyTypeID, $this->mPossibleInputsForPropType ) ) {
 94+ $this->mPossibleInputsForPropType[$propertyTypeID][] = $inputTypeName;
 95+ } else {
 96+ $this->mPossibleInputsForPropType[$propertyTypeID] = array( $inputTypeName );
 97+ }
 98+ }
 99+ $otherPropertyLists = call_user_func( array( $inputTypeClass, 'getOtherPropTypeListsHandled' ) );
 100+ foreach ( $otherPropertyLists as $propertyTypeID ) {
 101+ if ( array_key_exists( $propertyTypeID, $this->mPossibleInputsForPropTypeList ) ) {
 102+ $this->mPossibleInputsForPropTypeList[$propertyTypeID][] = $inputTypeName;
 103+ } else {
 104+ $this->mPossibleInputsForPropTypeList[$propertyTypeID] = array( $inputTypeName );
 105+ }
 106+ }
107107
108 - $initJSFunction = call_user_func( array( $inputTypeClass, 'getInitJSFunction' ) );
109 - if ( !is_null( $initJSFunction ) ) {
110 - $sfgInitJSFunctions[] = $initJSFunction;
111 - }
112 - $validationJSFunctions = call_user_func( array( $inputTypeClass, 'getValidationJSFunctions' ) );
113 - if ( count( $validationJSFunctions ) > 0 ) {
114 - $sfgValidationJSFunctions = array_merge( $sfgValidationJSFunctions, $initJSFunction );
115 - }
116 - }
 108+ $initJSFunction = call_user_func( array( $inputTypeClass, 'getInitJSFunction' ) );
 109+ if ( !is_null( $initJSFunction ) ) {
 110+ $sfgInitJSFunctions[] = $initJSFunction;
 111+ }
 112+ $validationJSFunctions = call_user_func( array( $inputTypeClass, 'getValidationJSFunctions' ) );
 113+ if ( count( $validationJSFunctions ) > 0 ) {
 114+ $sfgValidationJSFunctions = array_merge( $sfgValidationJSFunctions, $initJSFunction );
 115+ }
 116+ }
117117
118 - function getInputType( $inputTypeName ) {
119 - if ( array_key_exists( $inputTypeName, $this->mInputTypeClasses ) ) {
120 - return $this->mInputTypeClasses[$inputTypeName];
121 - } else {
122 - return null;
123 - }
124 - }
 118+ public function getInputType( $inputTypeName ) {
 119+ if ( array_key_exists( $inputTypeName, $this->mInputTypeClasses ) ) {
 120+ return $this->mInputTypeClasses[$inputTypeName];
 121+ } else {
 122+ return null;
 123+ }
 124+ }
125125
126 - public function getDefaultInputType( $isList, $propertyType ) {
127 - if ( $isList ) {
128 - return $this->mDefaultInputForPropTypeList[$propertyType];
129 - } else {
130 - return $this->mDefaultInputForPropType[$propertyType];
131 - }
132 - }
 126+ public function getDefaultInputType( $isList, $propertyType ) {
 127+ if ( $isList ) {
 128+ return $this->mDefaultInputForPropTypeList[$propertyType];
 129+ } else {
 130+ return $this->mDefaultInputForPropType[$propertyType];
 131+ }
 132+ }
133133
134 - public function getPossibleInputTypes( $isList, $propertyType ) {
135 - if ( $isList ) {
136 - if ( array_key_exists( $propertyType, $this->mPossibleInputsForPropTypeList ) ) {
137 - return $this->mPossibleInputsForPropTypeList[$propertyType];
138 - } else {
139 - return array();
140 - }
141 - } else {
142 - if ( array_key_exists( $propertyType, $this->mPossibleInputsForPropType ) ) {
143 - return $this->mPossibleInputsForPropType[$propertyType];
144 - } else {
145 - return array();
146 - }
147 - }
148 - }
 134+ public function getPossibleInputTypes( $isList, $propertyType ) {
 135+ if ( $isList ) {
 136+ if ( array_key_exists( $propertyType, $this->mPossibleInputsForPropTypeList ) ) {
 137+ return $this->mPossibleInputsForPropTypeList[$propertyType];
 138+ } else {
 139+ return array();
 140+ }
 141+ } else {
 142+ if ( array_key_exists( $propertyType, $this->mPossibleInputsForPropType ) ) {
 143+ return $this->mPossibleInputsForPropType[$propertyType];
 144+ } else {
 145+ return array();
 146+ }
 147+ }
 148+ }
149149
150 - public function getAllInputTypes() {
151 - return array_keys( $this->mInputTypeClasses );
152 - }
 150+ public function getAllInputTypes() {
 151+ return array_keys( $this->mInputTypeClasses );
 152+ }
153153
154 - /**
155 - * Show the set of previous deletions for the page being added.
156 - * This function is copied almost exactly from EditPage::showDeletionLog() -
157 - * unfortunately, neither that function nor Article::showDeletionLog() can
158 - * be called from here, since they're both protected
159 - */
160 - function showDeletionLog( $out ) {
161 - // if MW doesn't have LogEventsList defined, exit immediately
162 - if ( ! class_exists( 'LogEventsList' ) )
163 - return false;
 154+ /**
 155+ * Show the set of previous deletions for the page being added.
 156+ * This function is copied almost exactly from EditPage::showDeletionLog() -
 157+ * unfortunately, neither that function nor Article::showDeletionLog() can
 158+ * be called from here, since they're both protected
 159+ */
 160+ function showDeletionLog( $out ) {
 161+ // if MW doesn't have LogEventsList defined, exit immediately
 162+ if ( ! class_exists( 'LogEventsList' ) )
 163+ return false;
164164
165 - global $wgUser;
166 - $loglist = new LogEventsList( $wgUser->getSkin(), $out );
167 - $pager = new LogPager( $loglist, 'delete', false, $this->mPageTitle->getPrefixedText() );
168 - $count = $pager->getNumRows();
169 - if ( $count > 0 ) {
170 - $pager->mLimit = 10;
171 - $out->addHTML( '<div class="mw-warning-with-logexcerpt">' );
172 - // the message name changed in MW 1.16
173 - if ( ! wfEmptyMsg( 'moveddeleted-notice', wfMsg( 'moveddeleted-notice' ) ) )
174 - $out->addWikiMsg( 'moveddeleted-notice' );
175 - else
176 - $out->addWikiMsg( 'recreate-deleted-warn' );
177 - $out->addHTML(
178 - $loglist->beginLogEventsList() .
179 - $pager->getBody() .
180 - $loglist->endLogEventsList()
181 - );
182 - if ( $count > 10 ) {
183 - $out->addHTML( $wgUser->getSkin()->link(
184 - SpecialPage::getTitleFor( 'Log' ),
185 - wfMsgHtml( 'deletelog-fulllog' ),
186 - array(),
187 - array(
188 - 'type' => 'delete',
189 - 'page' => $this->mPageTitle->getPrefixedText() ) ) );
190 - }
191 - $out->addHTML( '</div>' );
192 - return true;
193 - }
 165+ global $wgUser;
 166+ $loglist = new LogEventsList( $wgUser->getSkin(), $out );
 167+ $pager = new LogPager( $loglist, 'delete', false, $this->mPageTitle->getPrefixedText() );
 168+ $count = $pager->getNumRows();
 169+ if ( $count > 0 ) {
 170+ $pager->mLimit = 10;
 171+ $out->addHTML( '<div class="mw-warning-with-logexcerpt">' );
 172+ // the message name changed in MW 1.16
 173+ if ( ! wfEmptyMsg( 'moveddeleted-notice', wfMsg( 'moveddeleted-notice' ) ) )
 174+ $out->addWikiMsg( 'moveddeleted-notice' );
 175+ else
 176+ $out->addWikiMsg( 'recreate-deleted-warn' );
 177+ $out->addHTML(
 178+ $loglist->beginLogEventsList() .
 179+ $pager->getBody() .
 180+ $loglist->endLogEventsList()
 181+ );
 182+ if ( $count > 10 ) {
 183+ $out->addHTML( $wgUser->getSkin()->link(
 184+ SpecialPage::getTitleFor( 'Log' ),
 185+ wfMsgHtml( 'deletelog-fulllog' ),
 186+ array(),
 187+ array(
 188+ 'type' => 'delete',
 189+ 'page' => $this->mPageTitle->getPrefixedText() ) ) );
 190+ }
 191+ $out->addHTML( '</div>' );
 192+ return true;
 193+ }
194194
195 - return false;
196 - }
 195+ return false;
 196+ }
197197
198 - /**
199 - * Like PHP's str_replace(), but only replaces the first found instance -
200 - * unfortunately, str_replace() doesn't allow for that.
201 - * This code is basically copied directly from
202 - * http://www.php.net/manual/en/function.str-replace.php#86177
203 - * - this might make sense in the SFUtils class, if it's useful in
204 - * other places.
205 - */
206 - function strReplaceFirst( $search, $replace, $subject) {
207 - $firstChar = strpos( $subject, $search );
208 - if ( $firstChar !== false ) {
209 - $beforeStr = substr( $subject, 0, $firstChar );
210 - $afterStr = substr( $subject, $firstChar + strlen( $search ) );
211 - return $beforeStr . $replace . $afterStr;
212 - } else {
213 - return $subject;
214 - }
215 - }
 198+ /**
 199+ * Like PHP's str_replace(), but only replaces the first found instance -
 200+ * unfortunately, str_replace() doesn't allow for that.
 201+ * This code is basically copied directly from
 202+ * http://www.php.net/manual/en/function.str-replace.php#86177
 203+ * - this might make sense in the SFUtils class, if it's useful in
 204+ * other places.
 205+ */
 206+ function strReplaceFirst( $search, $replace, $subject) {
 207+ $firstChar = strpos( $subject, $search );
 208+ if ( $firstChar !== false ) {
 209+ $beforeStr = substr( $subject, 0, $firstChar );
 210+ $afterStr = substr( $subject, $firstChar + strlen( $search ) );
 211+ return $beforeStr . $replace . $afterStr;
 212+ } else {
 213+ return $subject;
 214+ }
 215+ }
216216
217 - /**
218 - * Creates the HTML for the inner table for every instance of a
219 - * multiple-instance template in the form.
220 - */
221 - function multipleTemplateInstanceTableHTML( $mainText ) {
222 - global $sfgTabIndex, $sfgScriptPath;
 217+ /**
 218+ * Creates the HTML for the inner table for every instance of a
 219+ * multiple-instance template in the form.
 220+ */
 221+ function multipleTemplateInstanceTableHTML( $mainText ) {
 222+ global $sfgTabIndex, $sfgScriptPath;
223223
224 - $remove_text = wfMsg( 'sf_formedit_remove' );
225 - $text =<<<END
 224+ $remove_text = wfMsg( 'sf_formedit_remove' );
 225+ $text =<<<END
226226
227227 <table>
228228 <tr>
@@ -239,1222 +239,1222 @@
240240
241241 END;
242242
243 - return $text;
244 - }
 243+ return $text;
 244+ }
245245
246 - /**
247 - * This function is the real heart of the entire Semantic Forms
248 - * extension. It handles two main actions: (1) displaying a form on the
249 - * screen, given a form definition and possibly page contents (if an
250 - * existing page is being edited); and (2) creating actual page contents,
251 - * if the form was already submitted by the user.
252 - *
253 - * It also does some related tasks, like figuring out the page name (if
254 - * only a page formula exists).
255 - */
256 - 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, $embedded = false ) {
257 - global $wgRequest, $wgUser, $wgParser;
258 - global $sfgTabIndex; // used to represent the current tab index in the form
259 - global $sfgFieldNum; // used for setting various HTML IDs
 246+ /**
 247+ * This function is the real heart of the entire Semantic Forms
 248+ * extension. It handles two main actions: (1) displaying a form on the
 249+ * screen, given a form definition and possibly page contents (if an
 250+ * existing page is being edited); and (2) creating actual page contents,
 251+ * if the form was already submitted by the user.
 252+ *
 253+ * It also does some related tasks, like figuring out the page name (if
 254+ * only a page formula exists).
 255+ */
 256+ 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, $embedded = false ) {
 257+ global $wgRequest, $wgUser, $wgParser;
 258+ global $sfgTabIndex; // used to represent the current tab index in the form
 259+ global $sfgFieldNum; // used for setting various HTML IDs
260260
261 - // initialize some variables
262 - $sfgTabIndex = 1;
263 - $sfgFieldNum = 1;
264 - $source_page_matches_this_form = false;
265 - $form_page_title = NULL;
266 - $generated_page_name = $page_name_formula;
267 - // $form_is_partial is true if:
268 - // (a) 'partial' == 1 in the arguments
269 - // (b) 'partial form' is found in the form definition
270 - // in the latter case, it may remain false until close to the end of
271 - // the parsing, so we have to assume that it will become a possibility
272 - $form_is_partial = false;
273 - $new_text = "";
274 - // flag for placing "<onlyinclude>" tags in form output
275 - $onlyinclude_free_text = false;
276 -
277 - // If we have existing content and we're not in an active replacement
278 - // situation, preserve the original content. We do this because we want
279 - // to pass the original content on IF this is a partial form.
280 - // TODO: A better approach here would be to pass the revision id of the
281 - // existing page content through the replace value, which would
282 - // minimize the html traffic and would allow us to do a concurrent
283 - // update check. For now, we pass it through the hidden text field...
 261+ // initialize some variables
 262+ $sfgTabIndex = 1;
 263+ $sfgFieldNum = 1;
 264+ $source_page_matches_this_form = false;
 265+ $form_page_title = NULL;
 266+ $generated_page_name = $page_name_formula;
 267+ // $form_is_partial is true if:
 268+ // (a) 'partial' == 1 in the arguments
 269+ // (b) 'partial form' is found in the form definition
 270+ // in the latter case, it may remain false until close to the end of
 271+ // the parsing, so we have to assume that it will become a possibility
 272+ $form_is_partial = false;
 273+ $new_text = "";
 274+ // flag for placing "<onlyinclude>" tags in form output
 275+ $onlyinclude_free_text = false;
 276+
 277+ // If we have existing content and we're not in an active replacement
 278+ // situation, preserve the original content. We do this because we want
 279+ // to pass the original content on IF this is a partial form.
 280+ // TODO: A better approach here would be to pass the revision id of the
 281+ // existing page content through the replace value, which would
 282+ // minimize the html traffic and would allow us to do a concurrent
 283+ // update check. For now, we pass it through the hidden text field...
284284
285 - if ( ! $wgRequest->getCheck( 'partial' ) ) {
286 - $original_page_content = $existing_page_content;
287 - } else {
288 - $original_page_content = null;
289 - if ( $wgRequest->getCheck( 'free_text' ) ) {
290 - $existing_page_content = $wgRequest->getVal( 'free_text' );
291 - $form_is_partial = true;
292 - }
293 - }
 285+ if ( ! $wgRequest->getCheck( 'partial' ) ) {
 286+ $original_page_content = $existing_page_content;
 287+ } else {
 288+ $original_page_content = null;
 289+ if ( $wgRequest->getCheck( 'free_text' ) ) {
 290+ $existing_page_content = $wgRequest->getVal( 'free_text' );
 291+ $form_is_partial = true;
 292+ }
 293+ }
294294
295 - // Disable all form elements if user doesn't have edit permission -
296 - // two different checks are needed, because editing permissions can be
297 - // set in different ways.
298 - // HACK - sometimes we don't know the page name in advance, but we still
299 - // need to set a title here for testing permissions
300 - if ( $embedded ) {
301 - // if this is an embedded form (probably a 'RunQuery'), just use the
302 - // name of the actual page we're on
303 - global $wgTitle;
304 - $this->mPageTitle = $wgTitle;
305 - } elseif ( $page_name == '' ) {
306 - $this->mPageTitle = Title::newFromText(
307 - $wgRequest->getVal( 'namespace' ) . ":Semantic Forms permissions test" );
308 - } else {
309 - $this->mPageTitle = Title::newFromText( $page_name );
310 - }
 295+ // Disable all form elements if user doesn't have edit permission -
 296+ // two different checks are needed, because editing permissions can be
 297+ // set in different ways.
 298+ // HACK - sometimes we don't know the page name in advance, but we still
 299+ // need to set a title here for testing permissions
 300+ if ( $embedded ) {
 301+ // if this is an embedded form (probably a 'RunQuery'), just use the
 302+ // name of the actual page we're on
 303+ global $wgTitle;
 304+ $this->mPageTitle = $wgTitle;
 305+ } elseif ( $page_name == '' ) {
 306+ $this->mPageTitle = Title::newFromText(
 307+ $wgRequest->getVal( 'namespace' ) . ":Semantic Forms permissions test" );
 308+ } else {
 309+ $this->mPageTitle = Title::newFromText( $page_name );
 310+ }
311311
312 - global $wgOut;
313 - // show previous set of deletions for this page, if it's been deleted before
314 - if ( ! $form_submitted && ! $this->mPageTitle->exists() ) {
315 - $this->showDeletionLog( $wgOut );
316 - }
317 - // Unfortunately, we can't just call userCan() here because, as of MW 1.16,
318 - // it has a bug in which it ignores a setting of
319 - // "$wgEmailConfirmToEdit = true;". Instead, we'll just get the
320 - // permission errors from the start, and use those to determine whether
321 - // the page is editable.
322 - //$userCanEditPage = ( $wgUser->isAllowed( 'edit' ) && $this->mPageTitle->userCan( 'edit' ) );
323 - $permissionErrors = $this->mPageTitle->getUserPermissionsErrors( 'edit', $wgUser );
324 - $userCanEditPage = count( $permissionErrors ) == 0;
325 - wfRunHooks( 'sfUserCanEditPage', array( &$userCanEditPage ) );
326 - $form_text = "";
327 - if ( $userCanEditPage || $is_query ) {
328 - $form_is_disabled = false;
329 - // Show "Your IP address will be recorded" warning if user is
330 - // anonymous, and it's not a query -
331 - // wiki-text for bolding has to be replaced with HTML.
332 - if ( $wgUser->isAnon() && ! $is_query ) {
333 - $anon_edit_warning = preg_replace( "/'''(.*)'''/", "<strong>$1</strong>", wfMsg( 'anoneditwarning' ) );
334 - $form_text .= "<p>$anon_edit_warning</p>\n";
335 - }
336 - } else {
337 - $form_is_disabled = true;
338 - $wgOut->readOnlyPage( null, false, $permissionErrors, 'edit' );
339 - $wgOut->addHTML( "\n<hr />\n" );
340 - }
 312+ global $wgOut;
 313+ // show previous set of deletions for this page, if it's been deleted before
 314+ if ( ! $form_submitted && ! $this->mPageTitle->exists() ) {
 315+ $this->showDeletionLog( $wgOut );
 316+ }
 317+ // Unfortunately, we can't just call userCan() here because, as of MW 1.16,
 318+ // it has a bug in which it ignores a setting of
 319+ // "$wgEmailConfirmToEdit = true;". Instead, we'll just get the
 320+ // permission errors from the start, and use those to determine whether
 321+ // the page is editable.
 322+ //$userCanEditPage = ( $wgUser->isAllowed( 'edit' ) && $this->mPageTitle->userCan( 'edit' ) );
 323+ $permissionErrors = $this->mPageTitle->getUserPermissionsErrors( 'edit', $wgUser );
 324+ $userCanEditPage = count( $permissionErrors ) == 0;
 325+ wfRunHooks( 'sfUserCanEditPage', array( &$userCanEditPage ) );
 326+ $form_text = "";
 327+ if ( $userCanEditPage || $is_query ) {
 328+ $form_is_disabled = false;
 329+ // Show "Your IP address will be recorded" warning if user is
 330+ // anonymous, and it's not a query -
 331+ // wiki-text for bolding has to be replaced with HTML.
 332+ if ( $wgUser->isAnon() && ! $is_query ) {
 333+ $anon_edit_warning = preg_replace( "/'''(.*)'''/", "<strong>$1</strong>", wfMsg( 'anoneditwarning' ) );
 334+ $form_text .= "<p>$anon_edit_warning</p>\n";
 335+ }
 336+ } else {
 337+ $form_is_disabled = true;
 338+ $wgOut->readOnlyPage( null, false, $permissionErrors, 'edit' );
 339+ $wgOut->addHTML( "\n<hr />\n" );
 340+ }
341341
342 - // Remove <noinclude> sections and <includeonly> tags from form definition.
343 - $form_def = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $form_def );
344 - $form_def = strtr( $form_def, array( '<includeonly>' => '', '</includeonly>' => '' ) );
 342+ // Remove <noinclude> sections and <includeonly> tags from form definition.
 343+ $form_def = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $form_def );
 344+ $form_def = strtr( $form_def, array( '<includeonly>' => '', '</includeonly>' => '' ) );
345345
346 - // Parse wiki-text.
347 - // Add '<nowiki>' tags around every triple-bracketed form definition
348 - // element, so that the wiki parser won't touch it - the parser will
349 - // remove the '<nowiki>' tags, leaving us with what we need.
350 - $form_def = "__NOEDITSECTION__" . strtr( $form_def, array( '{{{' => '<nowiki>{{{', '}}}' => '}}}</nowiki>' ) );
351 - if ( empty( $wgParser->mOptions ) ) {
352 - $wgParser->mOptions = new ParserOptions();
353 - }
 346+ // Parse wiki-text.
 347+ // Add '<nowiki>' tags around every triple-bracketed form definition
 348+ // element, so that the wiki parser won't touch it - the parser will
 349+ // remove the '<nowiki>' tags, leaving us with what we need.
 350+ $form_def = "__NOEDITSECTION__" . strtr( $form_def, array( '{{{' => '<nowiki>{{{', '}}}' => '}}}</nowiki>' ) );
 351+ if ( empty( $wgParser->mOptions ) ) {
 352+ $wgParser->mOptions = new ParserOptions();
 353+ }
354354
355 - // Get the form definition from the cache, if we're using caching and it's
356 - // there.
357 - $got_form_def_from_cache = false;
358 - global $sfgCacheFormDefinitions;
359 - if ( $sfgCacheFormDefinitions && ! is_null( $form_id ) ) {
360 - $db = wfGetDB( DB_MASTER );
361 - $res = $db->select( 'page_props', 'pp_value', "pp_propname = 'formdefinition' AND pp_page = '$form_id'" );
362 - if ( $res->numRows() > 0 ) {
363 - $form_def = $res->fetchObject()->pp_value;
364 - $got_form_def_from_cache = true;
365 - }
366 - }
367 - // Otherwise, parse it.
368 - if ( ! $got_form_def_from_cache ) {
369 - if ( $embedded) {
370 - $form_def = $wgParser->recursiveTagParse( $form_def );
371 - $form_def = $wgParser->mStripState->unstripBoth( $form_def );
372 - } else {
373 - $form_def = $wgParser->parse( $form_def, $this->mPageTitle, $wgParser->mOptions )->getText();
374 - }
375 - }
376 -
377 - // Turn form definition file into an array of sections, one for each
378 - // template definition (plus the first section)
379 - $form_def_sections = array();
380 - $start_position = 0;
381 - $section_start = 0;
382 - $free_text_was_included = false;
383 - $free_text_preload_page = null;
384 - $free_text_components = array();
385 - $all_values_for_template = array();
386 - // Unencode any HTML-encoded representations of curly brackets and
387 - // pipes - this is a hack to allow for forms to include templates
388 - // that themselves contain form elements - the escaping was needed
389 - // to make sure that those elements don't get parsed too early.
390 - $form_def = str_replace( array( '&#123;', '&#124;', '&#125;' ), array( '{', '|', '}' ), $form_def );
391 - // And another hack - replace the 'free text' standard input with
392 - // a field declaration to get it to be handled as a field.
393 - $form_def = str_replace( 'standard input|free text', 'field|<freetext>', $form_def );
394 - while ( $brackets_loc = strpos( $form_def, "{{{", $start_position ) ) {
395 - $brackets_end_loc = strpos( $form_def, "}}}", $brackets_loc );
396 - $bracketed_string = substr( $form_def, $brackets_loc + 3, $brackets_end_loc - ( $brackets_loc + 3 ) );
397 - $tag_components = SFUtils::getFormTagComponents( $bracketed_string );
398 - $tag_title = trim( $tag_components[0] );
399 - if ( $tag_title == 'for template' || $tag_title == 'end template' ) {
400 - // Create a section for everything up to here
401 - $section = substr( $form_def, $section_start, $brackets_loc - $section_start );
402 - $form_def_sections[] = $section;
403 - $section_start = $brackets_loc;
404 - }
405 - $start_position = $brackets_loc + 1;
406 - } // end while
407 - $form_def_sections[] = trim( substr( $form_def, $section_start ) );
 355+ // Get the form definition from the cache, if we're using caching and it's
 356+ // there.
 357+ $got_form_def_from_cache = false;
 358+ global $sfgCacheFormDefinitions;
 359+ if ( $sfgCacheFormDefinitions && ! is_null( $form_id ) ) {
 360+ $db = wfGetDB( DB_MASTER );
 361+ $res = $db->select( 'page_props', 'pp_value', "pp_propname = 'formdefinition' AND pp_page = '$form_id'" );
 362+ if ( $res->numRows() > 0 ) {
 363+ $form_def = $res->fetchObject()->pp_value;
 364+ $got_form_def_from_cache = true;
 365+ }
 366+ }
 367+ // Otherwise, parse it.
 368+ if ( ! $got_form_def_from_cache ) {
 369+ if ( $embedded) {
 370+ $form_def = $wgParser->recursiveTagParse( $form_def );
 371+ $form_def = $wgParser->mStripState->unstripBoth( $form_def );
 372+ } else {
 373+ $form_def = $wgParser->parse( $form_def, $this->mPageTitle, $wgParser->mOptions )->getText();
 374+ }
 375+ }
 376+
 377+ // Turn form definition file into an array of sections, one for each
 378+ // template definition (plus the first section)
 379+ $form_def_sections = array();
 380+ $start_position = 0;
 381+ $section_start = 0;
 382+ $free_text_was_included = false;
 383+ $free_text_preload_page = null;
 384+ $free_text_components = array();
 385+ $all_values_for_template = array();
 386+ // Unencode any HTML-encoded representations of curly brackets and
 387+ // pipes - this is a hack to allow for forms to include templates
 388+ // that themselves contain form elements - the escaping was needed
 389+ // to make sure that those elements don't get parsed too early.
 390+ $form_def = str_replace( array( '&#123;', '&#124;', '&#125;' ), array( '{', '|', '}' ), $form_def );
 391+ // And another hack - replace the 'free text' standard input with
 392+ // a field declaration to get it to be handled as a field.
 393+ $form_def = str_replace( 'standard input|free text', 'field|<freetext>', $form_def );
 394+ while ( $brackets_loc = strpos( $form_def, "{{{", $start_position ) ) {
 395+ $brackets_end_loc = strpos( $form_def, "}}}", $brackets_loc );
 396+ $bracketed_string = substr( $form_def, $brackets_loc + 3, $brackets_end_loc - ( $brackets_loc + 3 ) );
 397+ $tag_components = SFUtils::getFormTagComponents( $bracketed_string );
 398+ $tag_title = trim( $tag_components[0] );
 399+ if ( $tag_title == 'for template' || $tag_title == 'end template' ) {
 400+ // Create a section for everything up to here
 401+ $section = substr( $form_def, $section_start, $brackets_loc - $section_start );
 402+ $form_def_sections[] = $section;
 403+ $section_start = $brackets_loc;
 404+ }
 405+ $start_position = $brackets_loc + 1;
 406+ } // end while
 407+ $form_def_sections[] = trim( substr( $form_def, $section_start ) );
408408
409 - // Cycle through form definition file (and possibly an existing article
410 - // as well), finding template and field declarations and replacing them
411 - // with form elements, either blank or pre-populated, as appropriate.
412 - $all_fields = array();
413 - $data_text = "";
414 - $template_name = "";
415 - $allow_multiple = false;
416 - $instance_num = 0;
417 - $all_instances_printed = false;
418 - $strict_parsing = false;
419 - for ( $section_num = 0; $section_num < count( $form_def_sections ); $section_num++ ) {
420 - $tif = new SFTemplateInForm();
421 - $start_position = 0;
422 - $template_text = "";
423 - // the append is there to ensure that the original array doesn't get
424 - // modified; is it necessary?
425 - $section = " " . $form_def_sections[$section_num];
 409+ // Cycle through form definition file (and possibly an existing article
 410+ // as well), finding template and field declarations and replacing them
 411+ // with form elements, either blank or pre-populated, as appropriate.
 412+ $all_fields = array();
 413+ $data_text = "";
 414+ $template_name = "";
 415+ $allow_multiple = false;
 416+ $instance_num = 0;
 417+ $all_instances_printed = false;
 418+ $strict_parsing = false;
 419+ for ( $section_num = 0; $section_num < count( $form_def_sections ); $section_num++ ) {
 420+ $tif = new SFTemplateInForm();
 421+ $start_position = 0;
 422+ $template_text = "";
 423+ // the append is there to ensure that the original array doesn't get
 424+ // modified; is it necessary?
 425+ $section = " " . $form_def_sections[$section_num];
426426
427 - while ( $brackets_loc = strpos( $section, '{{{', $start_position ) ) {
428 - $brackets_end_loc = strpos( $section, "}}}", $brackets_loc );
429 - $bracketed_string = substr( $section, $brackets_loc + 3, $brackets_end_loc - ( $brackets_loc + 3 ) );
430 - $tag_components = SFUtils::getFormTagComponents( $bracketed_string );
431 - $tag_title = trim( $tag_components[0] );
432 - // =====================================================
433 - // for template processing
434 - // =====================================================
435 - if ( $tag_title == 'for template' ) {
436 - $old_template_name = $template_name;
437 - $template_name = trim( $tag_components[1] );
438 - $tif->template_name = $template_name;
439 - $query_template_name = str_replace( ' ', '_', $template_name );
440 - $add_button_text = wfMsg( 'sf_formedit_addanother' );
441 - // Also replace periods with underlines, since that's what
442 - // POST does to strings anyway.
443 - $query_template_name = str_replace( '.', '_', $query_template_name );
444 - // Cycle through the other components.
445 - for ( $i = 2; $i < count( $tag_components ); $i++ ) {
446 - $component = $tag_components[$i];
447 - if ( $component == 'multiple' ) $allow_multiple = true;
448 - if ( $component == 'strict' ) $strict_parsing = true;
449 - $sub_components = explode( '=', $component, 2 );
450 - if ( count( $sub_components ) == 2 ) {
451 - if ( $sub_components[0] == 'label' ) {
452 - $template_label = $sub_components[1];
453 - } elseif ( $sub_components[0] == 'add button text' ) {
454 - $add_button_text = $sub_components[1];
455 - }
456 - }
457 - }
458 - // If this is the first instance, add the label into the form, if
459 - // there is one, and add the appropriate wrapper div, if this is
460 - // a multiple-instance template.
461 - if ( $old_template_name != $template_name ) {
462 - if ( isset( $template_label ) ) {
463 - $form_text .= "<fieldset>\n";
464 - $form_text .= "<legend>$template_label</legend>\n";
465 - }
466 - if ($allow_multiple) {
467 - $form_text .= "\t" . '<div class="multipleTemplateWrapper">' . "\n";
468 - $form_text .= "\t" . '<div class="multipleTemplateList">' . "\n";
469 - }
470 - }
471 - $template_text .= "{{" . $tif->template_name;
472 - $all_fields = $tif->getAllFields();
473 - // remove template tag
474 - $section = substr_replace( $section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
475 - $template_instance_query_values = $wgRequest->getArray( $query_template_name );
476 - // If we are editing a page, and this template can be found more than
477 - // once in that page, and multiple values are allowed, repeat this
478 - // section.
479 - $existing_template_text = null;
480 - if ( $source_is_page || $form_is_partial ) {
481 - // Replace underlines with spaces in template name, to allow for
482 - // searching on either.
483 - $search_template_str = str_replace( '_', ' ', $tif->template_name );
484 - $preg_match_template_str = str_replace(
485 - array( '/', '(', ')' ),
486 - array( '\/', '\(', '\)' ),
487 - $search_template_str );
488 - $found_instance = preg_match( '/{{' . $preg_match_template_str . '\s*[\|}]/i', str_replace( '_', ' ', $existing_page_content ) );
489 - if ( $allow_multiple ) {
490 - // find instances of this template in the page -
491 - // if there's at least one, re-parse this section of the
492 - // definition form for the subsequent template instances in
493 - // this page; if there's none, don't include fields at all.
494 - // there has to be a more efficient way to handle multiple
495 - // instances of templates, one that doesn't involve re-parsing
496 - // the same tags, but I don't know what it is.
497 - if ( $found_instance ) {
498 - $instance_num++;
499 - } else {
500 - $all_instances_printed = true;
501 - }
502 - }
503 - // get the first instance of this template on the page being edited,
504 - // even if there are more
505 - if ( $found_instance ) {
506 - $matches = array();
507 - $search_pattern = '/{{' . $preg_match_template_str . '\s*[\|}]/i';
508 - $content_str = str_replace( '_', ' ', $existing_page_content );
509 - preg_match($search_pattern, $content_str, $matches, PREG_OFFSET_CAPTURE);
510 - // is this check necessary?
511 - if ( array_key_exists( 0, $matches ) && array_key_exists( 1, $matches[0] ) ) {
512 - $start_char = $matches[0][1];
513 - $fields_start_char = $start_char + 2 + strlen( $search_template_str );
514 - // Skip ahead to the first real character.
515 - while ( in_array( $existing_page_content[$fields_start_char], array( ' ', '\n' ) ) ) {
516 - $fields_start_char++;
517 - }
518 - // If the next character is a pipe, skip that too.
519 - if( $existing_page_content[$fields_start_char] == '|' ) {
520 - $fields_start_char++;
521 - }
522 - $template_contents = array( '0' => '' );
523 - // Cycle through template call, splitting it up by pipes ('|'),
524 - // except when that pipe is part of a piped link.
525 - $field = "";
526 - $uncompleted_square_brackets = 0;
527 - $uncompleted_curly_brackets = 2;
528 - $template_ended = false;
529 - for ( $i = $fields_start_char; ! $template_ended && ( $i < strlen( $existing_page_content ) ); $i++ ) {
530 - $c = $existing_page_content[$i];
531 - if ( $c == '[' ) {
532 - $uncompleted_square_brackets++;
533 - } elseif ( $c == ']' && $uncompleted_square_brackets > 0 ) {
534 - $uncompleted_square_brackets--;
535 - } elseif ( $c == '{' ) {
536 - $uncompleted_curly_brackets++;
537 - } elseif ( $c == '}' && $uncompleted_curly_brackets > 0 ) {
538 - $uncompleted_curly_brackets--;
539 - }
540 - // handle an end to a field and/or template declaration
541 - $template_ended = ( $uncompleted_curly_brackets == 0 && $uncompleted_square_brackets == 0 );
542 - $field_ended = ( $c == '|' && $uncompleted_square_brackets == 0 && $uncompleted_curly_brackets <= 2 );
543 - if ( $template_ended || $field_ended ) {
544 - // if this was the last character in the template, remove
545 - // the closing curly brackets
546 - if ( $template_ended ) {
547 - $field = substr( $field, 0, - 1 );
548 - }
549 - // either there's an equals sign near the beginning or not -
550 - // handling is similar in either way; if there's no equals
551 - // sign, the index of this field becomes the key
552 - $sub_fields = explode( '=', $field, 2 );
553 - if ( count( $sub_fields ) > 1 ) {
554 - $template_contents[trim( $sub_fields[0] )] = trim( $sub_fields[1] );
555 - } else {
556 - $template_contents[] = trim( $sub_fields[0] );
557 - }
558 - $field = '';
559 - } else {
560 - $field .= $c;
561 - }
562 - }
563 - $existing_template_text = substr( $existing_page_content, $start_char, $i - $start_char );
564 - // now remove this template from the text being edited
565 - // if this is a partial form, establish a new insertion point
566 - if ( $existing_page_content && $form_is_partial && $wgRequest->getCheck( 'partial' ) ) {
567 - // if something already exists, set the new insertion point
568 - // to its position; otherwise just let it lie
569 - if ( strpos( $existing_page_content, $existing_template_text ) !== false ) {
570 - $existing_page_content = str_replace( '{{{insertionpoint}}}', '', $existing_page_content );
571 - $existing_page_content = str_replace( $existing_template_text, '{{{insertionpoint}}}', $existing_page_content );
572 - }
573 - } else {
574 - $existing_page_content = self::strReplaceFirst( $existing_template_text, '', $existing_page_content );
575 - }
576 - // If this is not a multiple-instance template, and we've found
577 - // a match in the source page, there's a good chance that this
578 - // page was created with this form - note that, so we don't
579 - // send the user a warning
580 - // (multiple-instance templates have a greater chance of
581 - // getting repeated from one form to the next)
582 - // - on second thought, allow even the presence of multiple-
583 - // instance templates to validate that this is the correct
584 - // form: the problem is that some forms contain *only* mutliple-
585 - // instance templates.
586 - // if (! $allow_multiple) {
587 - $source_page_matches_this_form = true;
588 - // }
589 - }
590 - }
591 - }
592 - // If the input is from the form (meaning the user has hit one
593 - // of the bottom row of buttons), and we're dealing with a
594 - // multiple template, get the values for this instance of this
595 - // template, then delete them from the array, so we can get the
596 - // next group next time - the next() command for arrays doesn't
597 - // seem to work here.
598 - if ( ( ! $source_is_page ) && $allow_multiple && $wgRequest ) {
599 - $all_instances_printed = true;
600 - if ( $old_template_name != $template_name ) {
601 - $all_values_for_template = $wgRequest->getArray( $query_template_name );
602 - }
603 - if ( $all_values_for_template ) {
604 - $cur_key = key( $all_values_for_template );
605 - // skip the input coming in from the "starter" div
606 - // TODO: this code is probably no longer necessary
607 - if ( $cur_key == 'num' ) {
608 - unset( $all_values_for_template[$cur_key] );
609 - $cur_key = key( $all_values_for_template );
610 - }
611 - if ( $template_instance_query_values = current( $all_values_for_template ) ) {
612 - $all_instances_printed = false;
613 - unset( $all_values_for_template[$cur_key] );
614 - }
615 - }
616 - }
617 - // =====================================================
618 - // end template processing
619 - // =====================================================
620 - } elseif ( $tag_title == 'end template' ) {
621 - if ( $source_is_page ) {
622 - // add any unhandled template fields in the page as hidden variables
623 - if ( isset( $template_contents ) )
624 - $form_text .= SFFormUtils::unhandledFieldsHTML( $template_contents );
625 - }
626 - // remove this tag, reset some variables, and close off form HTML tag
627 - $section = substr_replace( $section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
628 - $template_name = null;
629 - if ( isset( $template_label ) ) {
630 - $form_text .= "</fieldset>\n";
631 - unset ( $template_label );
632 - }
633 - $allow_multiple = false;
634 - $all_instances_printed = false;
635 - $instance_num = 0;
636 - // =====================================================
637 - // field processing
638 - // =====================================================
639 - } elseif ( $tag_title == 'field' ) {
640 - $field_name = trim( $tag_components[1] );
641 - // cycle through the other components
642 - $is_mandatory = false;
643 - $is_hidden = false;
644 - $is_restricted = false;
645 - $is_uploadable = false;
646 - $is_list = false;
647 - $input_type = null;
648 - $field_args = array();
649 - $show_on_select = array();
650 - $default_value = "";
651 - $possible_values = null;
652 - $semantic_property = null;
653 - $preload_page = null;
654 - for ( $i = 2; $i < count( $tag_components ); $i++ ) {
655 - $component = trim( $tag_components[$i] );
656 - if ( $component == 'mandatory' ) {
657 - $is_mandatory = true;
658 - } elseif ( $component == 'hidden' ) {
659 - $is_hidden = true;
660 - } elseif ( $component == 'restricted' ) {
661 - $is_restricted = true;
662 - } elseif ( $component == 'uploadable' ) {
663 - $field_args['is_uploadable'] = true;
664 - } elseif ( $component == 'list' ) {
665 - $is_list = true;
666 - } elseif ( $component == 'autocomplete' ) {
667 - $field_args['autocomplete'] = true;
668 - } elseif ( $component == 'no autocomplete' ) {
669 - $field_args['no autocomplete'] = true;
670 - } elseif ( $component == 'remote autocompletion' ) {
671 - $field_args['remote autocompletion'] = true;
672 - } elseif ( $component == 'edittools' ) { // free text only
673 - $free_text_components[] = 'edittools';
674 - } else {
675 - $sub_components = explode( '=', $component, 2 );
676 - if ( count( $sub_components ) == 1 ) {
677 - // add handling for single-value params, for custom input types
678 - $field_args[$sub_components[0]] = null;
679 - } elseif ( count( $sub_components ) == 2 ) {
680 - if ( $sub_components[0] == 'input type' ) {
681 - $input_type = $sub_components[1];
682 - } elseif ( $sub_components[0] == 'default' ) {
683 - $default_value = $sub_components[1];
684 - } elseif ( $sub_components[0] == 'preload' ) {
685 - // free text field has special handling
686 - if ( $field_name == 'free text' || $field_name == '<freetext>' ) {
687 - $free_text_preload_page = $sub_components[1];
688 - } else {
689 - $preload_page = $sub_components[1];
690 - }
691 - } elseif ( $sub_components[0] == 'show on select' ) {
692 - // html_entity_decode() is needed to turn '&gt;' to '>'
693 - $vals = explode( ';', html_entity_decode( $sub_components[1] ) );
694 - foreach ( $vals as $val ) {
695 - $val = trim( $val );
696 - if ( empty( $val ) ) continue;
697 - $option_div_pair = explode( '=>', $val, 2 );
698 - if ( count( $option_div_pair ) > 1 ) {
699 - $option = $option_div_pair[0];
700 - $div_id = $option_div_pair[1];
701 - if ( array_key_exists( $div_id, $show_on_select ) )
702 - $show_on_select[$div_id][] = $option;
703 - else
704 - $show_on_select[$div_id] = array( $option );
705 - } else {
706 - $show_on_select[$val] = array();
707 - }
708 - }
709 - } elseif ( $sub_components[0] == 'autocomplete on property' ) {
710 - $property_name = $sub_components[1];
711 - $propValue = SMWPropertyValue::makeUserProperty( $property_name );
712 - if ( $propValue->getPropertyTypeID() == '_wpg' ) {
713 - $field_args['autocomplete field type'] = 'relation';
714 - } else {
715 - $field_args['autocomplete field type'] = 'attribute';
716 - }
717 - $field_args['autocompletion source'] = $sub_components[1];
718 - } elseif ( $sub_components[0] == 'autocomplete on category' ) {
719 - $field_args['autocomplete field type'] = 'category';
720 - $field_args['autocompletion source'] = $sub_components[1];
721 - } elseif ( $sub_components[0] == 'autocomplete on concept' ) {
722 - $field_args['autocomplete field type'] = 'concept';
723 - $field_args['autocompletion source'] = $sub_components[1];
724 - } elseif ( $sub_components[0] == 'autocomplete on namespace' ) {
725 - $field_args['autocomplete field type'] = 'namespace';
726 - $autocompletion_source = $sub_components[1];
727 - // special handling for "main" (blank) namespace
728 - if ( $autocompletion_source == "" )
729 - $autocompletion_source = "main";
730 - $field_args['autocompletion source'] = $autocompletion_source;
731 - } elseif ( $sub_components[0] == 'autocomplete from url' ) {
732 - $field_args['autocomplete field type'] = 'external_url';
733 - $field_args['autocompletion source'] = $sub_components[1];
734 - // 'external' autocompletion is always done remotely, i.e. via API
735 - $field_args['remote autocompletion'] = true;
736 - } elseif ( $sub_components[0] == 'values' ) {
737 - // remove whitespaces, and un-escape characters
738 - $possible_values = array_map( 'trim', explode( ',', $sub_components[1] ) );
739 - $possible_values = array_map( 'htmlspecialchars_decode', $possible_values );
740 - } elseif ( $sub_components[0] == 'values from property' ) {
741 - $propertyName = $sub_components[1];
742 - $propValue = SMWPropertyValue::makeUserProperty( $propertyName );
743 - $isRelation = $propValue->getPropertyTypeID() == '_wpg';
744 - $possible_values = SFAutocompleteAPI::getAllValuesForProperty( $isRelation, $propertyName );
745 - } elseif ( $sub_components[0] == 'values from category' ) {
746 - $category_name = ucfirst( $sub_components[1] );
747 - $possible_values = SFUtils::getAllPagesForCategory( $category_name, 10 );
748 - } elseif ( $sub_components[0] == 'values from concept' ) {
749 - $possible_values = SFUtils::getAllPagesForConcept( $sub_components[1] );
750 - } elseif ( $sub_components[0] == 'values from namespace' ) {
751 - $possible_values = SFUtils::getAllPagesForNamespace( $sub_components[1] );
752 - } elseif ( $sub_components[0] == 'property' ) {
753 - $semantic_property = $sub_components[1];
754 - } elseif ( $sub_components[0] == 'default filename' ) {
755 - $default_filename = str_replace( '&lt;page name&gt;', $page_name, $sub_components[1] );
756 - $field_args['default filename'] = $default_filename;
757 - }
 427+ while ( $brackets_loc = strpos( $section, '{{{', $start_position ) ) {
 428+ $brackets_end_loc = strpos( $section, "}}}", $brackets_loc );
 429+ $bracketed_string = substr( $section, $brackets_loc + 3, $brackets_end_loc - ( $brackets_loc + 3 ) );
 430+ $tag_components = SFUtils::getFormTagComponents( $bracketed_string );
 431+ $tag_title = trim( $tag_components[0] );
 432+ // =====================================================
 433+ // for template processing
 434+ // =====================================================
 435+ if ( $tag_title == 'for template' ) {
 436+ $old_template_name = $template_name;
 437+ $template_name = trim( $tag_components[1] );
 438+ $tif->template_name = $template_name;
 439+ $query_template_name = str_replace( ' ', '_', $template_name );
 440+ $add_button_text = wfMsg( 'sf_formedit_addanother' );
 441+ // Also replace periods with underlines, since that's what
 442+ // POST does to strings anyway.
 443+ $query_template_name = str_replace( '.', '_', $query_template_name );
 444+ // Cycle through the other components.
 445+ for ( $i = 2; $i < count( $tag_components ); $i++ ) {
 446+ $component = $tag_components[$i];
 447+ if ( $component == 'multiple' ) $allow_multiple = true;
 448+ if ( $component == 'strict' ) $strict_parsing = true;
 449+ $sub_components = explode( '=', $component, 2 );
 450+ if ( count( $sub_components ) == 2 ) {
 451+ if ( $sub_components[0] == 'label' ) {
 452+ $template_label = $sub_components[1];
 453+ } elseif ( $sub_components[0] == 'add button text' ) {
 454+ $add_button_text = $sub_components[1];
 455+ }
 456+ }
 457+ }
 458+ // If this is the first instance, add the label into the form, if
 459+ // there is one, and add the appropriate wrapper div, if this is
 460+ // a multiple-instance template.
 461+ if ( $old_template_name != $template_name ) {
 462+ if ( isset( $template_label ) ) {
 463+ $form_text .= "<fieldset>\n";
 464+ $form_text .= "<legend>$template_label</legend>\n";
 465+ }
 466+ if ($allow_multiple) {
 467+ $form_text .= "\t" . '<div class="multipleTemplateWrapper">' . "\n";
 468+ $form_text .= "\t" . '<div class="multipleTemplateList">' . "\n";
 469+ }
 470+ }
 471+ $template_text .= "{{" . $tif->template_name;
 472+ $all_fields = $tif->getAllFields();
 473+ // remove template tag
 474+ $section = substr_replace( $section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
 475+ $template_instance_query_values = $wgRequest->getArray( $query_template_name );
 476+ // If we are editing a page, and this template can be found more than
 477+ // once in that page, and multiple values are allowed, repeat this
 478+ // section.
 479+ $existing_template_text = null;
 480+ if ( $source_is_page || $form_is_partial ) {
 481+ // Replace underlines with spaces in template name, to allow for
 482+ // searching on either.
 483+ $search_template_str = str_replace( '_', ' ', $tif->template_name );
 484+ $preg_match_template_str = str_replace(
 485+ array( '/', '(', ')' ),
 486+ array( '\/', '\(', '\)' ),
 487+ $search_template_str );
 488+ $found_instance = preg_match( '/{{' . $preg_match_template_str . '\s*[\|}]/i', str_replace( '_', ' ', $existing_page_content ) );
 489+ if ( $allow_multiple ) {
 490+ // find instances of this template in the page -
 491+ // if there's at least one, re-parse this section of the
 492+ // definition form for the subsequent template instances in
 493+ // this page; if there's none, don't include fields at all.
 494+ // there has to be a more efficient way to handle multiple
 495+ // instances of templates, one that doesn't involve re-parsing
 496+ // the same tags, but I don't know what it is.
 497+ if ( $found_instance ) {
 498+ $instance_num++;
 499+ } else {
 500+ $all_instances_printed = true;
 501+ }
 502+ }
 503+ // get the first instance of this template on the page being edited,
 504+ // even if there are more
 505+ if ( $found_instance ) {
 506+ $matches = array();
 507+ $search_pattern = '/{{' . $preg_match_template_str . '\s*[\|}]/i';
 508+ $content_str = str_replace( '_', ' ', $existing_page_content );
 509+ preg_match($search_pattern, $content_str, $matches, PREG_OFFSET_CAPTURE);
 510+ // is this check necessary?
 511+ if ( array_key_exists( 0, $matches ) && array_key_exists( 1, $matches[0] ) ) {
 512+ $start_char = $matches[0][1];
 513+ $fields_start_char = $start_char + 2 + strlen( $search_template_str );
 514+ // Skip ahead to the first real character.
 515+ while ( in_array( $existing_page_content[$fields_start_char], array( ' ', '\n' ) ) ) {
 516+ $fields_start_char++;
 517+ }
 518+ // If the next character is a pipe, skip that too.
 519+ if( $existing_page_content[$fields_start_char] == '|' ) {
 520+ $fields_start_char++;
 521+ }
 522+ $template_contents = array( '0' => '' );
 523+ // Cycle through template call, splitting it up by pipes ('|'),
 524+ // except when that pipe is part of a piped link.
 525+ $field = "";
 526+ $uncompleted_square_brackets = 0;
 527+ $uncompleted_curly_brackets = 2;
 528+ $template_ended = false;
 529+ for ( $i = $fields_start_char; ! $template_ended && ( $i < strlen( $existing_page_content ) ); $i++ ) {
 530+ $c = $existing_page_content[$i];
 531+ if ( $c == '[' ) {
 532+ $uncompleted_square_brackets++;
 533+ } elseif ( $c == ']' && $uncompleted_square_brackets > 0 ) {
 534+ $uncompleted_square_brackets--;
 535+ } elseif ( $c == '{' ) {
 536+ $uncompleted_curly_brackets++;
 537+ } elseif ( $c == '}' && $uncompleted_curly_brackets > 0 ) {
 538+ $uncompleted_curly_brackets--;
 539+ }
 540+ // handle an end to a field and/or template declaration
 541+ $template_ended = ( $uncompleted_curly_brackets == 0 && $uncompleted_square_brackets == 0 );
 542+ $field_ended = ( $c == '|' && $uncompleted_square_brackets == 0 && $uncompleted_curly_brackets <= 2 );
 543+ if ( $template_ended || $field_ended ) {
 544+ // if this was the last character in the template, remove
 545+ // the closing curly brackets
 546+ if ( $template_ended ) {
 547+ $field = substr( $field, 0, - 1 );
 548+ }
 549+ // either there's an equals sign near the beginning or not -
 550+ // handling is similar in either way; if there's no equals
 551+ // sign, the index of this field becomes the key
 552+ $sub_fields = explode( '=', $field, 2 );
 553+ if ( count( $sub_fields ) > 1 ) {
 554+ $template_contents[trim( $sub_fields[0] )] = trim( $sub_fields[1] );
 555+ } else {
 556+ $template_contents[] = trim( $sub_fields[0] );
 557+ }
 558+ $field = '';
 559+ } else {
 560+ $field .= $c;
 561+ }
 562+ }
 563+ $existing_template_text = substr( $existing_page_content, $start_char, $i - $start_char );
 564+ // now remove this template from the text being edited
 565+ // if this is a partial form, establish a new insertion point
 566+ if ( $existing_page_content && $form_is_partial && $wgRequest->getCheck( 'partial' ) ) {
 567+ // if something already exists, set the new insertion point
 568+ // to its position; otherwise just let it lie
 569+ if ( strpos( $existing_page_content, $existing_template_text ) !== false ) {
 570+ $existing_page_content = str_replace( '{{{insertionpoint}}}', '', $existing_page_content );
 571+ $existing_page_content = str_replace( $existing_template_text, '{{{insertionpoint}}}', $existing_page_content );
 572+ }
 573+ } else {
 574+ $existing_page_content = self::strReplaceFirst( $existing_template_text, '', $existing_page_content );
 575+ }
 576+ // If this is not a multiple-instance template, and we've found
 577+ // a match in the source page, there's a good chance that this
 578+ // page was created with this form - note that, so we don't
 579+ // send the user a warning
 580+ // (multiple-instance templates have a greater chance of
 581+ // getting repeated from one form to the next)
 582+ // - on second thought, allow even the presence of multiple-
 583+ // instance templates to validate that this is the correct
 584+ // form: the problem is that some forms contain *only* mutliple-
 585+ // instance templates.
 586+ // if (! $allow_multiple) {
 587+ $source_page_matches_this_form = true;
 588+ // }
 589+ }
 590+ }
 591+ }
 592+ // If the input is from the form (meaning the user has hit one
 593+ // of the bottom row of buttons), and we're dealing with a
 594+ // multiple template, get the values for this instance of this
 595+ // template, then delete them from the array, so we can get the
 596+ // next group next time - the next() command for arrays doesn't
 597+ // seem to work here.
 598+ if ( ( ! $source_is_page ) && $allow_multiple && $wgRequest ) {
 599+ $all_instances_printed = true;
 600+ if ( $old_template_name != $template_name ) {
 601+ $all_values_for_template = $wgRequest->getArray( $query_template_name );
 602+ }
 603+ if ( $all_values_for_template ) {
 604+ $cur_key = key( $all_values_for_template );
 605+ // skip the input coming in from the "starter" div
 606+ // TODO: this code is probably no longer necessary
 607+ if ( $cur_key == 'num' ) {
 608+ unset( $all_values_for_template[$cur_key] );
 609+ $cur_key = key( $all_values_for_template );
 610+ }
 611+ if ( $template_instance_query_values = current( $all_values_for_template ) ) {
 612+ $all_instances_printed = false;
 613+ unset( $all_values_for_template[$cur_key] );
 614+ }
 615+ }
 616+ }
 617+ // =====================================================
 618+ // end template processing
 619+ // =====================================================
 620+ } elseif ( $tag_title == 'end template' ) {
 621+ if ( $source_is_page ) {
 622+ // add any unhandled template fields in the page as hidden variables
 623+ if ( isset( $template_contents ) )
 624+ $form_text .= SFFormUtils::unhandledFieldsHTML( $template_contents );
 625+ }
 626+ // remove this tag, reset some variables, and close off form HTML tag
 627+ $section = substr_replace( $section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
 628+ $template_name = null;
 629+ if ( isset( $template_label ) ) {
 630+ $form_text .= "</fieldset>\n";
 631+ unset ( $template_label );
 632+ }
 633+ $allow_multiple = false;
 634+ $all_instances_printed = false;
 635+ $instance_num = 0;
 636+ // =====================================================
 637+ // field processing
 638+ // =====================================================
 639+ } elseif ( $tag_title == 'field' ) {
 640+ $field_name = trim( $tag_components[1] );
 641+ // cycle through the other components
 642+ $is_mandatory = false;
 643+ $is_hidden = false;
 644+ $is_restricted = false;
 645+ $is_uploadable = false;
 646+ $is_list = false;
 647+ $input_type = null;
 648+ $field_args = array();
 649+ $show_on_select = array();
 650+ $default_value = "";
 651+ $possible_values = null;
 652+ $semantic_property = null;
 653+ $preload_page = null;
 654+ for ( $i = 2; $i < count( $tag_components ); $i++ ) {
 655+ $component = trim( $tag_components[$i] );
 656+ if ( $component == 'mandatory' ) {
 657+ $is_mandatory = true;
 658+ } elseif ( $component == 'hidden' ) {
 659+ $is_hidden = true;
 660+ } elseif ( $component == 'restricted' ) {
 661+ $is_restricted = true;
 662+ } elseif ( $component == 'uploadable' ) {
 663+ $field_args['is_uploadable'] = true;
 664+ } elseif ( $component == 'list' ) {
 665+ $is_list = true;
 666+ } elseif ( $component == 'autocomplete' ) {
 667+ $field_args['autocomplete'] = true;
 668+ } elseif ( $component == 'no autocomplete' ) {
 669+ $field_args['no autocomplete'] = true;
 670+ } elseif ( $component == 'remote autocompletion' ) {
 671+ $field_args['remote autocompletion'] = true;
 672+ } elseif ( $component == 'edittools' ) { // free text only
 673+ $free_text_components[] = 'edittools';
 674+ } else {
 675+ $sub_components = explode( '=', $component, 2 );
 676+ if ( count( $sub_components ) == 1 ) {
 677+ // add handling for single-value params, for custom input types
 678+ $field_args[$sub_components[0]] = null;
 679+ } elseif ( count( $sub_components ) == 2 ) {
 680+ if ( $sub_components[0] == 'input type' ) {
 681+ $input_type = $sub_components[1];
 682+ } elseif ( $sub_components[0] == 'default' ) {
 683+ $default_value = $sub_components[1];
 684+ } elseif ( $sub_components[0] == 'preload' ) {
 685+ // free text field has special handling
 686+ if ( $field_name == 'free text' || $field_name == '<freetext>' ) {
 687+ $free_text_preload_page = $sub_components[1];
 688+ } else {
 689+ $preload_page = $sub_components[1];
 690+ }
 691+ } elseif ( $sub_components[0] == 'show on select' ) {
 692+ // html_entity_decode() is needed to turn '&gt;' to '>'
 693+ $vals = explode( ';', html_entity_decode( $sub_components[1] ) );
 694+ foreach ( $vals as $val ) {
 695+ $val = trim( $val );
 696+ if ( empty( $val ) ) continue;
 697+ $option_div_pair = explode( '=>', $val, 2 );
 698+ if ( count( $option_div_pair ) > 1 ) {
 699+ $option = $option_div_pair[0];
 700+ $div_id = $option_div_pair[1];
 701+ if ( array_key_exists( $div_id, $show_on_select ) )
 702+ $show_on_select[$div_id][] = $option;
 703+ else
 704+ $show_on_select[$div_id] = array( $option );
 705+ } else {
 706+ $show_on_select[$val] = array();
 707+ }
 708+ }
 709+ } elseif ( $sub_components[0] == 'autocomplete on property' ) {
 710+ $property_name = $sub_components[1];
 711+ $propValue = SMWPropertyValue::makeUserProperty( $property_name );
 712+ if ( $propValue->getPropertyTypeID() == '_wpg' ) {
 713+ $field_args['autocomplete field type'] = 'relation';
 714+ } else {
 715+ $field_args['autocomplete field type'] = 'attribute';
 716+ }
 717+ $field_args['autocompletion source'] = $sub_components[1];
 718+ } elseif ( $sub_components[0] == 'autocomplete on category' ) {
 719+ $field_args['autocomplete field type'] = 'category';
 720+ $field_args['autocompletion source'] = $sub_components[1];
 721+ } elseif ( $sub_components[0] == 'autocomplete on concept' ) {
 722+ $field_args['autocomplete field type'] = 'concept';
 723+ $field_args['autocompletion source'] = $sub_components[1];
 724+ } elseif ( $sub_components[0] == 'autocomplete on namespace' ) {
 725+ $field_args['autocomplete field type'] = 'namespace';
 726+ $autocompletion_source = $sub_components[1];
 727+ // special handling for "main" (blank) namespace
 728+ if ( $autocompletion_source == "" )
 729+ $autocompletion_source = "main";
 730+ $field_args['autocompletion source'] = $autocompletion_source;
 731+ } elseif ( $sub_components[0] == 'autocomplete from url' ) {
 732+ $field_args['autocomplete field type'] = 'external_url';
 733+ $field_args['autocompletion source'] = $sub_components[1];
 734+ // 'external' autocompletion is always done remotely, i.e. via API
 735+ $field_args['remote autocompletion'] = true;
 736+ } elseif ( $sub_components[0] == 'values' ) {
 737+ // remove whitespaces, and un-escape characters
 738+ $possible_values = array_map( 'trim', explode( ',', $sub_components[1] ) );
 739+ $possible_values = array_map( 'htmlspecialchars_decode', $possible_values );
 740+ } elseif ( $sub_components[0] == 'values from property' ) {
 741+ $propertyName = $sub_components[1];
 742+ $propValue = SMWPropertyValue::makeUserProperty( $propertyName );
 743+ $isRelation = $propValue->getPropertyTypeID() == '_wpg';
 744+ $possible_values = SFAutocompleteAPI::getAllValuesForProperty( $isRelation, $propertyName );
 745+ } elseif ( $sub_components[0] == 'values from category' ) {
 746+ $category_name = ucfirst( $sub_components[1] );
 747+ $possible_values = SFUtils::getAllPagesForCategory( $category_name, 10 );
 748+ } elseif ( $sub_components[0] == 'values from concept' ) {
 749+ $possible_values = SFUtils::getAllPagesForConcept( $sub_components[1] );
 750+ } elseif ( $sub_components[0] == 'values from namespace' ) {
 751+ $possible_values = SFUtils::getAllPagesForNamespace( $sub_components[1] );
 752+ } elseif ( $sub_components[0] == 'property' ) {
 753+ $semantic_property = $sub_components[1];
 754+ } elseif ( $sub_components[0] == 'default filename' ) {
 755+ $default_filename = str_replace( '&lt;page name&gt;', $page_name, $sub_components[1] );
 756+ $field_args['default filename'] = $default_filename;
 757+ }
758758
759 - // Also set each value as its own entry in $field_args
760 - $field_args[$sub_components[0]] = $sub_components[1];
761 - }
762 - }
763 - } // end for
764 - // Backwards compatibility
765 - if ( $input_type == 'datetime with timezone' ) {
766 - $input_type = 'datetime';
767 - $field_args['include timezone'] = true;
768 - }
769 - if ( $allow_multiple )
770 - $field_args['part_of_multiple'] = $allow_multiple;
771 - if ( count( $show_on_select ) > 0 )
772 - $field_args['show on select'] = $show_on_select;
773 - // get the value from the request, if it's there, and if it's not
774 - // an array
775 - $escaped_field_name = str_replace( "'", "\'", $field_name );
776 - if ( isset( $template_instance_query_values ) &&
777 - $template_instance_query_values != null &&
778 - is_array( $template_instance_query_values ) &&
779 - array_key_exists( $escaped_field_name, $template_instance_query_values ) ) {
780 - $field_query_val = $template_instance_query_values[$escaped_field_name];
781 - if ( $form_submitted || ( ! is_null( $field_query_val ) && ! is_array( $field_query_val ) ) ) {
782 - $cur_value = $field_query_val;
783 - }
784 - } else {
785 - $cur_value = '';
786 - }
 759+ // Also set each value as its own entry in $field_args
 760+ $field_args[$sub_components[0]] = $sub_components[1];
 761+ }
 762+ }
 763+ } // end for
 764+ // Backwards compatibility
 765+ if ( $input_type == 'datetime with timezone' ) {
 766+ $input_type = 'datetime';
 767+ $field_args['include timezone'] = true;
 768+ }
 769+ if ( $allow_multiple )
 770+ $field_args['part_of_multiple'] = $allow_multiple;
 771+ if ( count( $show_on_select ) > 0 )
 772+ $field_args['show on select'] = $show_on_select;
 773+ // get the value from the request, if it's there, and if it's not
 774+ // an array
 775+ $escaped_field_name = str_replace( "'", "\'", $field_name );
 776+ if ( isset( $template_instance_query_values ) &&
 777+ $template_instance_query_values != null &&
 778+ is_array( $template_instance_query_values ) &&
 779+ array_key_exists( $escaped_field_name, $template_instance_query_values ) ) {
 780+ $field_query_val = $template_instance_query_values[$escaped_field_name];
 781+ if ( $form_submitted || ( ! is_null( $field_query_val ) && ! is_array( $field_query_val ) ) ) {
 782+ $cur_value = $field_query_val;
 783+ }
 784+ } else {
 785+ $cur_value = '';
 786+ }
787787
788 - if ( empty( $cur_value ) ) {
789 - if ( $default_value ) {
790 - // Set to the default value specified in the form, if it's there.
791 - $cur_value = $default_value;
792 - } elseif ( $preload_page ) {
793 - $cur_value = SFFormUtils::getPreloadedText( $preload_page );
794 - }
795 - }
 788+ if ( empty( $cur_value ) ) {
 789+ if ( $default_value ) {
 790+ // Set to the default value specified in the form, if it's there.
 791+ $cur_value = $default_value;
 792+ } elseif ( $preload_page ) {
 793+ $cur_value = SFFormUtils::getPreloadedText( $preload_page );
 794+ }
 795+ }
796796
797 - // if the user is editing a page, and that page contains a call to
798 - // the template being processed, get the current field's value
799 - // from the template call
800 - if ( $source_is_page && ( ! empty( $existing_template_text ) ) ) {
801 - if ( isset( $template_contents[$field_name] ) ) {
802 - $cur_value = $template_contents[$field_name];
803 - // now remove this value from $template_contents, so that
804 - // at the end we can have a list of all the fields that
805 - // weren't handled by the form
806 - unset( $template_contents[$field_name] );
807 - } else {
808 - $cur_value = '';
809 - }
810 - }
 797+ // if the user is editing a page, and that page contains a call to
 798+ // the template being processed, get the current field's value
 799+ // from the template call
 800+ if ( $source_is_page && ( ! empty( $existing_template_text ) ) ) {
 801+ if ( isset( $template_contents[$field_name] ) ) {
 802+ $cur_value = $template_contents[$field_name];
 803+ // now remove this value from $template_contents, so that
 804+ // at the end we can have a list of all the fields that
 805+ // weren't handled by the form
 806+ unset( $template_contents[$field_name] );
 807+ } else {
 808+ $cur_value = '';
 809+ }
 810+ }
811811
812 - // Handle the free text field - if it was declared as
813 - // "field|free text" (a deprecated usage), it has to be outside
814 - // of a template.
815 - if ( ( $template_name == '' && $field_name == 'free text' ) ||
816 - $field_name == '<freetext>' ) {
817 - // Add placeholders for the free text in both the form and
818 - // the page, using <free_text> tags - once all the free text
819 - // is known (at the end), it will get substituted in.
820 - if ( $is_hidden ) {
821 - $new_text = SFFormUtils::hiddenFieldHTML( 'free_text', '!free_text!' );
822 - } else {
823 - if ( ! array_key_exists( 'rows', $field_args ) )
824 - $field_args['rows'] = 5;
825 - if ( ! array_key_exists( 'cols', $field_args ) )
826 - $field_args['cols'] = 80;
827 - $sfgTabIndex++;
828 - $sfgFieldNum++;
829 - if ( $cur_value == '' ) {
830 - $default_value = '!free_text!';
831 - } else {
832 - $default_value = $cur_value;
833 - }
834 - $new_text = SFTextAreaInput::getHTML( $default_value, 'free_text', false, ( $form_is_disabled || $is_restricted ), $field_args );
835 - if ( in_array( 'edittools', $free_text_components ) ) {
836 - // borrowed from EditPage::showEditTools()
837 - $options[] = 'parse';
838 - $edittools_text = wfMsgExt( 'edittools', array( 'parse' ), array( 'content' ) );
 812+ // Handle the free text field - if it was declared as
 813+ // "field|free text" (a deprecated usage), it has to be outside
 814+ // of a template.
 815+ if ( ( $template_name == '' && $field_name == 'free text' ) ||
 816+ $field_name == '<freetext>' ) {
 817+ // Add placeholders for the free text in both the form and
 818+ // the page, using <free_text> tags - once all the free text
 819+ // is known (at the end), it will get substituted in.
 820+ if ( $is_hidden ) {
 821+ $new_text = SFFormUtils::hiddenFieldHTML( 'free_text', '!free_text!' );
 822+ } else {
 823+ if ( ! array_key_exists( 'rows', $field_args ) )
 824+ $field_args['rows'] = 5;
 825+ if ( ! array_key_exists( 'cols', $field_args ) )
 826+ $field_args['cols'] = 80;
 827+ $sfgTabIndex++;
 828+ $sfgFieldNum++;
 829+ if ( $cur_value == '' ) {
 830+ $default_value = '!free_text!';
 831+ } else {
 832+ $default_value = $cur_value;
 833+ }
 834+ $new_text = SFTextAreaInput::getHTML( $default_value, 'free_text', false, ( $form_is_disabled || $is_restricted ), $field_args );
 835+ if ( in_array( 'edittools', $free_text_components ) ) {
 836+ // borrowed from EditPage::showEditTools()
 837+ $options[] = 'parse';
 838+ $edittools_text = wfMsgExt( 'edittools', array( 'parse' ), array( 'content' ) );
839839
840 - $new_text .= <<<END
 840+ $new_text .= <<<END
841841 <div class="mw-editTools">
842842 $edittools_text
843843 </div>
844844
845845 END;
846 - }
847 - }
848 - $free_text_was_included = true;
849 - // add a similar placeholder to the data text
850 - $data_text .= "!free_text!\n";
851 - }
 846+ }
 847+ }
 848+ $free_text_was_included = true;
 849+ // add a similar placeholder to the data text
 850+ $data_text .= "!free_text!\n";
 851+ }
852852
853 - if ( $template_name == '' || $field_name == '<freetext>' ) {
854 - $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
855 - } else {
856 - if ( is_array( $cur_value ) ) {
857 - // first, check if it's a list
858 - if ( array_key_exists( 'is_list', $cur_value ) &&
859 - $cur_value['is_list'] == true ) {
860 - $cur_value_in_template = "";
861 - if ( array_key_exists( 'delimiter', $field_args ) ) {
862 - $delimiter = $field_args['delimiter'];
863 - } else {
864 - $delimiter = ",";
865 - }
866 - foreach ( $cur_value as $key => $val ) {
867 - if ( $key !== "is_list" ) {
868 - if ( $cur_value_in_template != "" ) {
869 - $cur_value_in_template .= $delimiter . " ";
870 - }
871 - $cur_value_in_template .= $val;
872 - }
873 - }
874 - } else {
875 - // otherwise:
876 - // if it has 1 or 2 elements, assume it's a checkbox; if it has
877 - // 3 elements, assume it's a date
878 - // - this handling will have to get more complex if other
879 - // possibilities get added
880 - if ( count( $cur_value ) == 1 ) {
881 - // manually load SMW's message values here, in case they
882 - // didn't get loaded before
883 - global $wgVersion;
884 - if ( version_compare( $wgVersion, '1.16', '<' ) ) {
885 - wfLoadExtensionMessages( 'SemanticMediaWiki' );
886 - }
887 - $words_for_false = explode( ',', wfMsgForContent( 'smw_false_words' ) );
888 - // for each language, there's a series of words that are
889 - // equal to false - get the word in the series that matches
890 - // "no"; generally, that's the third word
891 - $index_of_no = 2;
892 - if ( count( $words_for_false ) > $index_of_no ) {
893 - $no = ucwords( $words_for_false[$index_of_no] );
894 - } elseif ( count( $words_for_false ) == 0 ) {
895 - $no = "0"; // some safe value if no words are found
896 - } else {
897 - $no = ucwords( $words_for_false[0] );
898 - }
899 - $cur_value_in_template = $no;
900 - } elseif ( count( $cur_value ) == 2 ) {
901 - global $wgVersion;
902 - if ( version_compare( $wgVersion, '1.16', '<' ) ) {
903 - wfLoadExtensionMessages( 'SemanticMediaWiki' );
904 - }
905 - $words_for_true = explode( ',', wfMsgForContent( 'smw_true_words' ) );
906 - // get the value in the 'true' series that tends to be "yes",
907 - // and go with that one - generally, that's the third word
908 - $index_of_yes = 2;
909 - if ( count( $words_for_true ) > $index_of_yes ) {
910 - $yes = ucwords( $words_for_true[$index_of_yes] );
911 - } elseif ( count( $words_for_true ) == 0 ) {
912 - $yes = "1"; // some safe value if no words are found
913 - } else {
914 - $yes = ucwords( $words_for_true[0] );
915 - }
916 - $cur_value_in_template = $yes;
917 - // if it's 3 or greater, assume it's a date or datetime
918 - } elseif ( count( $cur_value ) >= 3 ) {
919 - $month = $cur_value['month'];
920 - $day = $cur_value['day'];
921 - if ( $day != '' ) {
922 - global $wgAmericanDates;
923 - if ( $wgAmericanDates == false ) {
924 - // pad out day to always be two digits
925 - $day = str_pad( $day, 2, "0", STR_PAD_LEFT );
926 - }
927 - }
928 - $year = $cur_value['year'];
929 - $hour = $minute = $second = $ampm24h = $timezone = null;
930 - if ( isset( $cur_value['hour'] ) ) $hour = $cur_value['hour'];
931 - if ( isset( $cur_value['minute'] ) ) $minute = $cur_value['minute'];
932 - if ( isset( $cur_value['second'] ) ) $second = $cur_value['second'];
933 - if ( isset( $cur_value['ampm24h'] ) ) $ampm24h = $cur_value['ampm24h'];
934 - if ( isset( $cur_value['timezone'] ) ) $timezone = $cur_value['timezone'];
935 - if ( $month != '' && $day != '' && $year != '' ) {
936 - // special handling for American dates - otherwise, just
937 - // the standard year/month/day (where month is a number)
938 - global $wgAmericanDates;
939 - if ( $wgAmericanDates == true ) {
940 - $cur_value_in_template = "$month $day, $year";
941 - } else {
942 - $cur_value_in_template = "$year/$month/$day";
943 - }
944 - // include whatever time information we have
945 - if ( ! is_null( $hour ) )
946 - $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 );
947 - if ( ! is_null( $second ) )
948 - $cur_value_in_template .= ":" . str_pad( intval( substr( $second, 0, 2 ) ), 2, '0', STR_PAD_LEFT );
949 - if ( ! is_null( $ampm24h ) )
950 - $cur_value_in_template .= " $ampm24h";
951 - if ( ! is_null( $timezone ) )
952 - $cur_value_in_template .= " $timezone";
953 - } else {
954 - $cur_value_in_template = "";
955 - }
956 - }
957 - }
958 - } else { // value is not an array
959 - $cur_value_in_template = $cur_value;
960 - }
961 - if ( $template_name == null || $template_name == '' )
962 - $input_name = $field_name;
963 - elseif ( $allow_multiple )
964 - // 'num' will get replaced by an actual index, either in PHP
965 - // or in Javascript, later on
966 - $input_name = $template_name . '[num][' . $field_name . ']';
967 - else
968 - $input_name = $template_name . '[' . $field_name . ']';
 853+ if ( $template_name == '' || $field_name == '<freetext>' ) {
 854+ $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
 855+ } else {
 856+ if ( is_array( $cur_value ) ) {
 857+ // first, check if it's a list
 858+ if ( array_key_exists( 'is_list', $cur_value ) &&
 859+ $cur_value['is_list'] == true ) {
 860+ $cur_value_in_template = "";
 861+ if ( array_key_exists( 'delimiter', $field_args ) ) {
 862+ $delimiter = $field_args['delimiter'];
 863+ } else {
 864+ $delimiter = ",";
 865+ }
 866+ foreach ( $cur_value as $key => $val ) {
 867+ if ( $key !== "is_list" ) {
 868+ if ( $cur_value_in_template != "" ) {
 869+ $cur_value_in_template .= $delimiter . " ";
 870+ }
 871+ $cur_value_in_template .= $val;
 872+ }
 873+ }
 874+ } else {
 875+ // otherwise:
 876+ // if it has 1 or 2 elements, assume it's a checkbox; if it has
 877+ // 3 elements, assume it's a date
 878+ // - this handling will have to get more complex if other
 879+ // possibilities get added
 880+ if ( count( $cur_value ) == 1 ) {
 881+ // manually load SMW's message values here, in case they
 882+ // didn't get loaded before
 883+ global $wgVersion;
 884+ if ( version_compare( $wgVersion, '1.16', '<' ) ) {
 885+ wfLoadExtensionMessages( 'SemanticMediaWiki' );
 886+ }
 887+ $words_for_false = explode( ',', wfMsgForContent( 'smw_false_words' ) );
 888+ // for each language, there's a series of words that are
 889+ // equal to false - get the word in the series that matches
 890+ // "no"; generally, that's the third word
 891+ $index_of_no = 2;
 892+ if ( count( $words_for_false ) > $index_of_no ) {
 893+ $no = ucwords( $words_for_false[$index_of_no] );
 894+ } elseif ( count( $words_for_false ) == 0 ) {
 895+ $no = "0"; // some safe value if no words are found
 896+ } else {
 897+ $no = ucwords( $words_for_false[0] );
 898+ }
 899+ $cur_value_in_template = $no;
 900+ } elseif ( count( $cur_value ) == 2 ) {
 901+ global $wgVersion;
 902+ if ( version_compare( $wgVersion, '1.16', '<' ) ) {
 903+ wfLoadExtensionMessages( 'SemanticMediaWiki' );
 904+ }
 905+ $words_for_true = explode( ',', wfMsgForContent( 'smw_true_words' ) );
 906+ // get the value in the 'true' series that tends to be "yes",
 907+ // and go with that one - generally, that's the third word
 908+ $index_of_yes = 2;
 909+ if ( count( $words_for_true ) > $index_of_yes ) {
 910+ $yes = ucwords( $words_for_true[$index_of_yes] );
 911+ } elseif ( count( $words_for_true ) == 0 ) {
 912+ $yes = "1"; // some safe value if no words are found
 913+ } else {
 914+ $yes = ucwords( $words_for_true[0] );
 915+ }
 916+ $cur_value_in_template = $yes;
 917+ // if it's 3 or greater, assume it's a date or datetime
 918+ } elseif ( count( $cur_value ) >= 3 ) {
 919+ $month = $cur_value['month'];
 920+ $day = $cur_value['day'];
 921+ if ( $day != '' ) {
 922+ global $wgAmericanDates;
 923+ if ( $wgAmericanDates == false ) {
 924+ // pad out day to always be two digits
 925+ $day = str_pad( $day, 2, "0", STR_PAD_LEFT );
 926+ }
 927+ }
 928+ $year = $cur_value['year'];
 929+ $hour = $minute = $second = $ampm24h = $timezone = null;
 930+ if ( isset( $cur_value['hour'] ) ) $hour = $cur_value['hour'];
 931+ if ( isset( $cur_value['minute'] ) ) $minute = $cur_value['minute'];
 932+ if ( isset( $cur_value['second'] ) ) $second = $cur_value['second'];
 933+ if ( isset( $cur_value['ampm24h'] ) ) $ampm24h = $cur_value['ampm24h'];
 934+ if ( isset( $cur_value['timezone'] ) ) $timezone = $cur_value['timezone'];
 935+ if ( $month != '' && $day != '' && $year != '' ) {
 936+ // special handling for American dates - otherwise, just
 937+ // the standard year/month/day (where month is a number)
 938+ global $wgAmericanDates;
 939+ if ( $wgAmericanDates == true ) {
 940+ $cur_value_in_template = "$month $day, $year";
 941+ } else {
 942+ $cur_value_in_template = "$year/$month/$day";
 943+ }
 944+ // include whatever time information we have
 945+ if ( ! is_null( $hour ) )
 946+ $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 );
 947+ if ( ! is_null( $second ) )
 948+ $cur_value_in_template .= ":" . str_pad( intval( substr( $second, 0, 2 ) ), 2, '0', STR_PAD_LEFT );
 949+ if ( ! is_null( $ampm24h ) )
 950+ $cur_value_in_template .= " $ampm24h";
 951+ if ( ! is_null( $timezone ) )
 952+ $cur_value_in_template .= " $timezone";
 953+ } else {
 954+ $cur_value_in_template = "";
 955+ }
 956+ }
 957+ }
 958+ } else { // value is not an array
 959+ $cur_value_in_template = $cur_value;
 960+ }
 961+ if ( $template_name == null || $template_name == '' )
 962+ $input_name = $field_name;
 963+ elseif ( $allow_multiple )
 964+ // 'num' will get replaced by an actual index, either in PHP
 965+ // or in Javascript, later on
 966+ $input_name = $template_name . '[num][' . $field_name . ']';
 967+ else
 968+ $input_name = $template_name . '[' . $field_name . ']';
969969
970 - // if we're creating the page name from a formula based on
971 - // form values, see if the current input is part of that formula,
972 - // and if so, substitute in the actual value
973 - if ( $form_submitted && $generated_page_name != '' ) {
974 - // this line appears to be unnecessary
975 - // $generated_page_name = str_replace('.', '_', $generated_page_name);
976 - $generated_page_name = str_replace( ' ', '_', $generated_page_name );
977 - $escaped_input_name = str_replace( ' ', '_', $input_name );
978 - $generated_page_name = str_ireplace( "<$escaped_input_name>", $cur_value_in_template, $generated_page_name );
979 - // once the substitution is done, replace underlines back
980 - // with spaces
981 - $generated_page_name = str_replace( '_', ' ', $generated_page_name );
982 - }
983 - // disable this field if either the whole form is disabled, or
984 - // it's a restricted field and user doesn't have sysop privileges
985 - $is_disabled = ( $form_is_disabled ||
986 - ( $is_restricted && ( ! $wgUser || ! $wgUser->isAllowed( 'editrestrictedfields' ) ) ) );
987 - // Create an SFFormField instance based on all the parameters
988 - // in the form definition, and any information from the template
989 - // definition (contained in the $all_fields parameter).
990 - $form_field = SFFormField::createFromDefinition( $field_name,
991 - $input_name, $is_mandatory, $is_hidden, $is_uploadable,
992 - $possible_values, $is_disabled, $is_list, $input_type,
993 - $field_args, $all_fields, $strict_parsing );
994 - // If a property was set in the form definition, overwrite whatever
995 - // is set in the template field - this is somewhat of a hack, since
996 - // parameters set in the form definition are meant to go into the
997 - // SFFormField object, not the SFTemplateField object it contains;
998 - // it seemed like too much work, though, to create an
999 - // SFFormField::setSemanticProperty() function just for this call
1000 - if ( $semantic_property != null )
1001 - $form_field->template_field->setSemanticProperty( $semantic_property );
 970+ // if we're creating the page name from a formula based on
 971+ // form values, see if the current input is part of that formula,
 972+ // and if so, substitute in the actual value
 973+ if ( $form_submitted && $generated_page_name != '' ) {
 974+ // this line appears to be unnecessary
 975+ // $generated_page_name = str_replace('.', '_', $generated_page_name);
 976+ $generated_page_name = str_replace( ' ', '_', $generated_page_name );
 977+ $escaped_input_name = str_replace( ' ', '_', $input_name );
 978+ $generated_page_name = str_ireplace( "<$escaped_input_name>", $cur_value_in_template, $generated_page_name );
 979+ // once the substitution is done, replace underlines back
 980+ // with spaces
 981+ $generated_page_name = str_replace( '_', ' ', $generated_page_name );
 982+ }
 983+ // disable this field if either the whole form is disabled, or
 984+ // it's a restricted field and user doesn't have sysop privileges
 985+ $is_disabled = ( $form_is_disabled ||
 986+ ( $is_restricted && ( ! $wgUser || ! $wgUser->isAllowed( 'editrestrictedfields' ) ) ) );
 987+ // Create an SFFormField instance based on all the parameters
 988+ // in the form definition, and any information from the template
 989+ // definition (contained in the $all_fields parameter).
 990+ $form_field = SFFormField::createFromDefinition( $field_name,
 991+ $input_name, $is_mandatory, $is_hidden, $is_uploadable,
 992+ $possible_values, $is_disabled, $is_list, $input_type,
 993+ $field_args, $all_fields, $strict_parsing );
 994+ // If a property was set in the form definition, overwrite whatever
 995+ // is set in the template field - this is somewhat of a hack, since
 996+ // parameters set in the form definition are meant to go into the
 997+ // SFFormField object, not the SFTemplateField object it contains;
 998+ // it seemed like too much work, though, to create an
 999+ // SFFormField::setSemanticProperty() function just for this call
 1000+ if ( $semantic_property != null )
 1001+ $form_field->template_field->setSemanticProperty( $semantic_property );
10021002
1003 - // call hooks - unfortunately this has to be split into two
1004 - // separate calls, because of the different variable names in
1005 - // each case
1006 - if ( $form_submitted )
1007 - wfRunHooks( 'sfCreateFormField', array( &$form_field, &$cur_value_in_template, true ) );
1008 - else
1009 - wfRunHooks( 'sfCreateFormField', array( &$form_field, &$cur_value, false ) );
1010 - // if this is not part of a 'multiple' template, increment the
1011 - // global tab index (used for correct tabbing)
1012 - if ( ! array_key_exists( 'part_of_multiple', $field_args ) )
1013 - $sfgTabIndex++;
1014 - // increment the global field number regardless
1015 - $sfgFieldNum++;
1016 - // if the field is a date field, and its default value was set
1017 - // to 'now', and it has no current value, set $cur_value to be
1018 - // the current date
1019 - if ( $default_value == 'now' &&
1020 - // if the date is hidden, cur_value will already be set
1021 - // to the default value
1022 - ( $cur_value == '' || $cur_value == 'now' ) ) {
1023 - if ( $input_type == 'date' || $input_type == 'datetime' ||
1024 - $input_type == 'year' ||
1025 - ( $input_type == '' && $form_field->template_field->field_type_id == '_dat' ) ) {
1026 - // Get current time, for the time zone specified in the wiki.
1027 - global $wgLocaltimezone;
1028 - if ( isset( $wgLocaltimezone ) ) {
1029 - $serverTimezone = date_default_timezone_get();
1030 - date_default_timezone_set( $wgLocaltimezone );
1031 - }
1032 - $cur_time = time();
1033 - $year = date( "Y", $cur_time );
1034 - $month = date( "n", $cur_time );
1035 - $day = date( "j", $cur_time );
1036 - global $wgAmericanDates, $sfg24HourTime;
1037 - if ( $wgAmericanDates == true ) {
1038 - $month_names = SFFormUtils::getMonthNames();
1039 - $month_name = $month_names[$month - 1];
1040 - $cur_value_in_template = "$month_name $day, $year";
1041 - } else {
1042 - $cur_value_in_template = "$year/$month/$day";
1043 - }
1044 - if ( isset( $wgLocaltimezone ) ) {
1045 - date_default_timezone_set( $serverTimezone );
1046 - }
1047 - if ( $input_type == 'datetime' ) {
1048 - if ( $sfg24HourTime ) {
1049 - $hour = str_pad( intval( substr( date( "G", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
1050 - } else {
1051 - $hour = str_pad( intval( substr( date( "g", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
1052 - }
1053 - $minute = str_pad( intval( substr( date( "i", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
1054 - $second = str_pad( intval( substr( date( "s", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
1055 - if ( $sfg24HourTime ) {
1056 - $cur_value_in_template .= " $hour:$minute:$second";
1057 - } else {
1058 - $ampm = date( "A", $cur_time );
1059 - $cur_value_in_template .= " $hour:$minute:$second $ampm";
1060 - }
1061 - }
1062 - if ( array_key_exists( 'include timezone', $field_args ) ) {
1063 - $timezone = date( "T", $cur_time );
1064 - $cur_value_in_template .= " $timezone";
1065 - }
1066 - }
1067 - }
1068 - // if the field is a text field, and its default value was set
1069 - // to 'current user', and it has no current value, set $cur_value
1070 - // to be the current user
1071 - if ( $default_value == 'current user' &&
1072 - // if the date is hidden, cur_value will already be set
1073 - // to the default value
1074 - ( $cur_value == '' || $cur_value == 'current user' ) ) {
1075 - if ( $input_type == 'text' || $input_type == '' ) {
1076 - $cur_value_in_template = $wgUser->getName();
1077 - $cur_value = $cur_value_in_template;
1078 - }
1079 - }
1080 - $new_text = $this->formFieldHTML( $form_field, $cur_value );
 1003+ // call hooks - unfortunately this has to be split into two
 1004+ // separate calls, because of the different variable names in
 1005+ // each case
 1006+ if ( $form_submitted )
 1007+ wfRunHooks( 'sfCreateFormField', array( &$form_field, &$cur_value_in_template, true ) );
 1008+ else
 1009+ wfRunHooks( 'sfCreateFormField', array( &$form_field, &$cur_value, false ) );
 1010+ // if this is not part of a 'multiple' template, increment the
 1011+ // global tab index (used for correct tabbing)
 1012+ if ( ! array_key_exists( 'part_of_multiple', $field_args ) )
 1013+ $sfgTabIndex++;
 1014+ // increment the global field number regardless
 1015+ $sfgFieldNum++;
 1016+ // if the field is a date field, and its default value was set
 1017+ // to 'now', and it has no current value, set $cur_value to be
 1018+ // the current date
 1019+ if ( $default_value == 'now' &&
 1020+ // if the date is hidden, cur_value will already be set
 1021+ // to the default value
 1022+ ( $cur_value == '' || $cur_value == 'now' ) ) {
 1023+ if ( $input_type == 'date' || $input_type == 'datetime' ||
 1024+ $input_type == 'year' ||
 1025+ ( $input_type == '' && $form_field->template_field->field_type_id == '_dat' ) ) {
 1026+ // Get current time, for the time zone specified in the wiki.
 1027+ global $wgLocaltimezone;
 1028+ if ( isset( $wgLocaltimezone ) ) {
 1029+ $serverTimezone = date_default_timezone_get();
 1030+ date_default_timezone_set( $wgLocaltimezone );
 1031+ }
 1032+ $cur_time = time();
 1033+ $year = date( "Y", $cur_time );
 1034+ $month = date( "n", $cur_time );
 1035+ $day = date( "j", $cur_time );
 1036+ global $wgAmericanDates, $sfg24HourTime;
 1037+ if ( $wgAmericanDates == true ) {
 1038+ $month_names = SFFormUtils::getMonthNames();
 1039+ $month_name = $month_names[$month - 1];
 1040+ $cur_value_in_template = "$month_name $day, $year";
 1041+ } else {
 1042+ $cur_value_in_template = "$year/$month/$day";
 1043+ }
 1044+ if ( isset( $wgLocaltimezone ) ) {
 1045+ date_default_timezone_set( $serverTimezone );
 1046+ }
 1047+ if ( $input_type == 'datetime' ) {
 1048+ if ( $sfg24HourTime ) {
 1049+ $hour = str_pad( intval( substr( date( "G", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
 1050+ } else {
 1051+ $hour = str_pad( intval( substr( date( "g", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
 1052+ }
 1053+ $minute = str_pad( intval( substr( date( "i", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
 1054+ $second = str_pad( intval( substr( date( "s", $cur_time ), 0, 2 ) ), 2, '0', STR_PAD_LEFT );
 1055+ if ( $sfg24HourTime ) {
 1056+ $cur_value_in_template .= " $hour:$minute:$second";
 1057+ } else {
 1058+ $ampm = date( "A", $cur_time );
 1059+ $cur_value_in_template .= " $hour:$minute:$second $ampm";
 1060+ }
 1061+ }
 1062+ if ( array_key_exists( 'include timezone', $field_args ) ) {
 1063+ $timezone = date( "T", $cur_time );
 1064+ $cur_value_in_template .= " $timezone";
 1065+ }
 1066+ }
 1067+ }
 1068+ // if the field is a text field, and its default value was set
 1069+ // to 'current user', and it has no current value, set $cur_value
 1070+ // to be the current user
 1071+ if ( $default_value == 'current user' &&
 1072+ // if the date is hidden, cur_value will already be set
 1073+ // to the default value
 1074+ ( $cur_value == '' || $cur_value == 'current user' ) ) {
 1075+ if ( $input_type == 'text' || $input_type == '' ) {
 1076+ $cur_value_in_template = $wgUser->getName();
 1077+ $cur_value = $cur_value_in_template;
 1078+ }
 1079+ }
 1080+ $new_text = $this->formFieldHTML( $form_field, $cur_value );
10811081
1082 - // if this field is disabled, add a hidden field holding
1083 - // the value of this field, because disabled inputs for some
1084 - // reason don't submit their value
1085 - if ( $form_field->is_disabled ) {
1086 - if ( $field_name == 'free text' || $field_name == '<freetext>' ) {
1087 - $new_text .= SFFormUtils::hiddenFieldHTML( 'free_text', '!free_text!' );
1088 - } else {
1089 - $new_text .= SFFormUtils::hiddenFieldHTML( $input_name, $cur_value );
1090 - }
1091 - }
 1082+ // if this field is disabled, add a hidden field holding
 1083+ // the value of this field, because disabled inputs for some
 1084+ // reason don't submit their value
 1085+ if ( $form_field->is_disabled ) {
 1086+ if ( $field_name == 'free text' || $field_name == '<freetext>' ) {
 1087+ $new_text .= SFFormUtils::hiddenFieldHTML( 'free_text', '!free_text!' );
 1088+ } else {
 1089+ $new_text .= SFFormUtils::hiddenFieldHTML( $input_name, $cur_value );
 1090+ }
 1091+ }
10921092
1093 - if ( $new_text ) {
1094 - // include the field name only for non-numeric field names
1095 - if ( is_numeric( $field_name ) ) {
1096 - $template_text .= "|$cur_value_in_template";
1097 - } else {
1098 - // if the value is null, don't include it at all
1099 - if ( $cur_value_in_template != '' )
1100 - $template_text .= "\n|$field_name=$cur_value_in_template";
1101 - }
1102 - $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
1103 - } else {
1104 - $start_position = $brackets_end_loc;
1105 - }
1106 - }
1107 - // =====================================================
1108 - // standard input processing
1109 - // =====================================================
1110 - } elseif ( $tag_title == 'standard input' ) {
1111 - // handle all the possible values
1112 - $input_name = $tag_components[1];
1113 - $input_label = null;
1114 - $attr = array();
1115 -
1116 - // if it's a query, ignore all standard inputs except run query
1117 - if ( ( $is_query && $input_name != 'run query' ) || ( !$is_query && $input_name == 'run query' ) ) {
1118 - $new_text = "";
1119 - $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
1120 - continue;
1121 - }
1122 - // set a flag so that the standard 'form bottom' won't get displayed
1123 - $this->standardInputsIncluded = true;
1124 - // cycle through the other components
1125 - for ( $i = 2; $i < count( $tag_components ); $i++ ) {
1126 - $component = $tag_components[$i];
1127 - $sub_components = explode( '=', $component );
1128 - if ( count( $sub_components ) == 1 ) {
1129 - if ( $sub_components[0] == 'edittools' ) {
1130 - $free_text_components[] = 'edittools';
1131 - }
1132 - } elseif ( count( $sub_components ) == 2 ) {
1133 - switch( $sub_components[0] ) {
1134 - case 'label':
1135 - $input_label = $sub_components[1];
1136 - break;
1137 - case 'class':
1138 - case 'style':
1139 - $attr[$sub_components[0]] = $sub_components[1];
1140 - break;
1141 - }
1142 - // free text input needs more handling than the rest
1143 - if ( $input_name == 'free text' || $input_name == '<freetext>' ) {
1144 - if ( $sub_components[0] == 'preload' ) {
1145 - $free_text_preload_page = $sub_components[1];
1146 - }
1147 - }
1148 - }
1149 - }
1150 - if ( $input_name == 'summary' ) {
1151 - $new_text = SFFormUtils::summaryInputHTML( $form_is_disabled, $input_label, $attr );
1152 - } elseif ( $input_name == 'minor edit' ) {
1153 - $new_text = SFFormUtils::minorEditInputHTML( $form_is_disabled, $input_label, $attr );
1154 - } elseif ( $input_name == 'watch' ) {
1155 - $new_text = SFFormUtils::watchInputHTML( $form_is_disabled, $input_label, $attr );
1156 - } elseif ( $input_name == 'save' ) {
1157 - $new_text = SFFormUtils::saveButtonHTML( $form_is_disabled, $input_label, $attr );
1158 - } elseif ( $input_name == 'preview' ) {
1159 - $new_text = SFFormUtils::showPreviewButtonHTML( $form_is_disabled, $input_label, $attr );
1160 - } elseif ( $input_name == 'changes' ) {
1161 - $new_text = SFFormUtils::showChangesButtonHTML( $form_is_disabled, $input_label, $attr );
1162 - } elseif ( $input_name == 'cancel' ) {
1163 - $new_text = SFFormUtils::cancelLinkHTML( $form_is_disabled, $input_label, $attr );
1164 - } elseif ( $input_name == 'run query' ) {
1165 - $new_text = SFFormUtils::runQueryButtonHTML( $form_is_disabled, $input_label, $attr );
1166 - }
1167 - $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
1168 - // =====================================================
1169 - // page info processing
1170 - // =====================================================
1171 - } elseif ( $tag_title == 'info' ) {
1172 - // TODO: Generate an error message if this is included more than once
1173 - foreach ( array_slice( $tag_components, 1 ) as $component ) {
1174 - $sub_components = explode( '=', $component, 2 );
1175 - $tag = $sub_components[0];
1176 - if ( $tag == 'create title' || $tag == 'add title' ) {
1177 - // handle this only if we're adding a page
1178 - if ( ! $this->mPageTitle->exists() ) {
1179 - $form_page_title = $sub_components[1];
1180 - }
1181 - } elseif ( $tag == 'edit title' ) {
1182 - // handle this only if we're editing a page
1183 - if ( $this->mPageTitle->exists() ) {
1184 - $form_page_title = $sub_components[1];
1185 - }
1186 - } elseif ( $tag == 'query title' ) {
1187 - // handle this only if we're in 'RunQuery'
1188 - if ( $is_query ) {
1189 - $form_page_title = $sub_components[1];
1190 - }
1191 - } elseif ( $tag == 'partial form' ) {
1192 - $form_is_partial = true;
1193 - // replacement pages may have minimal matches...
1194 - $source_page_matches_this_form = true;
1195 - } elseif ( $tag == 'includeonly free text' || $tag == 'onlyinclude free text' ) {
1196 - $onlyinclude_free_text = true;
1197 - }
1198 - }
1199 - $section = substr_replace( $section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
1200 - // =====================================================
1201 - // default outer level processing
1202 - // =====================================================
1203 - } else { // tag is not one of the three allowed values
1204 - // ignore tag
1205 - $start_position = $brackets_end_loc;
1206 - } // end if
1207 - } // end while
 1093+ if ( $new_text ) {
 1094+ // include the field name only for non-numeric field names
 1095+ if ( is_numeric( $field_name ) ) {
 1096+ $template_text .= "|$cur_value_in_template";
 1097+ } else {
 1098+ // if the value is null, don't include it at all
 1099+ if ( $cur_value_in_template != '' )
 1100+ $template_text .= "\n|$field_name=$cur_value_in_template";
 1101+ }
 1102+ $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
 1103+ } else {
 1104+ $start_position = $brackets_end_loc;
 1105+ }
 1106+ }
 1107+ // =====================================================
 1108+ // standard input processing
 1109+ // =====================================================
 1110+ } elseif ( $tag_title == 'standard input' ) {
 1111+ // handle all the possible values
 1112+ $input_name = $tag_components[1];
 1113+ $input_label = null;
 1114+ $attr = array();
 1115+
 1116+ // if it's a query, ignore all standard inputs except run query
 1117+ if ( ( $is_query && $input_name != 'run query' ) || ( !$is_query && $input_name == 'run query' ) ) {
 1118+ $new_text = "";
 1119+ $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
 1120+ continue;
 1121+ }
 1122+ // set a flag so that the standard 'form bottom' won't get displayed
 1123+ $this->standardInputsIncluded = true;
 1124+ // cycle through the other components
 1125+ for ( $i = 2; $i < count( $tag_components ); $i++ ) {
 1126+ $component = $tag_components[$i];
 1127+ $sub_components = explode( '=', $component );
 1128+ if ( count( $sub_components ) == 1 ) {
 1129+ if ( $sub_components[0] == 'edittools' ) {
 1130+ $free_text_components[] = 'edittools';
 1131+ }
 1132+ } elseif ( count( $sub_components ) == 2 ) {
 1133+ switch( $sub_components[0] ) {
 1134+ case 'label':
 1135+ $input_label = $sub_components[1];
 1136+ break;
 1137+ case 'class':
 1138+ case 'style':
 1139+ $attr[$sub_components[0]] = $sub_components[1];
 1140+ break;
 1141+ }
 1142+ // free text input needs more handling than the rest
 1143+ if ( $input_name == 'free text' || $input_name == '<freetext>' ) {
 1144+ if ( $sub_components[0] == 'preload' ) {
 1145+ $free_text_preload_page = $sub_components[1];
 1146+ }
 1147+ }
 1148+ }
 1149+ }
 1150+ if ( $input_name == 'summary' ) {
 1151+ $new_text = SFFormUtils::summaryInputHTML( $form_is_disabled, $input_label, $attr );
 1152+ } elseif ( $input_name == 'minor edit' ) {
 1153+ $new_text = SFFormUtils::minorEditInputHTML( $form_is_disabled, $input_label, $attr );
 1154+ } elseif ( $input_name == 'watch' ) {
 1155+ $new_text = SFFormUtils::watchInputHTML( $form_is_disabled, $input_label, $attr );
 1156+ } elseif ( $input_name == 'save' ) {
 1157+ $new_text = SFFormUtils::saveButtonHTML( $form_is_disabled, $input_label, $attr );
 1158+ } elseif ( $input_name == 'preview' ) {
 1159+ $new_text = SFFormUtils::showPreviewButtonHTML( $form_is_disabled, $input_label, $attr );
 1160+ } elseif ( $input_name == 'changes' ) {
 1161+ $new_text = SFFormUtils::showChangesButtonHTML( $form_is_disabled, $input_label, $attr );
 1162+ } elseif ( $input_name == 'cancel' ) {
 1163+ $new_text = SFFormUtils::cancelLinkHTML( $form_is_disabled, $input_label, $attr );
 1164+ } elseif ( $input_name == 'run query' ) {
 1165+ $new_text = SFFormUtils::runQueryButtonHTML( $form_is_disabled, $input_label, $attr );
 1166+ }
 1167+ $section = substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
 1168+ // =====================================================
 1169+ // page info processing
 1170+ // =====================================================
 1171+ } elseif ( $tag_title == 'info' ) {
 1172+ // TODO: Generate an error message if this is included more than once
 1173+ foreach ( array_slice( $tag_components, 1 ) as $component ) {
 1174+ $sub_components = explode( '=', $component, 2 );
 1175+ $tag = $sub_components[0];
 1176+ if ( $tag == 'create title' || $tag == 'add title' ) {
 1177+ // handle this only if we're adding a page
 1178+ if ( ! $this->mPageTitle->exists() ) {
 1179+ $form_page_title = $sub_components[1];
 1180+ }
 1181+ } elseif ( $tag == 'edit title' ) {
 1182+ // handle this only if we're editing a page
 1183+ if ( $this->mPageTitle->exists() ) {
 1184+ $form_page_title = $sub_components[1];
 1185+ }
 1186+ } elseif ( $tag == 'query title' ) {
 1187+ // handle this only if we're in 'RunQuery'
 1188+ if ( $is_query ) {
 1189+ $form_page_title = $sub_components[1];
 1190+ }
 1191+ } elseif ( $tag == 'partial form' ) {
 1192+ $form_is_partial = true;
 1193+ // replacement pages may have minimal matches...
 1194+ $source_page_matches_this_form = true;
 1195+ } elseif ( $tag == 'includeonly free text' || $tag == 'onlyinclude free text' ) {
 1196+ $onlyinclude_free_text = true;
 1197+ }
 1198+ }
 1199+ $section = substr_replace( $section, '', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
 1200+ // =====================================================
 1201+ // default outer level processing
 1202+ // =====================================================
 1203+ } else { // tag is not one of the three allowed values
 1204+ // ignore tag
 1205+ $start_position = $brackets_end_loc;
 1206+ } // end if
 1207+ } // end while
12081208
1209 - if ( ! $all_instances_printed ) {
1210 - if ( $template_text != '' ) {
1211 - // for mostly aesthetic purposes, if the template call ends with
1212 - // a bunch of pipes (i.e., it's an indexed template with unused
1213 - // parameters at the end), remove the pipes
1214 - $template_text = preg_replace( '/\|*$/', '', $template_text );
1215 - // add another newline before the final bracket, if this template
1216 - // call is already more than one line
1217 - if ( strpos( $template_text, "\n" ) )
1218 - $template_text .= "\n";
1219 - // if we're editing an existing page, and there were fields in
1220 - // the template call not handled by this form, preserve those
1221 - $template_text .= SFFormUtils::addUnhandledFields();
1222 - $template_text .= "}}";
1223 - $data_text .= $template_text . "\n";
1224 - // if there is a placeholder in the text, we know that we are
1225 - // doing a replace
1226 - if ( $existing_page_content && strpos( $existing_page_content, '{{{insertionpoint}}}', 0 ) !== false ) {
1227 - $existing_page_content = preg_replace( '/\{\{\{insertionpoint\}\}\}(\r?\n?)/',
1228 - preg_replace( '/\}\}/m', '}�',
1229 - preg_replace( '/\{\{/m', '�{', $template_text ) ) .
1230 - "\n{{{insertionpoint}}}",
1231 - $existing_page_content );
1232 - // otherwise, if it's a partial form, we have to add the new
1233 - // text somewhere
1234 - } elseif ( $form_is_partial && $wgRequest->getCheck( 'partial' ) ) {
1235 - $existing_page_content = preg_replace( '/\}\}/m', '}�',
1236 - preg_replace( '/\{\{/m', '�{', $template_text ) ) .
1237 - "\n{{{insertionpoint}}}\n" . $existing_page_content;
1238 - }
1239 - }
1240 - }
 1209+ if ( ! $all_instances_printed ) {
 1210+ if ( $template_text != '' ) {
 1211+ // for mostly aesthetic purposes, if the template call ends with
 1212+ // a bunch of pipes (i.e., it's an indexed template with unused
 1213+ // parameters at the end), remove the pipes
 1214+ $template_text = preg_replace( '/\|*$/', '', $template_text );
 1215+ // add another newline before the final bracket, if this template
 1216+ // call is already more than one line
 1217+ if ( strpos( $template_text, "\n" ) )
 1218+ $template_text .= "\n";
 1219+ // if we're editing an existing page, and there were fields in
 1220+ // the template call not handled by this form, preserve those
 1221+ $template_text .= SFFormUtils::addUnhandledFields();
 1222+ $template_text .= "}}";
 1223+ $data_text .= $template_text . "\n";
 1224+ // if there is a placeholder in the text, we know that we are
 1225+ // doing a replace
 1226+ if ( $existing_page_content && strpos( $existing_page_content, '{{{insertionpoint}}}', 0 ) !== false ) {
 1227+ $existing_page_content = preg_replace( '/\{\{\{insertionpoint\}\}\}(\r?\n?)/',
 1228+ preg_replace( '/\}\}/m', '}�',
 1229+ preg_replace( '/\{\{/m', '�{', $template_text ) ) .
 1230+ "\n{{{insertionpoint}}}",
 1231+ $existing_page_content );
 1232+ // otherwise, if it's a partial form, we have to add the new
 1233+ // text somewhere
 1234+ } elseif ( $form_is_partial && $wgRequest->getCheck( 'partial' ) ) {
 1235+ $existing_page_content = preg_replace( '/\}\}/m', '}�',
 1236+ preg_replace( '/\{\{/m', '�{', $template_text ) ) .
 1237+ "\n{{{insertionpoint}}}\n" . $existing_page_content;
 1238+ }
 1239+ }
 1240+ }
12411241
1242 - if ( $allow_multiple ) {
1243 - if ( ! $all_instances_printed ) {
1244 - // add the character "a" onto the instance number of this input
1245 - // in the form, to differentiate the inputs the form starts out
1246 - // with from any inputs added by the Javascript
1247 - $section = str_replace( '[num]', "[{$instance_num}a]", $section );
1248 - $form_text .= "\t\t" . Xml::tags( 'div',
1249 - array(
1250 - // The "multipleTemplate" class is there for
1251 - // backwards-compatibility with any custom CSS on people's
1252 - // wikis before SF 2.0.9.
1253 - 'class' => "multipleTemplateInstance multipleTemplate"
1254 - ),
1255 - self::multipleTemplateInstanceTableHTML( $section )
1256 - ) . "\n";
 1242+ if ( $allow_multiple ) {
 1243+ if ( ! $all_instances_printed ) {
 1244+ // add the character "a" onto the instance number of this input
 1245+ // in the form, to differentiate the inputs the form starts out
 1246+ // with from any inputs added by the Javascript
 1247+ $section = str_replace( '[num]', "[{$instance_num}a]", $section );
 1248+ $form_text .= "\t\t" . Xml::tags( 'div',
 1249+ array(
 1250+ // The "multipleTemplate" class is there for
 1251+ // backwards-compatibility with any custom CSS on people's
 1252+ // wikis before SF 2.0.9.
 1253+ 'class' => "multipleTemplateInstance multipleTemplate"
 1254+ ),
 1255+ self::multipleTemplateInstanceTableHTML( $section )
 1256+ ) . "\n";
12571257
1258 - // this will cause the section to be re-parsed on the next go
1259 - $section_num--;
1260 - } else {
1261 - // This is the last instance of this template - print all the
1262 - // sections necessary for adding additional instances.
1263 - $form_text .= "\t\t" . Xml::tags( 'div',
1264 - array(
1265 - 'class' => "multipleTemplateStarter",
1266 - 'style' => "display: none",
1267 - ),
1268 - self::multipleTemplateInstanceTableHTML( $section )
1269 - ) . "\n";
1270 - $form_text .= <<<END
 1258+ // this will cause the section to be re-parsed on the next go
 1259+ $section_num--;
 1260+ } else {
 1261+ // This is the last instance of this template - print all the
 1262+ // sections necessary for adding additional instances.
 1263+ $form_text .= "\t\t" . Xml::tags( 'div',
 1264+ array(
 1265+ 'class' => "multipleTemplateStarter",
 1266+ 'style' => "display: none",
 1267+ ),
 1268+ self::multipleTemplateInstanceTableHTML( $section )
 1269+ ) . "\n";
 1270+ $form_text .= <<<END
12711271 </div><!-- multipleTemplateList -->
12721272 <p style="margin-left:10px;" />
12731273 <p><input type="button" value="$add_button_text" tabindex="$sfgTabIndex" class="multipleTemplateAdder" /></p>
12741274 </div><!-- multipleTemplateWrapper -->
12751275
12761276 END;
1277 - }
1278 - } else {
1279 - $form_text .= $section;
1280 - }
 1277+ }
 1278+ } else {
 1279+ $form_text .= $section;
 1280+ }
12811281
1282 - } // end for
 1282+ } // end for
12831283
1284 - // if it wasn't included in the form definition, add the
1285 - // 'free text' input as a hidden field at the bottom
1286 - if ( ! $free_text_was_included ) {
1287 - $form_text .= SFFormUtils::hiddenFieldHTML( 'free_text', '!free_text!' );
1288 - }
1289 - // get free text, and add to page data, as well as retroactively
1290 - // inserting it into the form
 1284+ // if it wasn't included in the form definition, add the
 1285+ // 'free text' input as a hidden field at the bottom
 1286+ if ( ! $free_text_was_included ) {
 1287+ $form_text .= SFFormUtils::hiddenFieldHTML( 'free_text', '!free_text!' );
 1288+ }
 1289+ // get free text, and add to page data, as well as retroactively
 1290+ // inserting it into the form
12911291
1292 - // If $form_is_partial is true then either:
1293 - // (a) we're processing a replacement (param 'partial' == 1)
1294 - // (b) we're sending out something to be replaced (param 'partial' is missing)
1295 - if ( $form_is_partial ) {
1296 - if ( !$wgRequest->getCheck( 'partial' ) ) {
1297 - $free_text = $original_page_content;
1298 - $form_text .= SFFormUtils::hiddenFieldHTML( 'partial', 1 );
1299 - } else {
1300 - $free_text = null;
1301 - $existing_page_content = preg_replace( array( '/�\{/m','/\}�/m' ),
1302 - array( '{{','}}' ),
1303 - $existing_page_content );
1304 - $existing_page_content = preg_replace( '/\{\{\{insertionpoint\}\}\}/', '', $existing_page_content );
1305 - }
1306 - } elseif ( $source_is_page ) {
1307 - // if the page is the source, free_text will just be whatever in the
1308 - // page hasn't already been inserted into the form
1309 - $free_text = trim( $existing_page_content );
1310 - // or get it from a form submission
1311 - } elseif ( $wgRequest->getCheck( 'free_text' ) ) {
1312 - $free_text = $wgRequest->getVal( 'free_text' );
1313 - if ( ! $free_text_was_included ) {
1314 - $data_text .= "!free_text!";
1315 - }
1316 - // or get it from the form definition
1317 - } elseif ( $free_text_preload_page != null ) {
1318 - $free_text = SFFormUtils::getPreloadedText( $free_text_preload_page );
1319 - } else {
1320 - $free_text = null;
1321 - }
1322 - if ( $onlyinclude_free_text ) {
1323 - // modify free text and data text to insert <onlyinclude> tags
1324 - $free_text = str_replace( "<onlyinclude>", '', $free_text );
1325 - $free_text = str_replace( "</onlyinclude>", '', $free_text );
1326 - $free_text = trim( $free_text );
1327 - $data_text = str_replace( '!free_text!', '<onlyinclude>!free_text!</onlyinclude>', $data_text );
1328 - }
1329 - // if the FCKeditor extension is installed, use that for the free text input
1330 - global $wgFCKEditorDir;
1331 - if ( $wgFCKEditorDir && strpos( $existing_page_content, '__NORICHEDITOR__' ) === false ) {
1332 - $showFCKEditor = SFFormUtils::getShowFCKEditor();
1333 - if ( !$form_submitted && ( $showFCKEditor & RTE_VISIBLE ) ) {
1334 - $free_text = SFFormUtils::prepareTextForFCK( $free_text );
1335 - }
1336 - } else {
1337 - $showFCKEditor = 0;
1338 - }
1339 - // now that we have it, substitute free text into the form and page
1340 - $escaped_free_text = Sanitizer::safeEncodeAttribute( $free_text );
1341 - $form_text = str_replace( '!free_text!', $escaped_free_text, $form_text );
1342 - $data_text = str_replace( '!free_text!', $free_text, $data_text );
 1292+ // If $form_is_partial is true then either:
 1293+ // (a) we're processing a replacement (param 'partial' == 1)
 1294+ // (b) we're sending out something to be replaced (param 'partial' is missing)
 1295+ if ( $form_is_partial ) {
 1296+ if ( !$wgRequest->getCheck( 'partial' ) ) {
 1297+ $free_text = $original_page_content;
 1298+ $form_text .= SFFormUtils::hiddenFieldHTML( 'partial', 1 );
 1299+ } else {
 1300+ $free_text = null;
 1301+ $existing_page_content = preg_replace( array( '/�\{/m','/\}�/m' ),
 1302+ array( '{{','}}' ),
 1303+ $existing_page_content );
 1304+ $existing_page_content = preg_replace( '/\{\{\{insertionpoint\}\}\}/', '', $existing_page_content );
 1305+ }
 1306+ } elseif ( $source_is_page ) {
 1307+ // if the page is the source, free_text will just be whatever in the
 1308+ // page hasn't already been inserted into the form
 1309+ $free_text = trim( $existing_page_content );
 1310+ // or get it from a form submission
 1311+ } elseif ( $wgRequest->getCheck( 'free_text' ) ) {
 1312+ $free_text = $wgRequest->getVal( 'free_text' );
 1313+ if ( ! $free_text_was_included ) {
 1314+ $data_text .= "!free_text!";
 1315+ }
 1316+ // or get it from the form definition
 1317+ } elseif ( $free_text_preload_page != null ) {
 1318+ $free_text = SFFormUtils::getPreloadedText( $free_text_preload_page );
 1319+ } else {
 1320+ $free_text = null;
 1321+ }
 1322+ if ( $onlyinclude_free_text ) {
 1323+ // modify free text and data text to insert <onlyinclude> tags
 1324+ $free_text = str_replace( "<onlyinclude>", '', $free_text );
 1325+ $free_text = str_replace( "</onlyinclude>", '', $free_text );
 1326+ $free_text = trim( $free_text );
 1327+ $data_text = str_replace( '!free_text!', '<onlyinclude>!free_text!</onlyinclude>', $data_text );
 1328+ }
 1329+ // if the FCKeditor extension is installed, use that for the free text input
 1330+ global $wgFCKEditorDir;
 1331+ if ( $wgFCKEditorDir && strpos( $existing_page_content, '__NORICHEDITOR__' ) === false ) {
 1332+ $showFCKEditor = SFFormUtils::getShowFCKEditor();
 1333+ if ( !$form_submitted && ( $showFCKEditor & RTE_VISIBLE ) ) {
 1334+ $free_text = SFFormUtils::prepareTextForFCK( $free_text );
 1335+ }
 1336+ } else {
 1337+ $showFCKEditor = 0;
 1338+ }
 1339+ // now that we have it, substitute free text into the form and page
 1340+ $escaped_free_text = Sanitizer::safeEncodeAttribute( $free_text );
 1341+ $form_text = str_replace( '!free_text!', $escaped_free_text, $form_text );
 1342+ $data_text = str_replace( '!free_text!', $free_text, $data_text );
13431343
1344 - // add a warning in, if we're editing an existing page and that page
1345 - // appears to not have been created with this form
1346 - if ( $this->mPageTitle->exists() && ( $existing_page_content != '' ) && ! $source_page_matches_this_form ) {
1347 - $form_text = "\t" . '<div class="warningMessage">' . wfMsg( 'sf_formedit_formwarning', $this->mPageTitle->getFullURL() ) . "</div>\n" . $form_text;
1348 - }
 1344+ // add a warning in, if we're editing an existing page and that page
 1345+ // appears to not have been created with this form
 1346+ if ( $this->mPageTitle->exists() && ( $existing_page_content != '' ) && ! $source_page_matches_this_form ) {
 1347+ $form_text = "\t" . '<div class="warningMessage">' . wfMsg( 'sf_formedit_formwarning', $this->mPageTitle->getFullURL() ) . "</div>\n" . $form_text;
 1348+ }
13491349
1350 - // add form bottom, if no custom "standard inputs" have been defined
1351 - if ( !$this->standardInputsIncluded ) {
1352 - if ( $is_query )
1353 - $form_text .= SFFormUtils::queryFormBottom( $form_is_disabled );
1354 - else
1355 - $form_text .= SFFormUtils::formBottom( $form_is_disabled );
1356 - }
1357 - $starttime = wfTimestampNow();
1358 - $page_article = new Article( $this->mPageTitle );
1359 - $edittime = $page_article->getTimestamp();
1360 - if ( !$is_query ) {
1361 - $form_text .= <<<END
 1350+ // add form bottom, if no custom "standard inputs" have been defined
 1351+ if ( !$this->standardInputsIncluded ) {
 1352+ if ( $is_query )
 1353+ $form_text .= SFFormUtils::queryFormBottom( $form_is_disabled );
 1354+ else
 1355+ $form_text .= SFFormUtils::formBottom( $form_is_disabled );
 1356+ }
 1357+ $starttime = wfTimestampNow();
 1358+ $page_article = new Article( $this->mPageTitle );
 1359+ $edittime = $page_article->getTimestamp();
 1360+ if ( !$is_query ) {
 1361+ $form_text .= <<<END
13621362
13631363 <input type="hidden" value="$starttime" name="wpStarttime" />
13641364 <input type="hidden" value="$edittime" name="wpEdittime" />
13651365 END;
1366 - }
1367 - $form_text .= <<<END
 1366+ }
 1367+ $form_text .= <<<END
13681368 </form>
13691369
13701370 END;
13711371
1372 - // add Javascript code for form-wide use
1373 - $javascript_text = "";
1374 - if ( $free_text_was_included && $showFCKEditor > 0 ) {
1375 - $javascript_text .= SFFormUtils::mainFCKJavascript( $showFCKEditor );
1376 - if ( $showFCKEditor & ( RTE_TOGGLE_LINK | RTE_POPUP ) ) {
1377 - $javascript_text .= SFFormUTils::FCKToggleJavascript();
1378 - }
1379 - if ( $showFCKEditor & RTE_POPUP ) {
1380 - $javascript_text .= SFFormUTils::FCKPopupJavascript();
1381 - }
1382 - }
 1372+ // add Javascript code for form-wide use
 1373+ $javascript_text = "";
 1374+ if ( $free_text_was_included && $showFCKEditor > 0 ) {
 1375+ $javascript_text .= SFFormUtils::mainFCKJavascript( $showFCKEditor );
 1376+ if ( $showFCKEditor & ( RTE_TOGGLE_LINK | RTE_POPUP ) ) {
 1377+ $javascript_text .= SFFormUTils::FCKToggleJavascript();
 1378+ }
 1379+ if ( $showFCKEditor & RTE_POPUP ) {
 1380+ $javascript_text .= SFFormUTils::FCKPopupJavascript();
 1381+ }
 1382+ }
13831383
1384 - // Send the autocomplete values to the browser, along with the mappings
1385 - // of which values should apply to which fields.
1386 - // If doing a replace, the data text is actually the modified original page
1387 - if ( $wgRequest->getCheck( 'partial' ) )
1388 - $data_text = $existing_page_content;
 1384+ // Send the autocomplete values to the browser, along with the mappings
 1385+ // of which values should apply to which fields.
 1386+ // If doing a replace, the data text is actually the modified original page
 1387+ if ( $wgRequest->getCheck( 'partial' ) )
 1388+ $data_text = $existing_page_content;
13891389
1390 - global $wgParser;
1391 - $new_text = "";
1392 - if ( !$embedded ) {
1393 - $new_text = $wgParser->recursiveTagParse( str_replace( "{{!}}", "|", $form_page_title ) );
1394 - }
 1390+ global $wgParser;
 1391+ $new_text = "";
 1392+ if ( !$embedded ) {
 1393+ $new_text = $wgParser->recursiveTagParse( str_replace( "{{!}}", "|", $form_page_title ) );
 1394+ }
13951395
1396 - // If the form has already been submitted, i.e. this is just the redirect
1397 - // page, get rid of all the Javascript, to avoid JS errors.
1398 - if ( $form_submitted ) {
1399 - $javascript_text = '';
1400 - }
1401 -
1402 - return array( $form_text, $javascript_text, $data_text, $new_text, $generated_page_name );
1403 - }
 1396+ // If the form has already been submitted, i.e. this is just the redirect
 1397+ // page, get rid of all the Javascript, to avoid JS errors.
 1398+ if ( $form_submitted ) {
 1399+ $javascript_text = '';
 1400+ }
 1401+
 1402+ return array( $form_text, $javascript_text, $data_text, $new_text, $generated_page_name );
 1403+ }
14041404
1405 - /**
1406 - * Create the HTML and Javascript to display this field within a form
1407 - */
1408 - function formFieldHTML( $form_field, $cur_value ) {
1409 - global $smwgContLang;
 1405+ /**
 1406+ * Create the HTML and Javascript to display this field within a form
 1407+ */
 1408+ function formFieldHTML( $form_field, $cur_value ) {
 1409+ global $smwgContLang;
14101410
1411 - // also get the actual field, with all the semantic information (type is
1412 - // SFTemplateField, instead of SFFormField)
1413 - $template_field = $form_field->template_field;
 1411+ // also get the actual field, with all the semantic information (type is
 1412+ // SFTemplateField, instead of SFFormField)
 1413+ $template_field = $form_field->template_field;
14141414
1415 - if ( $form_field->is_hidden ) {
1416 - $text = SFFormUtils::hiddenFieldHTML( $form_field->input_name, $cur_value );
1417 - } elseif ( $form_field->input_type != '' &&
1418 - array_key_exists( $form_field->input_type, $this->mInputTypeHooks ) &&
1419 - $this->mInputTypeHooks[$form_field->input_type] != null ) {
1420 - $funcArgs = array();
1421 - $funcArgs[] = $cur_value;
1422 - $funcArgs[] = $form_field->input_name;
1423 - $funcArgs[] = $form_field->is_mandatory;
1424 - $funcArgs[] = $form_field->is_disabled;
1425 - // last argument to function should be a hash, merging the default
1426 - // values for this input type with all other properties set in
1427 - // the form definition, plus some semantic-related arguments
1428 - $hook_values = $this->mInputTypeHooks[$form_field->input_type];
1429 - $other_args = $form_field->getArgumentsForInputCall( $hook_values[1] );
1430 - $funcArgs[] = $other_args;
1431 - $text = call_user_func_array( $hook_values[0], $funcArgs );
1432 - } else { // input type not defined in form
1433 - $field_type = $template_field->field_type;
1434 - $is_list = ( $form_field->is_list || $template_field->is_list );
1435 - if ( $field_type != '' &&
1436 - array_key_exists( $field_type, $this->mSemanticTypeHooks ) &&
1437 - isset( $this->mSemanticTypeHooks[$field_type][$is_list] ) ) {
1438 - $funcArgs = array();
1439 - $funcArgs[] = $cur_value;
1440 - $funcArgs[] = $form_field->input_name;
1441 - $funcArgs[] = $form_field->is_mandatory;
1442 - $funcArgs[] = $form_field->is_disabled;
1443 - $hook_values = $this->mSemanticTypeHooks[$field_type][$is_list];
1444 - $other_args = $form_field->getArgumentsForInputCall( $hook_values[1] );
1445 - $funcArgs[] = $other_args;
1446 - $text = call_user_func_array( $hook_values[0], $funcArgs );
1447 - } else { // anything else
1448 - $other_args = $form_field->getArgumentsForInputCall();
1449 - // special call to ensure that a list input is the right default size
1450 - if ( $form_field->is_list ) {
1451 - if ( ! array_key_exists( 'size', $other_args ) ) {
1452 - $other_args['size'] = 100;
1453 - }
1454 - }
1455 - $text = SFTextInput::getHTML( $cur_value, $form_field->input_name, $form_field->is_mandatory, $form_field->is_disabled, $other_args );
1456 - }
1457 - }
1458 - return $text;
1459 - }
 1415+ if ( $form_field->is_hidden ) {
 1416+ $text = SFFormUtils::hiddenFieldHTML( $form_field->input_name, $cur_value );
 1417+ } elseif ( $form_field->input_type != '' &&
 1418+ array_key_exists( $form_field->input_type, $this->mInputTypeHooks ) &&
 1419+ $this->mInputTypeHooks[$form_field->input_type] != null ) {
 1420+ $funcArgs = array();
 1421+ $funcArgs[] = $cur_value;
 1422+ $funcArgs[] = $form_field->input_name;
 1423+ $funcArgs[] = $form_field->is_mandatory;
 1424+ $funcArgs[] = $form_field->is_disabled;
 1425+ // last argument to function should be a hash, merging the default
 1426+ // values for this input type with all other properties set in
 1427+ // the form definition, plus some semantic-related arguments
 1428+ $hook_values = $this->mInputTypeHooks[$form_field->input_type];
 1429+ $other_args = $form_field->getArgumentsForInputCall( $hook_values[1] );
 1430+ $funcArgs[] = $other_args;
 1431+ $text = call_user_func_array( $hook_values[0], $funcArgs );
 1432+ } else { // input type not defined in form
 1433+ $field_type = $template_field->field_type;
 1434+ $is_list = ( $form_field->is_list || $template_field->is_list );
 1435+ if ( $field_type != '' &&
 1436+ array_key_exists( $field_type, $this->mSemanticTypeHooks ) &&
 1437+ isset( $this->mSemanticTypeHooks[$field_type][$is_list] ) ) {
 1438+ $funcArgs = array();
 1439+ $funcArgs[] = $cur_value;
 1440+ $funcArgs[] = $form_field->input_name;
 1441+ $funcArgs[] = $form_field->is_mandatory;
 1442+ $funcArgs[] = $form_field->is_disabled;
 1443+ $hook_values = $this->mSemanticTypeHooks[$field_type][$is_list];
 1444+ $other_args = $form_field->getArgumentsForInputCall( $hook_values[1] );
 1445+ $funcArgs[] = $other_args;
 1446+ $text = call_user_func_array( $hook_values[0], $funcArgs );
 1447+ } else { // anything else
 1448+ $other_args = $form_field->getArgumentsForInputCall();
 1449+ // special call to ensure that a list input is the right default size
 1450+ if ( $form_field->is_list ) {
 1451+ if ( ! array_key_exists( 'size', $other_args ) ) {
 1452+ $other_args['size'] = 100;
 1453+ }
 1454+ }
 1455+ $text = SFTextInput::getHTML( $cur_value, $form_field->input_name, $form_field->is_mandatory, $form_field->is_disabled, $other_args );
 1456+ }
 1457+ }
 1458+ return $text;
 1459+ }
14601460
14611461 }