[REF] Code cleanup on location entities for the Contact Summary screen
authorEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 18 Mar 2022 01:30:15 +0000 (14:30 +1300)
committerEileen McNaughton <emcnaughton@wikimedia.org>
Fri, 1 Apr 2022 03:35:30 +0000 (16:35 +1300)
This builds on https://github.com/civicrm/civicrm-core/pull/22966 to improve loading of location entities.

It addresses 2 problems
1) the code is really confusing - handling the loading in 2 places
2) not all keys are loaded - resulting in enotices at the tpl layer.

Note that address still seems kinda tricky so I haven't worked through
that in this PR.

CRM/Contact/Page/View/Summary.php

index d49f41c691d1da7982793cb254e1425e810d0f2a..1aae2e0bf97692b2764e2120635917e7d7a41a1d 100644 (file)
@@ -104,7 +104,9 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
   /**
    * View summary details of a contact.
    *
+   * @throws \API_Exception
    * @throws \CRM_Core_Exception
+   * @throws \CiviCRM_API3_Exception
    */
   public function view() {
     // Add js for tabs, in-place editing, and jstree for tags
@@ -122,7 +124,6 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
     $session->pushUserContext($url);
     $this->assignFieldMetadataToTemplate('Contact');
 
-    $params = [];
     $defaults = [
       // Set empty default values for these - they will be overwritten when the contact is
       // loaded in CRM_Contact_BAO_Contact::retrieve if there are real values
@@ -144,19 +145,16 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
       // for Demographics.tpl
       'age' => ['y' => '', 'm' => ''],
       'birth_date' => '',
-      // for Website.tpl (the others don't seem to enotice for some reason).
-      'website' => [],
     ];
 
-    $params['contact_id'] = $this->_contactId;
-
-    CRM_Contact_BAO_Contact::getValues(array_merge(['id' => $this->_contactId], $params), $defaults);
-    $defaults['im'] = CRM_Core_BAO_IM::getValues(['contact_id' => $params['contact_id']]);
-    $defaults['email'] = CRM_Core_BAO_Email::getValues(['contact_id' => $params['contact_id']]);
-    $defaults['openid'] = CRM_Core_BAO_OpenID::getValues(['contact_id' => $params['contact_id']]);
-    $defaults['phone'] = CRM_Core_BAO_Phone::getValues(['contact_id' => $params['contact_id']]);
-    $defaults['address'] = CRM_Core_BAO_Address::getValues(['contact_id' => $params['contact_id']], TRUE);
-    CRM_Core_BAO_Website::getValues($params, $defaults);
+    CRM_Contact_BAO_Contact::getValues(['id' => $this->_contactId], $defaults);
+    $defaults['im'] = $this->getLocationValues($this->_contactId, 'IM');
+    $defaults['email'] = $this->getLocationValues($this->_contactId, 'Email');
+    $defaults['openid'] = $this->getLocationValues($this->_contactId, 'OpenID');
+    $defaults['phone'] = $this->getLocationValues($this->_contactId, 'Phone');
+    // This microformat magic is still required...
+    $defaults['address'] = CRM_Core_BAO_Address::getValues(['contact_id' => $this->_contactId], TRUE);
+    $defaults['website'] = $this->getLocationValues($this->_contactId, 'Website');
     // Copy employer fields to the current_employer keys.
     if (($defaults['contact_type'] === 'Individual') && !empty($defaults['employer_id']) && !empty($defaults['organization_name'])) {
       $defaults['current_employer'] = $defaults['organization_name'];
@@ -167,39 +165,15 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
     $mailingBackend = Civi::settings()->get('mailing_backend');
     $this->assign('mailingOutboundOption', $mailingBackend['outBound_option']);
 
+    // @todo only address is still being special handled here.... Consolidate with other locations.
     $communicationType = [
-      'phone' => [
-        'type' => 'phoneType',
-        'id' => 'phone_type',
-        'daoName' => 'CRM_Core_DAO_Phone',
-        'fieldName' => 'phone_type_id',
-      ],
-      'im' => [
-        'type' => 'IMProvider',
-        'id' => 'provider',
-        'daoName' => 'CRM_Core_DAO_IM',
-        'fieldName' => 'provider_id',
-      ],
-      'website' => [
-        'type' => 'websiteType',
-        'id' => 'website_type',
-        'daoName' => 'CRM_Core_DAO_Website',
-        'fieldName' => 'website_type_id',
-      ],
-      'address' => ['skip' => TRUE, 'customData' => 1],
-      'email' => ['skip' => TRUE],
-      'openid' => ['skip' => TRUE],
+      'address' => ['customData' => 1],
     ];
 
     foreach ($communicationType as $key => $value) {
       if (!empty($defaults[$key])) {
         foreach ($defaults[$key] as & $val) {
           CRM_Utils_Array::lookupValue($val, 'location_type', CRM_Core_PseudoConstant::get('CRM_Core_DAO_Address', 'location_type_id', ['labelColumn' => 'display_name']), FALSE);
-          if (empty($value['skip'])) {
-            $daoName = $value['daoName'];
-            $pseudoConst = $daoName::buildOptions($value['fieldName'], 'get');
-            CRM_Utils_Array::lookupValue($val, $value['id'], $pseudoConst, FALSE);
-          }
         }
         if (isset($value['customData'])) {
           foreach ($defaults[$key] as $blockId => $blockVal) {
@@ -478,4 +452,45 @@ class CRM_Contact_Page_View_Summary extends CRM_Contact_Page_View {
     return $allTabs;
   }
 
+  /**
+   * Get the values for the location entity for this contact.
+   *
+   * The form layer requires that we put the label values into keys too.
+   * Unfortunately smarty can't handle {$location_type_id:label} - ie
+   * the colon - so we need to map the value over in the php layer.
+   *
+   * @param int $contact_id
+   * @param string $entity
+   *
+   * @return array
+   * @throws \API_Exception
+   */
+  protected function getLocationValues(int $contact_id, string $entity): array {
+    $fieldMap = [
+      'location_type_id' => 'location_type',
+      'provider_id' => 'provider',
+      'phone_type_id' => 'phone_type',
+      'website_type_id' => 'website_type',
+    ];
+    $optionFields = array_keys((array) civicrm_api4($entity, 'getFields', [
+      'where' => [['options', 'IS NOT EMPTY'], ['name', 'IN', array_keys($fieldMap)]],
+    ], 'name'));
+    $select = ['*', 'custom.*'];
+    foreach ($optionFields as $optionField) {
+      $select[] = $optionField . ':label';
+    }
+    $locationEntities = (array) civicrm_api4($entity, 'get', [
+      'select' => $select,
+      'where' => [['contact_id', '=', $contact_id]],
+      'orderBy' => $entity === 'Website' ? [] : ['is_primary' => 'DESC'],
+    ], 'id');
+
+    foreach ($locationEntities as $index => $locationEntity) {
+      foreach ($optionFields as $optionField) {
+        $locationEntities[$index][$fieldMap[$optionField]] = $locationEntity[$optionField . ':label'];
+      }
+    }
+    return $locationEntities;
+  }
+
 }