CRM-21738 fix transfer of view_only custom data.
authoreileen <emcnaughton@wikimedia.org>
Tue, 6 Feb 2018 05:36:02 +0000 (18:36 +1300)
committereileen <emcnaughton@wikimedia.org>
Thu, 8 Feb 2018 01:41:05 +0000 (14:41 +1300)
View only custom data was not being transferred during the merge despite code in order
to achieve that. The reason was the metadata was being used from the (hateful)
getGroupTree function, but without passing $permissions = FALSE it was not
returning viewOnly fields. Note that this metadata retrieval function is a bad place for
filtering - they should be in separate functions.

CRM/Dedupe/Merger.php
tests/phpunit/api/v3/JobTest.php

index 12c3903d8c2805cfa6902f951e017f3483878226..381488563baef9312af9e6f66ed997a7cb179516 100644 (file)
@@ -1528,9 +1528,20 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
     CRM_Core_OptionGroup::lookupValues($submitted, $names, TRUE);
 
     // fix custom fields so they're edible by createProfileContact()
-    static $treeCache = array();
+    $treeCache = array();
     if (!array_key_exists($migrationInfo['main_details']['contact_type'], $treeCache)) {
-      $treeCache[$migrationInfo['main_details']['contact_type']] = CRM_Core_BAO_CustomGroup::getTree($migrationInfo['main_details']['contact_type'], NULL, NULL, -1);
+      $treeCache[$migrationInfo['main_details']['contact_type']] = CRM_Core_BAO_CustomGroup::getTree(
+        $migrationInfo['main_details']['contact_type'],
+        NULL,
+        NULL,
+        -1,
+        array(),
+        NULL,
+        TRUE,
+        NULL,
+        FALSE,
+        FALSE
+      );
     }
 
     $cFields = array();
@@ -1696,12 +1707,12 @@ INNER JOIN  civicrm_membership membership2 ON membership1.membership_type_id = m
     // move view only custom fields CRM-5362
     $viewOnlyCustomFields = array();
     foreach ($submitted as $key => $value) {
-      $fid = (int) substr($key, 7);
-      if (array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view'])) {
+      $fid = CRM_Core_BAO_CustomField::getKeyID($key);
+      if ($fid && array_key_exists($fid, $cFields) && !empty($cFields[$fid]['attributes']['is_view'])
+      ) {
         $viewOnlyCustomFields[$key] = $value;
       }
     }
-
     // special case to set values for view only, CRM-5362
     if (!empty($viewOnlyCustomFields)) {
       $viewOnlyCustomFields['entityID'] = $mainId;
index ff5af1fd0c961bc668d06fae359441fe6cfb08b4..17358a1cd3d2e8e1bafe4e83a2f0dbcbeb90281e 100644 (file)
@@ -882,6 +882,28 @@ class api_v3_JobTest extends CiviUnitTestCase {
 
   }
 
+  /**
+   * Test the batch merge copes with view only custom data field.
+   */
+  public function testBatchMergeCustomDataViewOnlyField() {
+    CRM_Core_Config::singleton()->userPermissionClass->permissions = array('access CiviCRM', 'edit my contact');
+    $mouseParams = ['first_name' => 'Mickey', 'last_name' => 'Mouse', 'email' => 'tha_mouse@mouse.com'];
+    $this->individualCreate($mouseParams);
+
+    $customGroup = $this->CustomGroupCreate();
+    $customField = $this->customFieldCreate(array('custom_group_id' => $customGroup['id'], 'is_view' => 1));
+    $this->individualCreate(array_merge($mouseParams, ['custom_' . $customField['id'] => 'blah']));
+
+    $result = $this->callAPISuccess('Job', 'process_batch_merge', array('check_permissions' => 0, 'mode' => 'safe'));
+    $this->assertEquals(1, count($result['values']['merged']));
+    $mouseParams['return'] = 'custom_' . $customField['id'];
+    $mouse = $this->callAPISuccess('Contact', 'getsingle', $mouseParams);
+    $this->assertEquals('blah', $mouse['custom_' . $customField['id']]);
+
+    $this->customFieldDelete($customGroup['id']);
+    $this->customGroupDelete($customGroup['id']);
+  }
+
   /**
    * Test the batch merge function actually works!
    *