Yaron Koren has submitted this change and it was merged.

Change subject: Added "SFWikiPage" classes, intended for creation of page text
......................................................................


Added "SFWikiPage" classes, intended for creation of page text

Also slightly modified the relevant SF tests
Change-Id: Ia643c7ee0c8692bc18f0200de270b4c317eb2603
---
M SemanticForms.php
M extension.json
M includes/SF_FormPrinter.php
M includes/SF_FormUtils.php
M includes/SF_PageSection.php
M includes/SF_TemplateInForm.php
A includes/wikipage/SF_WikiPage.php
A includes/wikipage/SF_WikiPageFreeText.php
A includes/wikipage/SF_WikiPageSection.php
A includes/wikipage/SF_WikiPageTemplate.php
A includes/wikipage/SF_WikiPageTemplateParam.php
M tests/phpunit/includes/SF_FormPrinterTest.php
12 files changed, 423 insertions(+), 165 deletions(-)

Approvals:
  Yaron Koren: Checked; Looks good to me, approved
  jenkins-bot: Verified



diff --git a/SemanticForms.php b/SemanticForms.php
index fd6a444..3e2b6a5 100644
--- a/SemanticForms.php
+++ b/SemanticForms.php
@@ -226,6 +226,11 @@
 $GLOBALS['wgAutoloadClasses']['SFTokensInput'] = __DIR__ . 
'/includes/forminputs/SF_TokensInput.php';
 $GLOBALS['wgAutoloadClasses']['SFGoogleMapsInput'] = __DIR__ . 
'/includes/forminputs/SF_GoogleMapsInput.php';
 $GLOBALS['wgAutoloadClasses']['SFOpenLayersInput'] = __DIR__ . 
'/includes/forminputs/SF_OpenLayersInput.php';
+$GLOBALS['wgAutoloadClasses']['SFWikiPage'] = __DIR__ . 
'/includes/wikipage/SF_WikiPage.php';
+$GLOBALS['wgAutoloadClasses']['SFWikiPageTemplate'] = __DIR__ . 
'/includes/wikipage/SF_WikiPageTemplate.php';
+$GLOBALS['wgAutoloadClasses']['SFWikiPageTemplateParam'] = __DIR__ . 
'/includes/wikipage/SF_WikiPageTemplateParam.php';
+$GLOBALS['wgAutoloadClasses']['SFWikiPageSection'] = __DIR__ . 
'/includes/wikipage/SF_WikiPageSection.php';
+$GLOBALS['wgAutoloadClasses']['SFWikiPageFreeText'] = __DIR__ . 
'/includes/wikipage/SF_WikiPageFreeText.php';
 
 $GLOBALS['wgJobClasses']['createPage'] = 'SFCreatePageJob';
 $GLOBALS['wgAutoloadClasses']['SFCreatePageJob'] = __DIR__ . 
'/includes/SF_CreatePageJob.php';
diff --git a/extension.json b/extension.json
index 5c797ed..4266314 100644
--- a/extension.json
+++ b/extension.json
@@ -114,6 +114,11 @@
                "SFTokensInput": "includes/forminputs/SF_TokensInput.php",
                "SFGoogleMapsInput": 
"includes/forminputs/SF_GoogleMapsInput.php",
                "SFOpenLayersInput": 
"includes/forminputs/SF_OpenLayersInput.php",
+               "SFWikiPage": "includes/wikipage/SF_WikiPage.php",
+               "SFWikiPageTemplate": 
"includes/wikipage/SF_WikiPageTemplate.php",
+               "SFWikiPageTemplateParam": 
"includes/wikipage/SF_WikiPageTemplateParam.php",
+               "SFWikiPageSection": "includes/wikipage/SF_WikiPageSection.php",
+               "SFWikiPageFreeText": 
"includes/wikipage/SF_WikiPageFreeText.php",
                "SFCreatePageJob": "includes/SF_CreatePageJob.php",
                "SF_Language": "languages/SF_Language.php"
        },
diff --git a/includes/SF_FormPrinter.php b/includes/SF_FormPrinter.php
index bcef713..10ec236 100644
--- a/includes/SF_FormPrinter.php
+++ b/includes/SF_FormPrinter.php
@@ -272,10 +272,6 @@
                return $templateName . '___' . $fieldName;
        }
 
-       static function makePlaceholderInWikiText( $str ) {
-               return '@replace_' . $str . '@';
-       }
-
        static function makePlaceholderInFormHTML( $str ) {
                return '@insertHTML_' . $str . '@';
        }
@@ -544,6 +540,7 @@
                global $sfgFieldNum; // used for setting various HTML IDs
 
                // initialize some variables
+               $wiki_page = new SFWikiPage();
                $sfgTabIndex = 1;
                $sfgFieldNum = 1;
                $source_page_matches_this_form = false;
@@ -556,8 +553,6 @@
                // the parsing, so we have to assume that it will become a 
possibility
                $form_is_partial = false;
                $new_text = "";
-               // flag for placing "<onlyinclude>" tags in form output
-               $onlyinclude_free_text = false;
 
                // If we have existing content and we're not in an active 
replacement
                // situation, preserve the original content. We do this because 
we want
@@ -693,14 +688,12 @@
                // existing article as well, finding template and field
                // declarations and replacing them with form elements, either
                // blank or pre-populated, as appropriate.
-               $data_text = "";
                $tif = null;
                // This array will keep track of all the replaced @<name>@ 
strings
                $placeholderFields = array();
 
                for ( $section_num = 0; $section_num < count( 
$form_def_sections ); $section_num++ ) {
                        $start_position = 0;
-                       $template_text = "";
                        // the append is there to ensure that the original
                        // array doesn't get modified; is it necessary?
                        $section = " " . $form_def_sections[$section_num];
@@ -719,12 +712,11 @@
                                        } else {
                                                $previous_template_name = '';
                                        }
-                                       $template_name = $tag_components[1];
+                                       $template_name = str_replace( '_', ' ', 
$tag_components[1] );
                                        $is_new_template = ( $template_name != 
$previous_template_name );
                                        if ( $is_new_template ) {
                                                $tif = 
SFTemplateInForm::newFromFormTag( $tag_components );
                                        }
-                                       $template_text .= "{{" . 
$tif->getTemplateName();
                                        // Remove template tag.
                                        $section = substr_replace( $section, 
'', $brackets_loc, $brackets_end_loc + 3 - $brackets_loc );
                                        // If we are editing a page, and this
@@ -765,6 +757,8 @@
                                        }
 
                                        $tif->checkIfAllInstancesPrinted( 
$form_submitted, $source_is_page );
+
+                                       $wiki_page->addTemplate( $tif );
 
                                // 
=====================================================
                                // end template processing
@@ -857,8 +851,7 @@
                                                        }
                                                }
                                                $free_text_was_included = true;
-                                               // add a similar placeholder to 
the data text
-                                               $data_text .= "!free_text!\n";
+                                               
$wiki_page->addFreeTextSection();
                                        }
 
                                        if ( $tif->getTemplateName() === '' || 
$field_name == '<freetext>' ) {
@@ -950,13 +943,6 @@
                                                        $cur_value = 
$cur_value_in_template;
                                                }
 
-                                               // Generate a hidden field with 
a placeholder value that will be replaced
-                                               // by the multiple-instances 
template output at form submission.
-                                               //// <input type="hidden" 
value="@replace_Town___mayors@" name="Town[town_mayors]" />
-                                               if ( 
$form_field->holdsTemplate() ) {
-                                                       $cur_value = 
self::makePlaceholderInWikiText( self::placeholderFormat( 
$tif->getTemplateName(), $field_name ) );
-                                               }
-
                                                // If all instances have been
                                                // printed, that means we're
                                                // now printing a "starter"
@@ -973,15 +959,7 @@
                                                $new_text .= 
$form_field->additionalHTMLForInput( $cur_value, $field_name, 
$tif->getTemplateName() );
 
                                                if ( $new_text ) {
-                                                       // Include the field 
name only for non-numeric field names.
-                                                       if ( is_numeric( 
$field_name ) ) {
-                                                               $template_text 
.= "|$cur_value_in_template";
-                                                       } else {
-                                                               // If the value 
is null, don't include it at all.
-                                                               if ( 
$cur_value_in_template != '' ) {
-                                                                       
$template_text .= "\n|$field_name=$cur_value_in_template";
-                                                               }
-                                                       }
+                                                       
$wiki_page->addTemplateParam( $template_name, $tif->getInstanceNum(), 
$field_name, $cur_value_in_template );
                                                        $section = 
substr_replace( $section, $new_text, $brackets_loc, $brackets_end_loc + 3 - 
$brackets_loc );
                                                } else {
                                                        $start_position = 
$brackets_end_loc;
@@ -1093,11 +1071,6 @@
                                                }
                                        }
 
-                                       // Generate the wikitext for the 
section header
-                                       $header_string = str_repeat( "=", 
$header_level );
-                                       $header_text = $header_string . 
$section_name . $header_string . "\n";
-                                       $data_text .= $header_text;
-
                                        // split the existing page contents 
into the textareas in the form
                                        $default_value = "";
                                        $section_start_loc = 0;
@@ -1141,14 +1114,9 @@
                                        //if input is from the form
                                        $section_text = "";
                                        if ( ( ! $source_is_page ) && 
$wgRequest ) {
-                                               $section_text = 
$wgRequest->getArray( '_section' );
-                                               $default_value = 
$section_text[trim( $section_name )];
-
-                                               if ( $default_value == "" || 
$default_value == null ) {
-                                                       $data_text .= 
$default_value . "\n\n";
-                                               } else {
-                                                       $data_text .= rtrim( 
$default_value ) . "\n\n";
-                                               }
+                                               $text_per_section = 
$wgRequest->getArray( '_section' );
+                                               $section_text = 
$text_per_section[trim( $section_name )];
+                                               $wiki_page->addSection( 
$section_name, $header_level, $section_text );
                                        }
 
                                        //set input name for query string
@@ -1196,7 +1164,7 @@
                                                        // replacement pages 
may have minimal matches...
                                                        
$source_page_matches_this_form = true;
                                                } elseif ( $tag == 'includeonly 
free text' || $tag == 'onlyinclude free text' ) {
-                                                       $onlyinclude_free_text 
= true;
+                                                       
$wiki_page->makeFreeTextOnlyInclude();
                                                } elseif ( $tag == 'query form 
at top' ) {
                                                        // TODO - this should 
be made a field of
                                                        // some non-static 
class that actually
@@ -1216,55 +1184,22 @@
                                } // end if
                        } // end while
 
-                       if ( !$tif || !$tif->allInstancesPrinted() ) {
-                               if ( $template_text !== '' ) {
-                                       // For mostly aesthetic purposes, if 
the template call ends with
-                                       // a bunch of pipes (i.e., it's an 
indexed template with unused
-                                       // parameters at the end), remove the 
pipes.
-                                       $template_text = preg_replace( 
'/\|*$/', '', $template_text );
-                                       // add another newline before the final 
bracket, if this template
-                                       // call is already more than one line
-                                       if ( strpos( $template_text, "\n" ) ) {
-                                               $template_text .= "\n";
-                                       }
-                                       // If we're editing an existing page, 
and there were fields in
-                                       // the template call not handled by 
this form, preserve those.
-                                       if ( !$tif->allowsMultiple() ) {
-                                               $template_text .= 
SFFormUtils::addUnhandledFields( $tif->getTemplateName() );
-                                       }
-                                       $template_text .= "}}";
-
-                                       // The base $template_text will contain 
strings like "@replace_xxx@"
-                                       // in the hidden fields when the form 
is submitted.
-                                       // On the following loops, the text for 
the multiple-instance templates
-                                       // is progressively reinserted in the 
main data, always keeping a
-                                       // trailing @replace_xxx@ for a given 
field
-                                       // The trailing @replace_xxx@ is then 
deleted at the end.
-                                       // Note: this cleanup step could also 
be done with a regexp, instead of
-                                       // keeping a track array (e.g., 
/@replace_(.*)@/)
-                                       $reptmp = 
self::makePlaceholderInWikiText( $tif->getPlaceholder() );
-                                       if ( $tif->getPlaceholder() != null && 
$data_text && strpos( $data_text, $reptmp, 0 ) !== false ) {
-                                               $data_text = str_replace( 
$reptmp, $template_text . $reptmp, $data_text );
-                                       } else {
-                                               $data_text .= $template_text . 
"\n";
-                                       }
-
-                                       // If there is a placeholder in the
-                                       // text, we know that we are
-                                       // doing a replace.
-                                       if ( $existing_page_content && strpos( 
$existing_page_content, '{{{insertionpoint}}}', 0 ) !== false ) {
-                                               $existing_page_content = 
preg_replace( '/\{\{\{insertionpoint\}\}\}(\r?\n?)/',
-                                                       preg_replace( 
'/\}\}/m', '}�',
-                                                               preg_replace( 
'/\{\{/m', '�{', $template_text ) ) .
-                                                       
"\n{{{insertionpoint}}}",
-                                                       $existing_page_content 
);
-                                       // Otherwise, if it's a partial form, 
we have to add the new
-                                       // text somewhere.
-                                       } elseif ( $form_is_partial && 
$wgRequest->getCheck( 'partial' ) ) {
-                                               $existing_page_content = 
preg_replace( '/\}\}/m', '}�',
+                       if ( $tif && ( !$tif->allowsMultiple() || 
$tif->allInstancesPrinted() ) ) {
+                               $template_text = 
$wiki_page->createTemplateCallsForTemplateName( $tif->getTemplateName() );
+                               // If there is a placeholder in the text, we
+                               // know that we are doing a replace.
+                               if ( $existing_page_content && strpos( 
$existing_page_content, '{{{insertionpoint}}}', 0 ) !== false ) {
+                                       $existing_page_content = preg_replace( 
'/\{\{\{insertionpoint\}\}\}(\r?\n?)/',
+                                               preg_replace( '/\}\}/m', '}�',
                                                        preg_replace( 
'/\{\{/m', '�{', $template_text ) ) .
-                                                               
"{{{insertionpoint}}}" . $existing_page_content;
-                                       }
+                                               "\n{{{insertionpoint}}}",
+                                               $existing_page_content );
+                               // Otherwise, if it's a partial form, we have 
to add the new
+                               // text somewhere.
+                               } elseif ( $form_is_partial && 
$wgRequest->getCheck( 'partial' ) ) {
+                                       $existing_page_content = preg_replace( 
'/\}\}/m', '}�',
+                                               preg_replace( '/\{\{/m', '�{', 
$template_text ) ) .
+                                                       "{{{insertionpoint}}}" 
. $existing_page_content;
                                }
                        }
 
@@ -1279,13 +1214,14 @@
                                } else {
                                        $multipleTemplateHTML .= 
$this->multipleTemplateEndHTML( $tif, $form_is_disabled, $section );
                                }
-                               if ( $tif->getPlaceholder() != null ) {
-                                       $multipleTemplateHTML .= 
self::makePlaceholderInFormHTML( $tif->getPlaceholder() );
+                               $placeholder = $tif->getPlaceholder();
+                               if ( $placeholder != null ) {
+                                       $multipleTemplateHTML .= 
self::makePlaceholderInFormHTML( $placeholder );
                                }
                                if ( $tif->allInstancesPrinted() && 
$tif->getLabel() != null ) {
                                        $multipleTemplateHTML .= 
"</fieldset>\n";
                                }
-                               if ( $tif->getPlaceholder() == null ) {
+                               if ( $placeholder == null ) {
                                        // The normal process.
                                        $form_text .= $multipleTemplateHTML;
                                } else {
@@ -1304,7 +1240,7 @@
                                        // We replace the HTML into the current
                                        // placeholder tag, but also add another
                                        // placeholder tag, to keep track of it.
-                                       $form_text = str_replace( 
self::makePlaceholderInFormHTML( $tif->getPlaceholder() ), 
$multipleTemplateHTML, $form_text );
+                                       $form_text = str_replace( 
self::makePlaceholderInFormHTML( $placeholder ), $multipleTemplateHTML, 
$form_text );
                                }
                                if ( ! $tif->allInstancesPrinted() ) {
                                        // This will cause the section to be
@@ -1321,11 +1257,6 @@
                // Remove all the remaining placeholder
                // tags in the HTML and wiki-text.
                foreach ( $placeholderFields as $stringToReplace ) {
-
-                       // Remove the @<replacename>@ tags from the data that
-                       // is submitted.
-                       $data_text = str_replace( 
self::makePlaceholderInWikiText( $stringToReplace ), '', $data_text );
-
                        // Remove the @<insertHTML>@ tags from the generated
                        // HTML form.
                        $form_text = str_replace( 
self::makePlaceholderInFormHTML( $stringToReplace ), '', $form_text );
@@ -1362,18 +1293,19 @@
                } elseif ( $wgRequest->getCheck( 'sf_free_text' ) ) {
                        $free_text = $wgRequest->getVal( 'sf_free_text' );
                        if ( ! $free_text_was_included ) {
-                               $data_text .= "!free_text!";
+                               $wiki_page->addFreeTextSection();
                        }
                } else {
                        $free_text = null;
                }
-               if ( $onlyinclude_free_text ) {
-                       // modify free text and data text to insert 
<onlyinclude> tags
+
+               if ( $wiki_page->freeTextOnlyInclude() ) {
                        $free_text = str_replace( "<onlyinclude>", '', 
$free_text );
                        $free_text = str_replace( "</onlyinclude>", '', 
$free_text );
                        $free_text = trim( $free_text );
-                       $data_text = str_replace( '!free_text!', 
'<onlyinclude>!free_text!</onlyinclude>', $data_text );
                }
+
+               $page_text = '';
 
                // The first hook here is deprecated. Use the second.
                // Note: Hooks::run can take a third argument which indicates
@@ -1381,12 +1313,16 @@
                // an extension version.
                Hooks::run( 'sfModifyFreeTextField', array( &$free_text, 
$existing_page_content ) );
                Hooks::run( 'sfBeforeFreeTextSubstitution',
-                       array( &$free_text, $existing_page_content, &$data_text 
) );
+                       array( &$free_text, $existing_page_content, &$page_text 
) );
 
-               // now that we have it, substitute free text into the form and 
page
+               // Now that we have it, add free text to the page, and
+               // substitute it into the form.
+               if ( $form_submitted ) {
+                       $wiki_page->setFreeText( $free_text );
+                       $page_text = $wiki_page->createPageText();
+               }
                $escaped_free_text = Sanitizer::safeEncodeAttribute( $free_text 
);
                $form_text = str_replace( '!free_text!', $escaped_free_text, 
$form_text );
-               $data_text = str_replace( '!free_text!', $free_text, $data_text 
);
 
                // Add a warning in, if we're editing an existing page and that
                // page appears to not have been created with this form.
@@ -1425,10 +1361,10 @@
 
                // Send the autocomplete values to the browser, along with the
                // mappings of which values should apply to which fields.
-               // If doing a replace, the data text is actually the modified
+               // If doing a replace, the page text is actually the modified
                // original page.
                if ( $wgRequest->getCheck( 'partial' ) ) {
-                       $data_text = $existing_page_content;
+                       $page_text = $existing_page_content;
                }
 
                if ( !$is_embedded ) {
@@ -1446,7 +1382,7 @@
 
 //             $wgParser = $oldParser;
 
-               return array( $form_text, $javascript_text, $data_text, 
$form_page_title, $generated_page_name );
+               return array( $form_text, $javascript_text, $page_text, 
$form_page_title, $generated_page_name );
        }
 
        /**
diff --git a/includes/SF_FormUtils.php b/includes/SF_FormUtils.php
index 6566b74..a93b2c3 100644
--- a/includes/SF_FormUtils.php
+++ b/includes/SF_FormUtils.php
@@ -50,26 +50,6 @@
                return $text;
        }
 
-       /**
-        * Add unhandled fields back into the template call that the form
-        * generates, so that editing with a form will have no effect on them
-        */
-       static function addUnhandledFields( $templateName ) {
-               global $wgRequest;
-
-               $templateName = str_replace( ' ', '_', $templateName );
-               $prefix = '_unhandled_' . $templateName . '_';
-               $prefixSize = strlen( $prefix );
-               $additional_template_text = "";
-               foreach ( $wgRequest->getValues() as $key => $value ) {
-                       if ( strpos( $key, $prefix ) === 0 ) {
-                               $field_name = urldecode( substr( $key, 
$prefixSize ) );
-                               $additional_template_text .= 
"|$field_name=$value\n";
-                       }
-               }
-               return $additional_template_text;
-       }
-
        static function summaryInputHTML( $is_disabled, $label = null, $attr = 
array(), $value = '' ) {
                global $sfgTabIndex;
 
diff --git a/includes/SF_PageSection.php b/includes/SF_PageSection.php
index f7773fd..f35ed88 100644
--- a/includes/SF_PageSection.php
+++ b/includes/SF_PageSection.php
@@ -1,6 +1,9 @@
 <?php
 /**
  * Represents a page section in a user-defined form.
+ * This class should really be called "SFPageSectionInForm", to differentiate
+ * it from the SFWikiPageSection class.
+ *
  * @author Himeshi
  * @file
  * @ingroup SF
diff --git a/includes/SF_TemplateInForm.php b/includes/SF_TemplateInForm.php
index eab14fe..1fad687 100644
--- a/includes/SF_TemplateInForm.php
+++ b/includes/SF_TemplateInForm.php
@@ -14,6 +14,8 @@
        private $mMinAllowed;
        private $mMaxAllowed;
        private $mFields;
+       private $mEmbedInTemplate;
+       private $mEmbedInField;
 
        private $mSearchTemplateStr;
        private $mPregMatchTemplateStr;
@@ -284,6 +286,14 @@
                return $this->mFields;
        }
 
+       function getEmbedInTemplate() {
+               return $this->mEmbedInTemplate;
+       }
+
+       function getEmbedInField() {
+               return $this->mEmbedInField;
+       }
+
        function getLabel() {
                return $this->mLabel;
        }
@@ -349,7 +359,7 @@
        public static function newFromFormTag( $tag_components ) {
                global $wgParser;
 
-               $template_name = trim( $tag_components[1] );
+               $template_name = str_replace( '_', ' ', trim( 
$tag_components[1] ) );
                $tif = SFTemplateInForm::create( $template_name );
                $tif->mAddButtonText = wfMessage( 'sf_formedit_addanother' 
)->text();
                // Cycle through the other components.
@@ -376,7 +386,11 @@
                                        // We expect something like 
TemplateName[fieldName], and convert it to the
                                        // TemplateName___fieldName form used 
internally.
                                        preg_match( '/\s*(.*)\[(.*)\]\s*/', 
$sub_components[1], $matches );
-                                       $tif->mPlaceholder = ( count( $matches 
) > 2 ) ? SFFormPrinter::placeholderFormat( $matches[1], $matches[2] ) : null;
+                                       if ( count( $matches ) > 2 ) {
+                                               $tif->mEmbedInTemplate = 
$matches[1];
+                                               $tif->mEmbedInField = 
$matches[2];
+                                               $tif->mPlaceholder = 
SFFormPrinter::placeholderFormat( $tif->mEmbedInTemplate, $tif->mEmbedInField );
+                                       }
                                }
                        }
                }
@@ -416,7 +430,7 @@
                        if ( $this->mNumInstancesFromSubmit > 
$this->mInstanceNum ) {
                                $instanceKey = 
$valuesFromSubmitKeys[$this->mInstanceNum];
                                $this->mValuesFromSubmit = 
$allValuesFromSubmit[$instanceKey];
-                       }
+                       }
                } else {
                        $this->mValuesFromSubmit = $allValuesFromSubmit;
                }
@@ -513,30 +527,30 @@
                $this->mPageCallsThisTemplate = preg_match( '/{{' . 
$this->mPregMatchTemplateStr . '\s*[\|}]/i', str_replace( '_', ' ', 
$existing_page_content ) );
        }
 
-       function checkIfAllInstancesPrinted( $form_submitted, $source_is_page ) 
{
-               // Find instances of this template in the page -
-               // if there's at least one, re-parse this section of the
-               // definition form for the subsequent template instances in
-               // this page; if there's none, don't include fields at all.
-               // @TODO - There has to be a more efficient way to handle
-               // multiple instances of templates, one that doesn't involve
-               // re-parsing the same tags, but I don't know what it is.
-               // (Also add additional, blank instances if there's a minimum
-               // number required in this form, and we haven't reached it yet.)
-               if ( !$this->mAllowMultiple ) {
-                       return;
-               }
-               if ( $this->mInstanceNum < $this->mMinAllowed ) {
-                       return;
-               }
-               if ( $form_submitted && $this->mInstanceNum < 
$this->mNumInstancesFromSubmit ) {
-                       return;
-               }
-               if ( !$form_submitted && $source_is_page && 
$this->mPageCallsThisTemplate ) {
-                       return;
-               }
-               $this->mAllInstancesPrinted = true;
-       }
+       function checkIfAllInstancesPrinted( $form_submitted, $source_is_page ) 
{
+               // Find instances of this template in the page -
+               // if there's at least one, re-parse this section of the
+               // definition form for the subsequent template instances in
+               // this page; if there's none, don't include fields at all.
+               // @TODO - There has to be a more efficient way to handle
+               // multiple instances of templates, one that doesn't involve
+               // re-parsing the same tags, but I don't know what it is.
+               // (Also add additional, blank instances if there's a minimum
+               // number required in this form, and we haven't reached it yet.)
+               if ( !$this->mAllowMultiple ) {
+                       return;
+               }
+               if ( $this->mInstanceNum < $this->mMinAllowed ) {
+                       return;
+               }
+               if ( $form_submitted && $this->mInstanceNum < 
$this->mNumInstancesFromSubmit ) {
+                       return;
+               }
+               if ( !$form_submitted && $source_is_page && 
$this->mPageCallsThisTemplate ) {
+                       return;
+               }
+               $this->mAllInstancesPrinted = true;
+       }
 
        function creationHTML( $template_num ) {
                $checked_attribs = ( $this->mAllowMultiple ) ? array( 'checked' 
=> 'checked' ) : array();
diff --git a/includes/wikipage/SF_WikiPage.php 
b/includes/wikipage/SF_WikiPage.php
new file mode 100644
index 0000000..54120cf
--- /dev/null
+++ b/includes/wikipage/SF_WikiPage.php
@@ -0,0 +1,183 @@
+<?php
+/**
+ * @author Yaron Koren
+ * @file
+ * @ingroup SF
+ */
+
+/**
+ * Represents the structured contents of a wiki page.
+ */
+class SFWikiPage {
+       private $mComponents = array();
+       private $mEmbeddedTemplateDefs = array();
+       private $mEmbeddedTemplateCalls = array();
+       private $mFreeTextOnlyInclude = false;
+
+       function addTemplate( $templateInForm ) {
+               if ( $templateInForm->allInstancesPrinted() ) {
+                       return;
+               }
+
+               $templateName = $templateInForm->getTemplateName();
+               $this->mComponents[] = new SFWikiPageTemplate( $templateName, 
!$templateInForm->allowsMultiple() );
+               if ( $templateInForm->getInstanceNum() == 0 ) {
+                       $embedInTemplate = 
$templateInForm->getEmbedInTemplate();
+                       $embedInParam = $templateInForm->getEmbedInField();
+                       if ( $embedInTemplate != null && $embedInParam != null 
) {
+                               $this->mEmbeddedTemplateDefs[] = array( 
$embedInTemplate, $embedInParam, $templateName );
+                       }
+               }
+       }
+
+       function addTemplateParam( $templateName, $instanceNum, $paramName, 
$value ) {
+               $curInstance = 0;
+               foreach ( $this->mComponents as $i => $component ) {
+                       if ( get_class( $component ) == 'SFWikiPageTemplate' && 
$component->getName() == $templateName ) {
+                               if ( $curInstance++ == $instanceNum ) {
+                                       $this->mComponents[$i]->addParam( 
$paramName, $value );
+                                       return;
+                               }
+                       }
+               }
+       }
+
+       function getEmbeddedTemplateForParam( $templateName, $paramName ) {
+               foreach ( $this->mEmbeddedTemplateDefs as $etd ) {
+                       if ( $etd[0] == $templateName && $etd[1] == $paramName 
) {
+                               return $etd[2];
+                       }
+               }
+               return null;
+       }
+
+       function addSection( $sectionName, $headerLevel, $sectionText ) {
+               $this->mComponents[] = new SFWikiPageSection( $sectionName, 
$headerLevel, $sectionText );
+       }
+
+       function addFreeTextSection() {
+               $this->mComponents[] = new SFWikiPageFreeText();
+       }
+
+       function setFreeText( $text ) {
+               foreach ( $this->mComponents as $i => $component ) {
+                       if ( get_class( $component ) == 'SFWikiPageFreeText' ) {
+                               $this->mComponents[$i]->setText( $text );
+                       }
+               }
+               // Throw an exception here if no free text section found?
+       }
+
+       function makeFreeTextOnlyInclude() {
+               $this->mFreeTextOnlyInclude = true;
+       }
+
+       function freeTextOnlyInclude() {
+               return $this->mFreeTextOnlyInclude;
+       }
+
+       /**
+        * Create an array of the template calls in the page that are embedded
+        * in other templates.
+        */
+       private function findEmbeddedTemplates() {
+               foreach ( $this->mEmbeddedTemplateDefs as $etd ) {
+                       $embeddedTemplateName = $etd[2];
+                       foreach ( $this->mComponents as $component ) {
+                               if ( get_class( $component ) == 
'SFWikiPageTemplate' ) {
+                                       if ( $embeddedTemplateName == 
$component->getName() ) {
+                                               if ( !array_key_exists( 
$embeddedTemplateName, $this->mEmbeddedTemplateCalls ) ) {
+                                                       
$this->mEmbeddedTemplateCalls[$embeddedTemplateName] = array();
+                                               }
+                                               
$this->mEmbeddedTemplateCalls[$embeddedTemplateName][] = $component;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       function createTemplateCall( $template ) {
+               $template->addUnhandledParams();
+
+               $templateCall = '{{' . $template->getName();
+               foreach( $template->getParams() as $templateParam ) {
+                       $paramName = $templateParam->getName();
+                       $embeddedTemplateName = 
$this->getEmbeddedTemplateForParam( $template->getName(), $paramName );
+                       $paramValue = $templateParam->getValue();
+
+                       // If there's no value, skip this param.
+                       if ( $embeddedTemplateName == '' && $paramValue == '' ) 
{
+                               continue;
+                       }
+
+                       // Include the field name only for non-numeric field 
names.
+                       if ( is_numeric( $paramName ) ) {
+                               $templateCall .= '|';
+                       } else {
+                               $templateCall .= "\n|$paramName=";
+                       }
+                       if ( $embeddedTemplateName != '' ) {
+                               foreach ( 
$this->mEmbeddedTemplateCalls[$embeddedTemplateName] as $embeddedTemplate ) {
+                                       $templateCall .= 
$this->createTemplateCall( $embeddedTemplate );
+                               }
+                       } else {
+                               $templateCall .= $paramValue;
+                       }
+               }
+               // For mostly aesthetic purposes, if the template call ends with
+               // a bunch of pipes (i.e., it's an indexed template with unused
+               // parameters at the end), remove the pipes.
+               $templateCall = preg_replace( '/\|*$/', '', $templateCall );
+
+               // Add another newline before the final bracket, if this
+               // template call is already more than one line
+               if ( strpos( $templateCall, "\n" ) ) {
+                       $templateCall .= "\n";
+               }
+               $templateCall .= "}}";
+
+               return $templateCall;
+       }
+
+       function createTemplateCallsForTemplateName( $templateName ) {
+               $text = '';
+               foreach ( $this->mComponents as $component ) {
+                       if ( get_class( $component ) == 'SFWikiPageTemplate' ) {
+                               if ( $component->getName() == $templateName ) {
+                                       $text .= $this->createTemplateCall( 
$component ) . "\n";
+                               }
+                       }
+               }
+               return $text;
+       }
+
+       function createPageText() {
+               // First, go through and store the templates that are embedded,
+               // so that they can have special printing.
+               $this->findEmbeddedTemplates();
+
+               // Now create the text.
+               $pageText = '';
+               foreach ( $this->mComponents as $component ) {
+                       if ( get_class( $component ) == 'SFWikiPageTemplate' ) {
+                               if ( !array_key_exists( $component->getName(), 
$this->mEmbeddedTemplateCalls ) ) {
+                                       $pageText .= $this->createTemplateCall( 
$component ) . "\n";
+                               }
+                       } elseif ( get_class( $component ) == 
'SFWikiPageSection' ) {
+                               $sectionName = $component->getHeader();
+                               for ( $i = 0; $i < 
$component->getHeaderLevel(); $i++ ) {
+                                       $sectionName = "=$sectionName=";
+                               }
+                               $pageText .= "$sectionName\n";
+                               $pageText .= $component->getText() . "\n";
+                       } elseif ( get_class( $component ) == 
'SFWikiPageFreeText' ) {
+                               $freeText = $component->getText();
+                               if ( $this->mFreeTextOnlyInclude ) {
+                                       $freeText = 
"<onlyinclude>$freeText</onlyinclude>";
+                               }
+                               $pageText .= "$freeText\n";
+                       }
+               }
+               return $pageText;
+       }
+}
diff --git a/includes/wikipage/SF_WikiPageFreeText.php 
b/includes/wikipage/SF_WikiPageFreeText.php
new file mode 100644
index 0000000..db1c3f1
--- /dev/null
+++ b/includes/wikipage/SF_WikiPageFreeText.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @author Yaron Koren
+ * @file
+ * @ingroup SF
+ */
+
+/**
+ * Represents the "free text" in a wiki page, i.e. the text not in
+ * pre-defined template calls and sections.
+ */
+class SFWikiPageFreeText {
+       private $mText;
+
+       function setText( $text ) {
+               $this->mText = $text;
+       }
+
+       function getText() {
+               return $this->mText;
+       }
+}
diff --git a/includes/wikipage/SF_WikiPageSection.php 
b/includes/wikipage/SF_WikiPageSection.php
new file mode 100644
index 0000000..bef2143
--- /dev/null
+++ b/includes/wikipage/SF_WikiPageSection.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * @author Yaron Koren
+ * @file
+ * @ingroup SF
+ */
+
+/**
+ * Represents a section (header and contents) in a wiki page.
+ */
+class SFWikiPageSection {
+       private $mHeader, $mHeaderLevel, $mText;
+
+       function __construct( $sectionName, $headerLevel, $sectionText ) {
+               $this->mHeader = $sectionName;
+               $this->mHeaderLevel = $headerLevel;
+               $this->mText = $sectionText;
+       }
+
+       function getHeader() {
+               return $this->mHeader;
+       }
+
+       function getHeaderLevel() {
+               return $this->mHeaderLevel;
+       }
+
+       function getText() {
+               return $this->mText;
+       }
+}
diff --git a/includes/wikipage/SF_WikiPageTemplate.php 
b/includes/wikipage/SF_WikiPageTemplate.php
new file mode 100644
index 0000000..c38361e
--- /dev/null
+++ b/includes/wikipage/SF_WikiPageTemplate.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @author Yaron Koren
+ * @file
+ * @ingroup SF
+ */
+
+/**
+ * Represents a single template call within a wiki page.
+ */
+class SFWikiPageTemplate {
+       private $mName;
+       private $mParams = array();
+       private $mAddUnhandledParams;
+
+       function __construct( $name, $addUnhandledParams ) {
+               $this->mName = $name;
+               $this->mAddUnhandledParams = $addUnhandledParams;
+       }
+
+       function addParam( $paramName, $value ) {
+               $this->mParams[] = new SFWikiPageTemplateParam( $paramName, 
$value );
+       }
+
+       function addUnhandledParams() {
+               global $wgRequest;
+
+               if ( !$this->mAddUnhandledParams ) {
+                       return;
+               }
+
+               $templateName = str_replace( ' ', '_', $this->mName );
+               $prefix = '_unhandled_' . $templateName . '_';
+               $prefixSize = strlen( $prefix );
+               foreach ( $wgRequest->getValues() as $key => $value ) {
+                       if ( strpos( $key, $prefix ) === 0 ) {
+                               $paramName = urldecode( substr( $key, 
$prefixSize ) );
+                               $this->addParam( $paramName, $value );
+                       }
+               }
+
+       }
+
+       function getName() {
+               return $this->mName;
+       }
+
+       function getParams() {
+               return $this->mParams;
+       }
+}
diff --git a/includes/wikipage/SF_WikiPageTemplateParam.php 
b/includes/wikipage/SF_WikiPageTemplateParam.php
new file mode 100644
index 0000000..b2b58a6
--- /dev/null
+++ b/includes/wikipage/SF_WikiPageTemplateParam.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * @author Yaron Koren
+ * @file
+ * @ingroup SF
+ */
+
+/**
+ * Represents a single parameter (name and value) within a template call
+ * in a wiki page.
+ */
+class SFWikiPageTemplateParam {
+       private $mName;
+       private $mValue;
+
+       function __construct( $name, $value ) {
+               $this->mName = $name;
+               $this->mValue = $value;
+       }
+
+       function getName() {
+               return $this->mName;
+       }
+
+       function getValue() {
+               return $this->mValue;
+       }
+}
diff --git a/tests/phpunit/includes/SF_FormPrinterTest.php 
b/tests/phpunit/includes/SF_FormPrinterTest.php
index b759aa4..04f15a9 100644
--- a/tests/phpunit/includes/SF_FormPrinterTest.php
+++ b/tests/phpunit/includes/SF_FormPrinterTest.php
@@ -19,8 +19,8 @@
                $wgTitle = $this->getTitle();
                $wgOut->getContext()->setTitle( $wgTitle );
 
-               list ( $form_text, $javascript_text, $data_text, 
$form_page_title, $generated_page_name ) =
-                       $sfgFormPrinter->formHTML( $setup['form_definition'], 
null, false, null, null, 'TestStringForFormPageTitle', null );
+               list ( $form_text, $javascript_text, $page_text, 
$form_page_title, $generated_page_name ) =
+                       $sfgFormPrinter->formHTML( $setup['form_definition'], 
true, false, null, null, 'TestStringForFormPageTitle', null );
 
                $this->assertContains(
                        $expected['expected_form_text'],
@@ -28,8 +28,8 @@
                        'asserts that formHTML() returns the correct HTML text 
for the form for the given test input'
                        );
                $this->assertContains(
-                       $expected['expected_data_text'],
-                       $data_text,
+                       $expected['expected_page_text'],
+                       $page_text,
                        'assert that formHTML() returns the correct text for 
the page created by the form'
                        );
 
@@ -49,7 +49,7 @@
                                                                 
{{{section|section1|level=2}}}" ),
                array(
                        'expected_form_text' => "<span class=\"inputSpan 
pageSection\"><textarea tabindex=\"1\" name=\"_section[section1]\" 
id=\"input_1\" class=\"createboxInput\" rows=\"5\" cols=\"90\" style=\"width: 
100%\"></textarea></span>",
-                       'expected_data_text' => "==section1==" )
+                       'expected_page_text' => "==section1==" )
                );
 
                // #2 'rows' and 'colums' parameters set
@@ -59,7 +59,7 @@
                                                                 
{{{section|section 2|level=5|rows=10|cols=5}}}" ),
                array(
                        'expected_form_text' => "<span class=\"inputSpan 
pageSection\"><textarea tabindex=\"1\" name=\"_section[section 2]\" 
id=\"input_1\" class=\"createboxInput\" rows=\"10\" cols=\"5\" style=\"width: 
auto\"></textarea></span>",
-                       'expected_data_text' => "=====section 2=====" )
+                       'expected_page_text' => "=====section 2=====" )
                );
 
                // #3 'mandatory' and 'autogrow' parameters set
@@ -69,7 +69,7 @@
                                                                 
{{{section|section 3|level=2|mandatory|rows=20|cols=50|autogrow}}}" ),
                array(
                        'expected_form_text' => "<span class=\"inputSpan 
pageSection mandatoryFieldSpan\"><textarea tabindex=\"1\" 
name=\"_section[section 3]\" id=\"input_1\" class=\"mandatoryField autoGrow\" 
rows=\"20\" cols=\"50\" style=\"width: auto\"></textarea></span>",
-                       'expected_data_text' => "==section 3==" )
+                       'expected_page_text' => "==section 3==" )
                );
 
                // #4 'restricted' parameter set
@@ -79,7 +79,7 @@
                                                                 
{{{section|Section 5|level=3|restricted|class=FormTest}}}" ),
                array(
                        'expected_form_text' => "<span class=\"inputSpan 
pageSection\"><textarea tabindex=\"1\" name=\"_section[Section 5]\" 
id=\"input_1\" class=\"createboxInput FormTest\" rows=\"5\" cols=\"90\" 
style=\"width: 100%\" disabled=\"\"></textarea></span>",
-                       'expected_data_text' => "===Section 5===" )
+                       'expected_page_text' => "===Section 5===" )
                );
 
                // #5 'hidden' parameter set
@@ -89,7 +89,7 @@
                                                                 
{{{section|section 4|level=4|hidden}}}" ),
                array(
                        'expected_form_text' => "<input type=\"hidden\" 
name=\"_section[section 4]\" />",
-                       'expected_data_text' => "====section 4====" )
+                       'expected_page_text' => "====section 4====" )
                );
 
        return $provider;

-- 
To view, visit https://gerrit.wikimedia.org/r/266458
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ia643c7ee0c8692bc18f0200de270b4c317eb2603
Gerrit-PatchSet: 5
Gerrit-Project: mediawiki/extensions/SemanticForms
Gerrit-Branch: master
Gerrit-Owner: Yaron Koren <yaro...@gmail.com>
Gerrit-Reviewer: Yaron Koren <yaro...@gmail.com>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to