Joeytje50 has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/360803 )

Change subject: Working += and -= functionality.
......................................................................

Working += and -= functionality.

This allows you to add and remove items from a comma-separated list. It
has to be comma-separated, but other separators may be supported later
(perhaps it would be possible to specify the separator in the #autoedit
parser-function itself).

Change-Id: I5b62232fc790c33390f8e2f47096ba028b0aa268
---
M includes/PF_FormField.php
M includes/PF_FormPrinter.php
M includes/PF_ParserFunctions.php
M includes/PF_TemplateInForm.php
4 files changed, 94 insertions(+), 44 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/PageForms 
refs/changes/03/360803/1

diff --git a/includes/PF_FormField.php b/includes/PF_FormField.php
index 0dcff50..7766101 100644
--- a/includes/PF_FormField.php
+++ b/includes/PF_FormField.php
@@ -422,26 +422,27 @@
                return $f;
        }
 
-       function getCurrentValue( $template_instance_query_values, 
$form_submitted, $source_is_page, $all_instances_printed ) {
-               // Get the value from the request, if
-               // it's there, and if it's not an array.
+       function getCurrentValue( $template_instance_query_values, 
$form_submitted, $source_is_page, $all_instances_printed, &$val_modifier = null 
) {
+               // Get the value from the request, if it's there, and if it's 
not an array.
                $cur_value = null;
                $field_name = $this->template_field->getFieldName();
                $delimiter = $this->mFieldArgs['delimiter'];
-               $escaped_field_name = str_replace( "'", "\'", $field_name );
                if ( isset( $template_instance_query_values ) &&
                        $template_instance_query_values != null &&
                        is_array( $template_instance_query_values ) ) {
 
-                       // If the field name contains an apostrophe, the array
-                       // sometimes has the apostrophe escaped, and sometimes
-                       // not. For now, just check for both versions.
-                       // @TODO - figure this out.
                        $field_query_val = null;
-                       if ( array_key_exists( $escaped_field_name, 
$template_instance_query_values ) ) {
-                               $field_query_val = 
$template_instance_query_values[$escaped_field_name];
-                       } elseif ( array_key_exists( $field_name, 
$template_instance_query_values ) ) {
+                       if ( array_key_exists( $field_name, 
$template_instance_query_values ) ) {
                                $field_query_val = 
$template_instance_query_values[$field_name];
+                       } else {
+                               // The next checks are to allow for support for 
appending/prepending with autoedit.
+                               if ( array_key_exists( "$field_name+", 
$template_instance_query_values ) ) {
+                                       $field_query_val = 
$template_instance_query_values["$field_name+"];
+                                       $val_modifier = '+';
+                               } elseif ( array_key_exists( "$field_name-", 
$template_instance_query_values ) ) {
+                                       $field_query_val = 
$template_instance_query_values["$field_name-"];
+                                       $val_modifier = '-';
+                               }
                        }
 
                        if ( $form_submitted && $field_query_val != '' ) {
diff --git a/includes/PF_FormPrinter.php b/includes/PF_FormPrinter.php
index 38751f9..38285e1 100644
--- a/includes/PF_FormPrinter.php
+++ b/includes/PF_FormPrinter.php
@@ -760,11 +760,42 @@
                        ( $this->tif->getDisplay() == 'spreadsheet' && 
$this->tif->allowsMultiple() && $this->tif->getInstanceNum() == 0 ) ) {
                        $this->tif->addField( $form_field );
                }
-               $cur_value = $form_field->getCurrentValue( 
$this->tif->getValuesFromSubmit(), $this->form_submitted, 
$this->source_is_page, $this->tif->allInstancesPrinted() );
+               $val_modifier = null;
+               $cur_value = $form_field->getCurrentValue( 
$this->tif->getValuesFromSubmit(), $this->form_submitted, 
$this->source_is_page, $this->tif->allInstancesPrinted(), $val_modifier );
                if ( $form_field->holdsTemplate() ) {
                        $this->placeholderFields[] = self::placeholderFormat( 
$this->tif->getTemplateName(), $field_name );
                }
 
+               if ($val_modifier !== null) {
+                       $page_value = 
$this->tif->getValuesFromPage()[$field_name];
+               }
+               if ($val_modifier === '+') {
+                       if (preg_match("#(,|\^)\s*$cur_value\s*(,|\$)#", 
$page_value) === 0) {
+                               $cur_value = "$page_value,$cur_value";
+                       } else {
+                               $cur_value = $page_value;
+                       }
+               } elseif ($val_modifier === '-') {
+                       // get an array of elements to remove:
+                       $remove = array_map('trim', explode(",", $cur_value));
+                       // process the current value:
+                       $val_array = array_map('trim', explode(",", 
$page_value));
+                       // remove element(s) from list
+                       foreach ($remove as $rmv) {
+                               // go through each element and remove match(es)
+                               if (($key = array_search($rmv, $val_array)) !== 
false) {
+                                       unset($val_array[$key]);
+                               }
+                       }
+                       // Convert modified array back to a comma-separated 
string value and modify
+                       $cur_value = implode(",", $val_array);
+                       if ($cur_value === '') {
+                               // HACK: setting an empty string prevents 
anything from happening at all.
+                               // set a dummy string that evaluates to an 
empty string
+                               $cur_value = '{{subst:lc: }}';
+                       }
+               }
+
                // If the user is editing a page, and that page contains a call 
to
                // the template being processed, get the current field's value
                // from the template call
diff --git a/includes/PF_ParserFunctions.php b/includes/PF_ParserFunctions.php
index 2f68d0d..1895b44 100644
--- a/includes/PF_ParserFunctions.php
+++ b/includes/PF_ParserFunctions.php
@@ -215,6 +215,24 @@
                return $parser->insertStripItem( self::createFormLink( $parser, 
$params, 'queryformlink' ), $parser->mStripState );
        }
 
+       static function convertQueryString ( $string, $inQueryArr ) {
+               // Change HTML-encoded ampersands directly to
+               // URL-encoded ampersands, so that the string
+               // doesn't get split up on the '&'.
+               $inQueryStr = str_replace( '&', '%26', $string );
+               // "Decode" any other HTML tags.
+               $inQueryStr = html_entity_decode( $inQueryStr, ENT_QUOTES );
+               // next, replace  Foo[Bar] += Baz  with  Foo[Bar+] = Baz
+               // and do the same for -=
+               // This way, parse_str won't strip out the += and -=
+               $inQueryStr = preg_replace( "/\[([^\]]+)\]\s*(\+|-)=/", 
"[$1$2]=", $inQueryStr);
+               $inQueryStr = str_replace( '+', '%2B', $inQueryStr); // prevent 
decoding + to space character
+
+               parse_str( $inQueryStr, $arr );
+
+               return PFUtils::array_merge_recursive_distinct( $inQueryArr, 
$arr );
+       }
+
        static function renderFormInput( &$parser ) {
                $params = func_get_args();
                array_shift( $params ); // don't need the parser
@@ -254,15 +272,7 @@
                        } elseif ( $paramName == 'button text' ) {
                                $inButtonStr = $value;
                        } elseif ( $paramName == 'query string' ) {
-                               // Change HTML-encoded ampersands directly to
-                               // URL-encoded ampersands, so that the string
-                               // doesn't get split up on the '&'.
-                               $inQueryStr = str_replace( '&', '%26', 
$value );
-                               // "Decode" any other HTML tags.
-                               $inQueryStr = html_entity_decode( $inQueryStr, 
ENT_QUOTES );
-
-                               parse_str( $inQueryStr, $arr );
-                               $inQueryArr = 
PFUtils::array_merge_recursive_distinct( $inQueryArr, $arr );
+                               $inQueryArr = self::convertQueryString( $value, 
$inQueryArr );
                        } elseif ( $paramName == 'autocomplete on category' ) {
                                $inAutocompletionSource = $value;
                                $autocompletionType = 'category';
@@ -503,17 +513,9 @@
                                case 'summary':
                                        $summary = $parser->recursiveTagParse( 
$value );
                                        break;
-                               case 'query string' :
-
-                                       // Change HTML-encoded ampersands 
directly to
-                                       // URL-encoded ampersands, so that the 
string
-                                       // doesn't get split up on the '&'.
-                                       $inQueryStr = str_replace( '&', 
'%26', $value );
-
-                                       parse_str( $inQueryStr, $arr );
-                                       $inQueryArr = 
PFUtils::array_merge_recursive_distinct( $inQueryArr, $arr );
+                               case 'query string':
+                                       $inQueryArr = self::convertQueryString( 
$value, $inQueryArr );
                                        break;
-
                                case 'ok text':
                                case 'error text':
                                        // do not parse ok text or error text 
yet. Will be parsed on api call
@@ -648,13 +650,7 @@
                        } elseif ( $param_name == 'link type' ) {
                                $inLinkType = $value;
                        } elseif ( $param_name == 'query string' ) {
-                               // Change HTML-encoded ampersands directly to
-                               // URL-encoded ampersands, so that the string
-                               // doesn't get split up on the '&'.
-                               $inQueryStr = str_replace( '&', '%26', 
$value );
-
-                               parse_str( $inQueryStr, $arr );
-                               $inQueryArr = 
PFUtils::array_merge_recursive_distinct( $inQueryArr, $arr );
+                               $inQueryArr = self::convertQueryString( $value, 
$inQueryArr );
                        } elseif ( $param_name == 'tooltip' ) {
                                $inTooltip = Sanitizer::decodeCharReferences( 
$value );
                        } elseif ( $param_name == 'target' ) {
diff --git a/includes/PF_TemplateInForm.php b/includes/PF_TemplateInForm.php
index edddf1d..263256e 100644
--- a/includes/PF_TemplateInForm.php
+++ b/includes/PF_TemplateInForm.php
@@ -27,7 +27,7 @@
        private $mPregMatchTemplateStr;
        private $mFullTextInPage;
        private $mValuesFromPage = array();
-       private $mValuesFromSubmit;
+       private $mValuesFromSubmit = array();
        private $mNumInstancesFromSubmit = 0;
        private $mPageCallsThisTemplate = false;
        private $mInstanceNum = 0;
@@ -228,17 +228,23 @@
                $this->mFields[] = $form_field;
        }
 
+       // this makes it possible for += and -= to modify values based on 
existing values.
+       function changeFieldValues( $field_name,  $new_value, $modifier=null ) {
+               $this->mValuesFromPage[$field_name] = $new_value;
+               if ($modifier !== null && 
array_key_exists($field_name.$modifier, $this->mValuesFromPage)) {
+                       // clean up old values with + or - in them from the 
array
+                       unset( $this->mValuesFromPage[$field_name.$modifier] );
+               }
+       }
+
        function setFieldValuesFromSubmit() {
                global $wgRequest;
-
-               $this->mValuesFromSubmit = null;
 
                $query_template_name = str_replace( ' ', '_', 
$this->mTemplateName );
                // Also replace periods with underlines, since that's what
                // POST does to strings anyway.
                $query_template_name = str_replace( '.', '_', 
$query_template_name );
-               // ...and escape apostrophes.
-               // (Or don't.)
+               // ...and escape apostrophes. (Or don't.)
                //$query_template_name = str_replace( "'", "\'", 
$query_template_name );
 
                $allValuesFromSubmit = $wgRequest->getArray( 
$query_template_name );
@@ -251,7 +257,15 @@
                        $valuesFromSubmitKeys = array();
                        foreach ( array_keys( $allValuesFromSubmit ) as $key ) {
                                if ( $key != 'num' ) {
-                                       $valuesFromSubmitKeys[] = $key;
+                                       // prevent single quotes from being 
escaped (which happens only sometimes)
+                                       // TODO: figure out why this problem 
occurs at all
+                                       if (strpos($key, "\\'") !== false) {
+                                               $newkey = str_replace("\\'", 
"'", $key);
+                                               $valuesFromSubmitKeys[] = 
$newkey;
+                                               $allValuesFromSubmit[$newkey] = 
$allValuesFromSubmit[$key];
+                                       } else {
+                                               $valuesFromSubmitKeys[] = $key;
+                                       }
                                }
                        }
                        $this->mNumInstancesFromSubmit = count( 
$valuesFromSubmitKeys );
@@ -260,6 +274,14 @@
                                $this->mValuesFromSubmit = 
$allValuesFromSubmit[$instanceKey];
                        }
                } else {
+                       foreach ( array_keys( $allValuesFromSubmit) as $key ) {
+                               if (strpos($key, "\\'") !== false) {
+                                       $newkey = str_replace("\\'", "'", $key);
+                                       // prevent single quotes from being 
escaped (which happens only sometimes)
+                                       $allValuesFromSubmit[$newkey] = 
$allValuesFromSubmit[$key];
+                                       // leave old, un-fixed key intact, just 
in case it was intended (although unlikely)
+                               }
+                       }
                        $this->mValuesFromSubmit = $allValuesFromSubmit;
                }
        }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5b62232fc790c33390f8e2f47096ba028b0aa268
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/PageForms
Gerrit-Branch: master
Gerrit-Owner: Joeytje50 <joeytj...@gmail.com>

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

Reply via email to