From 60fd90d86fae28d66eb1e53e75b021210149c75b Mon Sep 17 00:00:00 2001 From: Dave Greenberg Date: Mon, 20 Jul 2015 11:51:41 -0700 Subject: [PATCH] Revert "CRM-10551: Allow deletion of blanked location-based fields edited via a profile" --- CRM/Contact/BAO/Contact.php | 20 +-- CRM/Contact/Form/Inline/Website.php | 5 +- CRM/Core/BAO/Block.php | 214 +++++++++++++++------------- CRM/Core/BAO/Website.php | 60 +++----- 4 files changed, 145 insertions(+), 154 deletions(-) diff --git a/CRM/Contact/BAO/Contact.php b/CRM/Contact/BAO/Contact.php index f3fa846bc0..69dda6bd15 100644 --- a/CRM/Contact/BAO/Contact.php +++ b/CRM/Contact/BAO/Contact.php @@ -276,6 +276,9 @@ class CRM_Contact_BAO_Contact extends CRM_Contact_DAO_Contact { * @param bool $invokeHooks * If we need to invoke hooks. * + * @param bool $skipDelete + * Unclear parameter, passed to website create + * * @todo explain this parameter * * @throws Exception @@ -283,7 +286,7 @@ class CRM_Contact_BAO_Contact extends CRM_Contact_DAO_Contact { * Created or updated contribution object. We are deprecating returning an error in * favour of exceptions */ - public static function &create(&$params, $fixAddress = TRUE, $invokeHooks = TRUE) { + public static function &create(&$params, $fixAddress = TRUE, $invokeHooks = TRUE, $skipDelete = FALSE) { $contact = NULL; if (empty($params['contact_type']) && empty($params['contact_id'])) { return $contact; @@ -363,10 +366,8 @@ class CRM_Contact_BAO_Contact extends CRM_Contact_DAO_Contact { $contact->$name = $value; } - // Process website(s) if present in params - if (!empty($params['website'])) { - CRM_Core_BAO_Website::create($params, $contact->id); - } + //add website + CRM_Core_BAO_Website::create($params['website'], $contact->id, $skipDelete); //get userID from session $session = CRM_Core_Session::singleton(); @@ -1864,15 +1865,6 @@ ORDER BY civicrm_email.is_primary DESC"; } if ($contactID) { - // CRM-10551 - // If a user has logged in, or accessed via a checksum - // Then deliberately 'blanking' a value in the profile should remove it from their record - $session = CRM_Core_Session::singleton(); - $params['updateBlankLocInfo'] = TRUE; - if (($session->get('authSrc') & (CRM_Core_Permission::AUTH_SRC_CHECKSUM + CRM_Core_Permission::AUTH_SRC_LOGIN)) == 0) { - $params['updateBlankLocInfo'] = FALSE; - } - $editHook = TRUE; CRM_Utils_Hook::pre('edit', 'Profile', $contactID, $params); } diff --git a/CRM/Contact/Form/Inline/Website.php b/CRM/Contact/Form/Inline/Website.php index 3b60fe2800..72cf288ac8 100644 --- a/CRM/Contact/Form/Inline/Website.php +++ b/CRM/Contact/Form/Inline/Website.php @@ -123,10 +123,7 @@ class CRM_Contact_Form_Inline_Website extends CRM_Contact_Form_Inline { $params = $this->exportValues(); // Process / save websites - // CRM-10551 - // Use updateBlankLocInfo to overwrite blanked values of matching type - $params['updateBlankLocInfo'] = TRUE; - CRM_Core_BAO_Website::create($params, $this->_contactId); + CRM_Core_BAO_Website::create($params['website'], $this->_contactId, TRUE); $this->log(); $this->response(); diff --git a/CRM/Core/BAO/Block.php b/CRM/Core/BAO/Block.php index d7b5b2e623..3131756955 100644 --- a/CRM/Core/BAO/Block.php +++ b/CRM/Core/BAO/Block.php @@ -223,18 +223,14 @@ class CRM_Core_BAO_Block { * CRM_Core_BAO_Block object on success, null otherwise */ public static function create($blockName, &$params, $entity = NULL, $contactId = NULL) { - if (!self::blockExists($blockName, $params)) { return NULL; } - // Set up required information / defaults - $entityElements = $blocks = array(); - $resetPrimary = $primarySet = $billingSet = FALSE; + $name = ucfirst($blockName); $contactId = NULL; - - $baoString = 'CRM_Core_BAO_' . ucfirst($blockName); - $updateBlankLocInfo = CRM_Utils_Array::value('updateBlankLocInfo', $params, FALSE); + $isPrimary = $isBilling = TRUE; + $entityElements = $blocks = array(); if ($entity) { $entityElements = array( @@ -246,130 +242,150 @@ class CRM_Core_BAO_Block { $contactId = $params['contact_id']; } - // Get current and submitted values - $existingValues = self::getBlockIds($blockName, $contactId, $entityElements, $updateBlankLocInfo); - $submittedValues = $params[$blockName]; - - // For each submitted value - foreach ($submittedValues as $count => $submittedValue) { - - // Set the contact ID - $submittedValue['contact_id'] = $contactId; - - // If this is a primary value, and we haven't unset a primary value yet, and there are values on the contact - // Then unset any primary value currently on the Contact - if (!empty($submittedValue['is_primary']) && !$resetPrimary && is_array($existingValues)) { - foreach ($existingValues as $existingValueId => $existingValue) { - if (!empty($existingValue['is_primary'])) { + $updateBlankLocInfo = CRM_Utils_Array::value('updateBlankLocInfo', $params, FALSE); - // @todo Can we refactor this? + //get existsing block ids. + $blockIds = self::getBlockIds($blockName, $contactId, $entityElements, $updateBlankLocInfo); + + if (!$updateBlankLocInfo) { + $resetPrimaryId = NULL; + $primaryId = FALSE; + foreach ($params[$blockName] as $count => $value) { + $blockId = CRM_Utils_Array::value('id', $value); + if ($blockId) { + if (is_array($blockIds) + && array_key_exists($blockId, $blockIds) + ) { + unset($blockIds[$blockId]); + } + else { + unset($value['id']); + } + } + //lets allow to update primary w/ more cleanly. + if (!$resetPrimaryId && !empty($value['is_primary'])) { + $primaryId = TRUE; + if (is_array($blockIds)) { + foreach ($blockIds as $blockId => $blockValue) { + if (!empty($blockValue['is_primary'])) { + $resetPrimaryId = $blockId; + break; + } + } + } + if ($resetPrimaryId) { + $baoString = 'CRM_Core_BAO_' . $blockName; $block = new $baoString(); $block->selectAdd(); $block->selectAdd("id, is_primary"); - $block->id = $existingValue['id']; + $block->id = $resetPrimaryId; if ($block->find(TRUE)) { $block->is_primary = FALSE; $block->save(); } $block->free(); - - // Stop looping since we found a match - $resetPrimary = TRUE; - break; } } } + } - // If there is already an ID passed in - if (!empty($submittedValue['id'])) { - // If the ID already exists on the contact - // Then we don't want to match on it later, so unset it - if (array_key_exists($submittedValue['id'], $existingValues)) { - unset($existingValues[$existingValueId]); - } - // Otherwise it is a new value, so ignore the passed in ID - else { - unset($submittedValue['id']); - } + foreach ($params[$blockName] as $count => $value) { + if (!is_array($value)) { + continue; } + $contactFields = array( + 'contact_id' => $contactId, + 'location_type_id' => CRM_Utils_Array::value('location_type_id', $value), + ); - // Otherwise, if there was no ID passed in - // Loop through the current values, and find the first match on location type - else { - foreach ($existingValues as $existingValueId => $existingValue) { - if ($existingValue['locationTypeId'] == $submittedValue['location_type_id']) { - - // Also require a match on 'type id' for phone and IM blocks - $matchFound = FALSE; - - if ($blockName == 'phone') { - if (CRM_Utils_Array::value('phoneTypeId', $existingValue) == CRM_Utils_Array::value('phone_type_id', $submittedValue)) { - $matchFound = TRUE; - } + //check for update + if (empty($value['id']) && + is_array($blockIds) && !empty($blockIds) + ) { + foreach ($blockIds as $blockId => $blockValue) { + if ($updateBlankLocInfo) { + if (!empty($blockIds[$count])) { + $value['id'] = $blockIds[$count]['id']; + unset($blockIds[$count]); } - elseif ($blockName == 'im') { - if (CRM_Utils_Array::value('providerId', $existingValue) == CRM_Utils_Array::value('provider_id', $submittedValue)) { - $matchFound = TRUE; + } + else { + if ($blockValue['locationTypeId'] == CRM_Utils_Array::value('location_type_id', $value)) { + $valueId = FALSE; + + if ($blockName == 'phone') { + $phoneTypeBlockValue = CRM_Utils_Array::value('phoneTypeId', $blockValue); + if ($phoneTypeBlockValue == CRM_Utils_Array::value('phone_type_id', $value)) { + $valueId = TRUE; + } + } + elseif ($blockName == 'im') { + $providerBlockValue = CRM_Utils_Array::value('providerId', $blockValue); + if ($providerBlockValue == $value['provider_id']) { + $valueId = TRUE; + } + } + else { + $valueId = TRUE; } - } - else { - $matchFound = TRUE; - } - // If we found a match - if ($matchFound) { - // Match up the ID - $submittedValue['id'] = $existingValue['id']; - // If the submitted value is not primary, but the matched value is - // Then set the submitted value to be primary - if (empty($submittedValue['is_primary']) && !empty($existingValue['is_primary'])) { - $submittedValue['is_primary'] = 1; + if ($valueId) { + //assigned id as first come first serve basis + $value['id'] = $blockValue['id']; + if (!$primaryId && !empty($blockValue['is_primary'])) { + $value['is_primary'] = $blockValue['is_primary']; + } + unset($blockIds[$blockId]); + break; } - // Remove the original value from the array so we don't match on it again - unset($existingValues[$existingValueId]); - break; } } } } - // Check if data exists in the submitted value - $dataExists = self::dataExists(self::$requiredBlockFields[$blockName], $submittedValue); - - // If there is data - if ($dataExists) { - - // "There can be only one" primary / billing block - if (!$primarySet && !empty($submittedValue['is_primary'])) { - $submittedValue['is_primary'] = 1; - $primarySet = TRUE; - } - else { - $contactFields['is_primary'] = 0; - } - - if (!$billingSet && !empty($submittedValue['is_billing'])) { - $submittedValue['is_billing'] = 1; - $billingSet = TRUE; - } - else { - $contactFields['is_billing'] = 0; - } + $dataExits = self::dataExists(self::$requiredBlockFields[$blockName], $value); - // Add the value to the list of blocks - $blocks[] = $baoString::add($submittedValue); + // Note there could be cases when block info already exist ($value[id] is set) for a contact/entity + // BUT info is not present at this time, and therefore we should be really careful when deleting the block. + // $updateBlankLocInfo will help take appropriate decision. CRM-5969 + if (!empty($value['id']) && !$dataExits && $updateBlankLocInfo) { + //delete the existing record + self::blockDelete($blockName, array('id' => $value['id'])); + continue; + } + elseif (!$dataExits) { + continue; } - // Otherwise, if there is no data, and there is an ID, and we are deleting 'blanked' values - // Then delete it - elseif (!empty($submittedValue['id']) && $updateBlankLocInfo) { - self::blockDelete($blockName, array('id' => $submittedValue['id'])); + if ($isPrimary && !empty($value['is_primary'])) { + $contactFields['is_primary'] = $value['is_primary']; + $isPrimary = FALSE; + } + else { + $contactFields['is_primary'] = 0; } - // Otherwise we ignore it + if ($isBilling && !empty($value['is_billing'])) { + $contactFields['is_billing'] = $value['is_billing']; + $isBilling = FALSE; + } else { + $contactFields['is_billing'] = 0; } + $blockFields = array_merge($value, $contactFields); + $baoString = 'CRM_Core_BAO_' . $name; + $blocks[] = $baoString::add($blockFields); + } + + // we need to delete blocks that were deleted during update + if ($updateBlankLocInfo && !empty($blockIds)) { + foreach ($blockIds as $deleteBlock) { + if (empty($deleteBlock['id'])) { + continue; + } + self::blockDelete($blockName, array('id' => $deleteBlock['id'])); + } } return $blocks; diff --git a/CRM/Core/BAO/Website.php b/CRM/Core/BAO/Website.php index e20e43de39..aa68196409 100644 --- a/CRM/Core/BAO/Website.php +++ b/CRM/Core/BAO/Website.php @@ -66,60 +66,46 @@ class CRM_Core_BAO_Website extends CRM_Core_DAO_Website { * @param int $contactID * Contact id. * + * @param $skipDelete + * * @return void */ - public static function create(&$params, $contactID) { - - if (empty($params['website'])) { + public static function create(&$params, $contactID, $skipDelete) { + if (empty($params)) { return FALSE; } - // CRM-10551 - // Use updateBlankLocInfo to overwrite blanked values of matching type - $updateBlankLocInfo = CRM_Utils_Array::value('updateBlankLocInfo', $params, FALSE); - - // Get websites submitted in the form, and already on the Contact - $submittedWebsites = $params['website']; - $existingWebsites = self::allWebsites($contactID); - - // For each website submitted on the form - foreach ($submittedWebsites as $key => $submittedValue) { - - // Check for matching IDs on submitted / existing data - $websiteId = CRM_Utils_Array::value('id', $submittedValue); + $ids = self::allWebsites($contactID); + foreach ($params as $key => $values) { + $websiteId = CRM_Utils_Array::value('id', $values); if ($websiteId) { - if (array_key_exists($websiteId, $existingWebsites)) { - unset($existingWebsites[$websiteId]); + if (array_key_exists($websiteId, $ids)) { + unset($ids[$websiteId]); } else { - unset($submittedValue['id']); + unset($values['id']); } } - // Match up submitted values to existing ones, based on type - if (empty($submittedValue['id']) && !empty($existingWebsites)) { - foreach ($existingWebsites as $id => $existingValue) { - if ($existingValue['website_type_id'] == $submittedValue['website_type_id']) { - $submittedValue['id'] = $id; - unset($existingWebsites[$id]); + if (empty($values['id']) && + is_array($ids) && !empty($ids) + ) { + foreach ($ids as $id => $value) { + if (($value['website_type_id'] == $values['website_type_id']) && !empty($values['url'])) { + $values['id'] = $id; + unset($ids[$id]); break; } } } - - $submittedValue['contact_id'] = $contactID; - - // CRM-10551 - // If there is a matching ID, the URL is empty and we are deleting blanked values - // Then remove it from the contact - if (!empty($submittedValue['id']) && empty($submittedValue['url']) && $updateBlankLocInfo) { - self::del(array($submittedValue['id'])); + $values['contact_id'] = $contactID; + if (!empty($values['url'])) { + self::add($values); } + } - // Otherwise, add the website if the URL isn't empty - elseif (!empty($submittedValue['url'])) { - self::add($submittedValue); - } + if ($skipDelete && !empty($ids)) { + self::del(array_keys($ids)); } } -- 2.25.1