From 4a49ddd14b0b4e75c4ef4a3c3e728b31b10fa4c7 Mon Sep 17 00:00:00 2001
From: Jared Hancock <jared@osticket.com>
Date: Mon, 25 Aug 2014 22:17:42 -0500
Subject: [PATCH] forms: Standardize saving of choice field values

Always save a key/value hash of the selected value(s). However, if the field
does not have the multivalue configuration setting, then retrieve just the
key with the to_php() function. to_database(), however, will always return a
JSON string with the value(s) formatted as a hash array.
---
 include/class.dynamic_forms.php |  4 +--
 include/class.forms.php         | 61 ++++++++++++++++++++-------------
 include/class.list.php          |  4 +--
 3 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index e33d6e207..af720ee56 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -752,7 +752,7 @@ class DynamicFormEntry extends VerySimpleModel {
         foreach ($this->getAnswers() as $answer)
             $answer->deleted = true;
 
-        foreach ($this->getFields() as $field) {
+        foreach ($this->getForm()->getDynamicFields() as $field) {
             $found = false;
             foreach ($this->getAnswers() as $answer) {
                 if ($answer->get('field_id') == $field->get('id')) {
@@ -1053,7 +1053,7 @@ class SelectionField extends FormField {
 
         $config = parent::getConfiguration();
         if ($config['widget'])
-            $config['typeahead'] = isset($config['widget']['typeahead']);
+            $config['typeahead'] = $config['widget'] == 'typeahead';
 
         //Typeahed doesn't support multiselect for now  TODO: Add!
         if ($config['typeahead'])
diff --git a/include/class.forms.php b/include/class.forms.php
index c5c93866e..58a8fe403 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -757,33 +757,32 @@ class ChoiceField extends FormField {
     }
 
     function parse($value) {
-
-        if (!$value) return null;
-
-        // Assume multiselect
-        $values = array();
-        $choices = $this->getChoices();
-        if (is_array($value)) {
-            foreach($value as $k => $v)
-                if (isset($choices[$v]))
-                    $values[$v] = $choices[$v];
-        } elseif(isset($choices[$value])) {
-            $values[$value] = $choices[$value];
-        }
-
-        return $values ?: null;
+        return $this->to_php($value ?: null);
     }
 
     function to_database($value) {
-        if ($value && is_array($value))
+        if (!is_array($value)) {
+            $choices = $this->getChoices();
+            if (isset($choices[$value]))
+                $value = array($value => $choices[$value]);
+        }
+        if (is_array($value))
             $value = JsonDataEncoder::encode($value);
 
         return $value;
     }
 
     function to_php($value) {
-        return ($value && !is_array($value))
-            ? JsonDataParser::parse($value) : $value;
+        if (is_string($value))
+            $array = JsonDataParser::parse($value) ?: $value;
+        else
+            $array = $value;
+        $config = $this->getConfiguration();
+        if (is_array($array) && !$config['multiselect'] && count($array) < 2) {
+            reset($array);
+            return key($array);
+        }
+        return $array;
     }
 
     function toString($value) {
@@ -1171,7 +1170,6 @@ FormField::addFieldTypes('Dynamic Fields', function() {
     );
 });
 
-
 class Widget {
 
     function __construct($field) {
@@ -1321,10 +1319,10 @@ class ChoicesWidget extends Widget {
             $def_val = $have_def ? $choices[$def_key] : $prompt;
         }
 
-        if (($value=$this->getValue()))
-            $values = $this->field->parse($value);
-        elseif ($this->value)
-             $values = $this->value;
+        $values = $this->value;
+        if (!is_array($values)) {
+            $values = array($values => $this->field->getChoice($values));
+        }
 
         if ($values === null)
             $values = $have_def ? array($def_key => $choices[$def_key]) : array();
@@ -1361,6 +1359,23 @@ class ChoicesWidget extends Widget {
        <?php
         }
     }
+
+    function getValue() {
+        $value = parent::getValue();
+
+        if (!$value) return null;
+
+        // Assume multiselect
+        $values = array();
+        $choices = $this->field->getChoices();
+        if (is_array($value)) {
+            foreach($value as $k => $v) {
+                if (isset($choices[$v]))
+                    $values[$v] = $choices[$v];
+            }
+        }
+        return $values;
+    }
 }
 
 class CheckboxWidget extends Widget {
diff --git a/include/class.list.php b/include/class.list.php
index 31a3dd519..86a428c22 100644
--- a/include/class.list.php
+++ b/include/class.list.php
@@ -946,8 +946,8 @@ class TicketStatus  extends VerySimpleModel implements CustomListItem {
                     }
                     break;
                 case 'state':
-                    if ($val && is_array($val))
-                        $this->set('state', key($val));
+                    if ($val)
+                        $this->set('state', $val);
                     else
                         $f->addError(__('Unknown or invalid state'), $name);
                     break;
-- 
GitLab