* This is intended as a refactoring step - not the long term function. Do not
* call from any function other than the one it is taken from (Merger::mergeLocations).
*
- * @param string $daoName
* @param int $otherBlockId
* @param string $name
* @param int $blkCount
*
- * @return mixed
+ * @return CRM_Core_DAO_Address|CRM_Core_DAO_Email|CRM_Core_DAO_IM|CRM_Core_DAO_Phone|CRM_Core_DAO_Website
+ *
+ * @throws \CRM_Core_Exception
*/
- public function copyDataToNewBlockDAO(string $daoName, $otherBlockId, $name, $blkCount) {
- $locationBlocks = CRM_Dedupe_Merger::getLocationBlockInfo();
- $migrationInfo = $this->getMigrationInfo();
+ public function copyDataToNewBlockDAO($otherBlockId, $name, $blkCount) {
// For the block which belongs to other-contact, link the location block to main-contact
- $otherBlockDAO = new $daoName();
+ $otherBlockDAO = $this->getDAOForLocationEntity($name, $this->getSelectedLocationType($name, $blkCount), $this->getSelectedType($name, $blkCount));
$otherBlockDAO->contact_id = $this->getToKeepID();
-
// Get the ID of this block on the 'other' contact, otherwise skip
$otherBlockDAO->id = $otherBlockId;
+ return $otherBlockDAO;
+ }
- // Add/update location and type information from the form, if applicable
- if ($locationBlocks[$name]['hasLocation']) {
- $locTypeId = $migrationInfo['location_blocks'][$name][$blkCount]['locTypeId'] ?? NULL;
- $otherBlockDAO->location_type_id = $locTypeId;
+ /**
+ * Get blocks, if any, to update for the deleted contact.
+ *
+ * If the deleted contact no longer has a primary address but still has
+ * one or more blocks we want to ensure the remaining block is updated
+ * to have is_primary = 1 in case the contact is ever undeleted.
+ *
+ * @param string $entity
+ *
+ * @return array
+ * @throws \CRM_Core_Exception
+ */
+ public function getBlocksToUpdateForDeletedContact($entity) {
+ $movedBlocks = $this->getLocationBlocksToMerge()[$entity];
+ $deletedContactsBlocks = $this->getLocationBlocksForContactToRemove()[$entity];
+ $unMovedBlocks = array_values(array_diff_key($deletedContactsBlocks, $movedBlocks));
+ if (empty($unMovedBlocks) || empty($movedBlocks)) {
+ return [];
}
- if ($locationBlocks[$name]['hasType']) {
- $typeTypeId = $migrationInfo['location_blocks'][$name][$blkCount]['typeTypeId'] ?? NULL;
- $otherBlockDAO->{$locationBlocks[$name]['hasType']} = $typeTypeId;
+ foreach (array_keys($movedBlocks) as $index) {
+ if ($deletedContactsBlocks[$index]['is_primary']) {
+ // We have moved the primary - change any other block to be primary.
+ $newPrimaryBlock = $this->getDAOForLocationEntity($entity);
+ $newPrimaryBlock->id = $unMovedBlocks[0]['id'];
+ $newPrimaryBlock->is_primary = 1;
+ return [$newPrimaryBlock->id => $newPrimaryBlock];
+ }
}
- return $otherBlockDAO;
+ return [];
+ }
+
+ /**
+ * Get the details of the blocks to be transferred over for the given entity.
+ *
+ * @param string $entity
+ *
+ * @return array
+ */
+ protected function getLocationBlocksToMoveForEntity($entity) {
+ $movedBlocks = $this->getLocationBlocksToMerge()[$entity];
+ $blockDetails = $this->getLocationBlocksForContactToRemove()[$entity];
+ return array_intersect_key($blockDetails, $movedBlocks);
+ }
+
+ /**
+ * Does the contact to keep have location blocks for the given entity.
+ *
+ * @param string $entity
+ *
+ * @return bool
+ */
+ public function contactToKeepHasLocationBlocksForEntity($entity) {
+ return !empty($this->getLocationBlocksForContactToKeep()[$entity]);
+ }
+
+ /**
+ * Get the location blocks for the contact to be kept.
+ *
+ * @return array
+ */
+ public function getLocationBlocksForContactToKeep() {
+ return $this->getMigrationInfo()['main_details']['location_blocks'];
+ }
+
+ /**
+ * Get the location blocks for the contact to be deleted.
+ *
+ * @return array
+ */
+ public function getLocationBlocksForContactToRemove() {
+ return $this->getMigrationInfo()['other_details']['location_blocks'];
+ }
+
+ /**
+ * Get the DAO object appropriate to the location entity.
+ *
+ * @param string $entity
+ *
+ * @param int|null $locationTypeID
+ * @param int|null $typeID
+ *
+ * @return CRM_Core_DAO_Address|CRM_Core_DAO_Email|CRM_Core_DAO_IM|CRM_Core_DAO_Phone|CRM_Core_DAO_Website
+ * @throws \CRM_Core_Exception
+ */
+ public function getDAOForLocationEntity($entity, $locationTypeID = NULL, $typeID = NULL) {
+ switch ($entity) {
+ case 'email':
+ $dao = new CRM_Core_DAO_Email();
+ $dao->location_type_id = $locationTypeID;
+ return $dao;
+
+ case 'address':
+ $dao = new CRM_Core_DAO_Address();
+ $dao->location_type_id = $locationTypeID;
+ return $dao;
+
+ case 'phone':
+ $dao = new CRM_Core_DAO_Phone();
+ $dao->location_type_id = $locationTypeID;
+ $dao->phone_type_id = $typeID;
+ return $dao;
+
+ case 'website':
+ $dao = new CRM_Core_DAO_Website();
+ $dao->website_type_id = $typeID;
+ return $dao;
+
+ case 'im':
+ $dao = new CRM_Core_DAO_IM();
+ $dao->location_type_id = $locationTypeID;
+ return $dao;
+
+ default:
+ // Mostly here, along with the switch over a more concise format, to help IDEs understand the possibilities.
+ throw new CRM_Core_Exception('Unsupported entity');
+ }
+ }
+
+ /**
+ * Get the selected location type for the given location block.
+ *
+ * This will retrieve any user selection if they specified which location to move a block to.
+ *
+ * @param string $entity
+ * @param int $blockIndex
+ *
+ * @return int|null
+ */
+ protected function getSelectedLocationType($entity, $blockIndex) {
+ return $this->getMigrationInfo()['location_blocks'][$entity][$blockIndex]['locTypeId'] ?? NULL;
+ }
+
+ /**
+ * Get the selected type for the given location block.
+ *
+ * This will retrieve any user selection if they specified which type to move a block to (e.g 'Mobile' for phone).
+ *
+ * @param string $entity
+ * @param int $blockIndex
+ *
+ * @return int|null
+ */
+ protected function getSelectedType($entity, $blockIndex) {
+ return $this->getMigrationInfo()['location_blocks'][$entity][$blockIndex]['typeTypeId'] ?? NULL;
}
}