Fix notice regression on contact edit
authorEileen McNaughton <emcnaughton@wikimedia.org>
Mon, 11 Dec 2023 23:36:18 +0000 (12:36 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Tue, 12 Dec 2023 19:35:30 +0000 (08:35 +1300)
This notice occurs when the contact has one or more subtypes allocated. Note that the thing
I focussed on while testing was ensuring that it was possible to add a contact sub-type
and save custom field data applicable to that sub-type. I also checked with the subtype
name differing from the label

CRM/Contact/Form/Contact.php

index 8bfc19f3773047df6efc14cc2f1f498175aaa927..99d0761d00863b94692ef7e3ee38683708dc810c 100644 (file)
@@ -25,6 +25,8 @@
  */
 class CRM_Contact_Form_Contact extends CRM_Core_Form {
 
+  use CRM_Contact_Form_ContactFormTrait;
+
   /**
    * The contact type of the form.
    *
@@ -128,6 +130,8 @@ class CRM_Contact_Form_Contact extends CRM_Core_Form {
 
   /**
    * Build all the data structures needed to build the form.
+   *
+   * @throws \CRM_Core_Exception
    */
   public function preProcess() {
     $this->_action = CRM_Utils_Request::retrieve('action', 'String', $this, FALSE, 'add');
@@ -183,14 +187,9 @@ class CRM_Contact_Form_Contact extends CRM_Core_Form {
       $this->_contactId = NULL;
     }
     else {
-      //update mode
-      if (!$this->_contactId) {
-        $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this, TRUE);
-      }
-
-      if ($this->_contactId) {
+      if ($this->getContactID()) {
         $defaults = [];
-        $params = ['id' => $this->_contactId];
+        $params = ['id' => $this->getContactID()];
         $returnProperities = ['id', 'contact_type', 'contact_sub_type', 'modified_date', 'is_deceased'];
         CRM_Core_DAO::commonRetrieve('CRM_Contact_DAO_Contact', $params, $defaults, $returnProperities);
 
@@ -359,14 +358,15 @@ class CRM_Contact_Form_Contact extends CRM_Core_Form {
         CRM_Contact_Form_Edit_CustomData::preProcess($this);
       }
       else {
-        $contactSubType = $this->_contactSubType;
-        // need contact sub type to build related grouptree array during post process
-        if (!empty($_POST['qfKey'])) {
-          $contactSubType = $_POST['contact_sub_type'] ?? NULL;
-        }
-        //only custom data has preprocess hence directly call it
-        CRM_Custom_Form_CustomData::preProcess($this, NULL, $contactSubType,
-          1, $this->_contactType, $this->_contactId
+        // The reason we call this here is that it sets the _groupTree property which is later used
+        // in setDefaultValues and buildForm. (Ideally instead we would have a trait with getCustomGroup & getCustomFields
+        // that can be called at appropriate times). In order for buildForm to add the right fields it needs
+        // to know any contact sub types that are being added in the submission. Since this runs before
+        // the buildForm adds the contact_sub_type to the form we need to look in _submitValues for it - submitValues
+        // is a un-sanitised version of what is in the form submission (_POST) whereas `getSubmittedValues()` retrieves
+        // 'allowed' POSTED values - ie values which match available fields, with some localization handling.
+        CRM_Custom_Form_CustomData::preProcess($this, NULL, $this->isSubmitted() ? ($this->_submitValues['contact_sub_type'] ?? []) : $this->getContactValue('contact_sub_type'),
+          1, $this->_contactType, $this->getContactID()
         );
         $this->assign('customValueCount', $this->_customValueCount);
       }
@@ -1505,4 +1505,18 @@ class CRM_Contact_Form_Contact extends CRM_Core_Form {
     return "$number$str";
   }
 
+  /**
+   * Get the contact ID being edited.
+   *
+   * @return int||null
+   *
+   * @noinspection PhpUnhandledExceptionInspection
+   */
+  public function getContactID(): ?int {
+    if (!$this->_contactId) {
+      $this->_contactId = CRM_Utils_Request::retrieve('cid', 'Positive', $this);
+    }
+    return $this->_contactId ? (int) $this->_contactId : NULL;
+  }
+
 }