From 652bacebc9baaa3b95bf92af41b7604ca4cc16d8 Mon Sep 17 00:00:00 2001
From: JediKev <kevin@enhancesoft.com>
Date: Tue, 17 Oct 2017 09:19:36 -0500
Subject: [PATCH] forms: Force Keys For Choice Field Options

This addresses an issue where some Choice Field options with no keys
that are apart of the Ticket Details form will not allow you to Export
them or Search for them correctly. This adds validation to make sure all
future Choice Field options have keys and to make sure all options are on new
lines. This will fix Exporting and Searching for all future Choice Field
options that are apart of the Ticket Details form.
---
 include/class.forms.php | 36 +++++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/include/class.forms.php b/include/class.forms.php
index c097dd995..a484bb4ab 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -1383,6 +1383,39 @@ class TextareaField extends FormField {
         return false;
     }
 
+    function validateEntry($value) {
+        parent::validateEntry($value);
+        $config = $this->getConfiguration();
+        $validators = array(
+            '' =>       null,
+            'choices' => array(
+                function($val) {
+                    $val = str_replace('"', '', JsonDataEncoder::encode($val));
+                    $regex = "/^(?! )[A-z0-9 _-]+:{1}[A-z0-9 _-]+$/";
+                    foreach (explode('\r\n', $val) as $v) {
+                        if (!preg_match($regex, $v))
+                            return false;
+                    }
+                    return true;
+                }, __('Each choice requires a key and has to be on a new line. (eg. key:value)')
+            ),
+        );
+        // Support configuration forms, as well as GUI-based form fields
+        $valid = $this->get('validator');
+        if (!$valid) {
+            $valid = $config['validator'];
+        }
+        if (!$value || !isset($validators[$valid]))
+            return;
+        $func = $validators[$valid];
+        $error = $func[1];
+        if ($config['validator-error'])
+            $error = $this->getLocal('validator-error', $config['validator-error']);
+        if (is_array($func) && is_callable($func[0]))
+            if (!call_user_func($func[0], $value))
+                $this->_errors[] = $error;
+    }
+
     function display($value) {
         $config = $this->getConfiguration();
         if ($config['html'])
@@ -1539,7 +1572,8 @@ class ChoiceField extends FormField {
         return array(
             'choices'  =>  new TextareaField(array(
                 'id'=>1, 'label'=>__('Choices'), 'required'=>false, 'default'=>'',
-                'hint'=>__('List choices, one per line. To protect against spelling changes, specify key:value names to preserve entries if the list item names change'),
+                'hint'=>__('List choices, one per line. To protect against spelling changes, specify key:value names to preserve entries if the list item names change.</br><b>Note:</b> If you have more than two choices, use a List instead.'),
+                'validator'=>'choices',
                 'configuration'=>array('html'=>false)
             )),
             'default' => new TextboxField(array(
-- 
GitLab