From 1bdbd4eca32d70bb5372b4ea0607a45c0f050b48 Mon Sep 17 00:00:00 2001 From: eileen Date: Wed, 20 Mar 2019 14:28:59 +1300 Subject: [PATCH] Fix Contact.create calls to respect passed in variables & variables set via hook for sort_name & display_name This has been applied to Organizations & Households, not Individuals at this stage as that is more complex. Use case is saving organizations with The so that The is at the end of their sort_name, making it easier to deal with data entry variations --- CRM/Contact/BAO/Contact.php | 32 ++++++++++++---------------- api/v3/Generic/Update.php | 6 ++++++ tests/phpunit/api/v3/ContactTest.php | 32 ++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index cea1e9da86..ed8ad48573 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -146,39 +146,35 @@ class CRM_Contact_BAO_Contact extends CRM_Contact_DAO_Contact { $params['contact_sub_type'] = 'null'; } - // Fixed contact source. - if (isset($params['contact_source'])) { - $params['source'] = $params['contact_source']; - } - if (isset($params['preferred_communication_method']) && is_array($params['preferred_communication_method'])) { CRM_Utils_Array::formatArrayKeys($params['preferred_communication_method']); $contact->preferred_communication_method = CRM_Utils_Array::implodePadded($params['preferred_communication_method']); unset($params['preferred_communication_method']); } + $defaults = ['source' => CRM_Utils_Array::value('contact_source', $params)]; + if ($params['contact_type'] === 'Organization' && isset($params['organization_name'])) { + $defaults['display_name'] = $params['organization_name']; + $defaults['sort_name'] = $params['organization_name']; + } + if ($params['contact_type'] === 'Household' && isset($params['household_name'])) { + $defaults['display_name'] = $params['household_name']; + $defaults['sort_name'] = $params['household_name']; + } + $params = array_merge($defaults, $params); + $allNull = $contact->copyValues($params); $contact->id = CRM_Utils_Array::value('contact_id', $params); if ($contact->contact_type == 'Individual') { $allNull = FALSE; - + // @todo allow the lines below to be overridden by input or hooks & add tests, + // as has been done for households and organizations. // Format individual fields. CRM_Contact_BAO_Individual::format($params, $contact); } - elseif ($contact->contact_type == 'Household') { - if (isset($params['household_name'])) { - $allNull = FALSE; - $contact->display_name = $contact->sort_name = CRM_Utils_Array::value('household_name', $params, ''); - } - } - elseif ($contact->contact_type == 'Organization') { - if (isset($params['organization_name'])) { - $allNull = FALSE; - $contact->display_name = $contact->sort_name = CRM_Utils_Array::value('organization_name', $params, ''); - } - } + if (strlen($contact->display_name) > 128) { $contact->display_name = substr($contact->display_name, 0, 128); } diff --git a/api/v3/Generic/Update.php b/api/v3/Generic/Update.php index d982f07426..0ba2aafb29 100644 --- a/api/v3/Generic/Update.php +++ b/api/v3/Generic/Update.php @@ -77,6 +77,12 @@ function civicrm_api3_generic_update($apiRequest) { } $existing = array_pop($existing['values']); + // Per Unit test testUpdateHouseholdWithAll we don't want to load these from the DB + // if they are not passed in then we'd rather they are calculated. + // Note update is not recomended anyway... + foreach (['sort_name', 'display_name'] as $fieldToNotSet) { + unset($existing[$fieldToNotSet]); + } $p = array_merge($existing, $apiRequest['params']); return civicrm_api($apiRequest['entity'], 'create', $p); } diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index db06ecd190..a427729382 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -2532,6 +2532,38 @@ class api_v3_ContactTest extends CiviUnitTestCase { $this->assertEquals('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', $result['values'][$result['id']]['sort_name']); } + /** + * Test that we can set the sort name via the api or alter it via a hook. + * + * As of writing this is being fixed for Organization & Household but it makes sense to do for individuals too. + */ + public function testCreateAlterSortName() { + $organizationID = $this->organizationCreate(['organization_name' => 'The Justice League', 'sort_name' => 'Justice League, The']); + $organization = $this->callAPISuccessGetSingle('Contact', ['return' => ['sort_name', 'display_name'], 'id' => $organizationID]); + $this->assertEquals('Justice League, The', $organization['sort_name']); + $this->assertEquals('The Justice League', $organization['display_name']); + $this->hookClass->setHook('civicrm_pre', array($this, 'killTheJusticeLeague')); + $this->organizationCreate(['id' => $organizationID, 'sort_name' => 'Justice League, The']); + $organization = $this->callAPISuccessGetSingle('Contact', ['return' => ['sort_name', 'display_name', 'is_deceased'], 'id' => $organizationID]); + $this->assertEquals('Steppenwolf wuz here', $organization['display_name']); + $this->assertEquals('Steppenwolf wuz here', $organization['sort_name']); + $this->assertEquals(1, $organization['is_deceased']); + + $householdID = $this->householdCreate(); + $household = $this->callAPISuccessGetSingle('Contact', ['return' => ['sort_name', 'display_name'], 'id' => $householdID]); + $this->assertEquals('Steppenwolf wuz here', $household['display_name']); + $this->assertEquals('Steppenwolf wuz here', $household['sort_name']); + } + + /** + * Implements hook_pre(). + */ + public function killTheJusticeLeague($op, $entity, $id, &$params) { + $params['sort_name'] = 'Steppenwolf wuz here'; + $params['display_name'] = 'Steppenwolf wuz here'; + $params['is_deceased'] = 1; + } + /** * Test Single Entity format. */ -- 2.25.1