diff --git a/include/class.dynamic_forms.php b/include/class.dynamic_forms.php
index c0a203646ffd02170cf4c5a1eff44778687722d8..050c8f3305635db0263018acac50f4c4805fc7eb 100644
--- a/include/class.dynamic_forms.php
+++ b/include/class.dynamic_forms.php
@@ -519,6 +519,7 @@ class DynamicFormEntry extends VerySimpleModel {
     var $_form;
     var $_errors = false;
     var $_clean = false;
+    var $_source = null;
 
     function getId() {
         return $this->get('id');
@@ -572,12 +573,21 @@ class DynamicFormEntry extends VerySimpleModel {
     function getFields() {
         if (!isset($this->_fields)) {
             $this->_fields = array();
-            foreach ($this->getAnswers() as $a)
-                $this->_fields[] = $a->getField();
+            foreach ($this->getAnswers() as $a) {
+                $T = $this->_fields[] = $a->getField();
+                $T->setForm($this);
+            }
         }
         return $this->_fields;
     }
 
+    function getSource() {
+        return $this->_source ?: (isset($this->id) ? false : $_POST);
+    }
+    function setSource($source) {
+        $this->_source = $source;
+    }
+
     function getField($name) {
 
         foreach ($this->getFields() as $field)
@@ -768,8 +778,8 @@ class DynamicFormEntry extends VerySimpleModel {
         if (count($this->dirty))
             $this->set('updated', new SqlFunction('NOW'));
         parent::save();
-        foreach ($this->getAnswers() as $a) {
-            $field = $a->getField();
+        foreach ($this->getFields() as $field) {
+            $a = $field->getAnswer();
             if ($this->object_type == 'U'
                     && in_array($field->get('name'), array('name','email')))
                 continue;
diff --git a/include/class.forms.php b/include/class.forms.php
index e86a07dd09b3a7219c8cc10bf4e5906d559075cb..e782f3ef2b94137e0cf45532acaaaf1a771dd791 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -662,7 +662,9 @@ class PhoneField extends FormField {
     function parse($value) {
         // NOTE: Value may have a legitimate 'X' to separate the number and
         // extension parts. Don't remove the 'X'
-        return preg_replace('/[^\dX]/', '', $value);
+        $val = preg_replace('/[^\dX]/', '', $value);
+        // Pass completely-incorrect string for validation error
+        return $val ?: $value;
     }
 
     function toString($value) {
diff --git a/include/class.ticket.php b/include/class.ticket.php
index c7c7375ac9489e8c4a7c63113c7f85baa3086ba2..881a5f0de7d242baad988801b67338911d1838aa 100644
--- a/include/class.ticket.php
+++ b/include/class.ticket.php
@@ -2311,9 +2311,11 @@ class Ticket {
 
         if ($vars['topicId'] && ($topic=Topic::lookup($vars['topicId']))) {
             if ($topic_form = $topic->getForm()) {
+                $TF = $topic_form->getForm($vars);
                 $topic_form = $topic_form->instanciate();
-                if (!$topic_form->getForm()->isValid($field_filter('topic')))
-                    $errors = array_merge($errors, $topic_form->getForm()->errors());
+                $topic_form->setSource($vars);
+                if (!$TF->isValid($field_filter('topic')))
+                    $errors = array_merge($errors, $TF->errors());
             }
         }
 
@@ -2342,6 +2344,9 @@ class Ticket {
         if(!Validator::process($fields, $vars, $errors) && !$errors['err'])
             $errors['err'] ='Missing or invalid data - check the errors and try again';
 
+        if ($vars['topicId'] && !$topic)
+            $errors['topicId'] = 'Invalid help topic selected';
+
         //Make sure the due date is valid
         if($vars['duedate']) {
             if(!$vars['time'] || strpos($vars['time'],':')===false)
diff --git a/include/class.user.php b/include/class.user.php
index d2e2e9e5706bbadf0d8a427b73221b158d2b73d3..127de6c87c1b8605cbadf78705e415913df30ab1 100644
--- a/include/class.user.php
+++ b/include/class.user.php
@@ -473,12 +473,13 @@ class User extends UserModel {
     function updateInfo($vars, &$errors) {
 
         $valid = true;
-        $forms = $this->getForms($vars);
+        $forms = $this->getDynamicData();
         foreach ($forms as $cd) {
-            if (!$cd->isValid())
+            $cd->setSource($vars);
+            if (!$cd->isValidForClient())
                 $valid = false;
-            if ($cd->get('type') == 'U'
-                        && ($form= $cd->getForm($vars))
+            elseif ($cd->get('type') == 'U'
+                        && ($form= $cd->getForm())
                         && ($f=$form->getField('email'))
                         && $f->getClean()
                         && ($u=User::lookup(array('emails__address'=>$f->getClean())))