Skip to content

Commit

Permalink
Merge pull request civicrm#9902 from JKingsnorth/CRM-19492
Browse files Browse the repository at this point in the history
CRM-19492 Merging: disable location settings if the relevant checkbox isn't selected
  • Loading branch information
eileenmcnaughton authored Feb 27, 2017
2 parents 5169c73 + 3caa7b4 commit 431f89f
Show file tree
Hide file tree
Showing 2 changed files with 96 additions and 79 deletions.
111 changes: 60 additions & 51 deletions CRM/Contact/Form/Merge.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,24 +78,25 @@ public function preProcess() {
$this->limit = CRM_Utils_Request::retrieve('limit', 'Positive', $this, FALSE);
$urlParams = "reset=1&rgid={$this->_rgid}&gid={$this->_gid}&limit=" . $this->limit;

// Sanity check
if ($cid == $oid) {
CRM_Core_Error::statusBounce(ts('Cannot merge a contact with itself.'));
}
$this->bounceIfInvalid($cid, $oid);

if (!CRM_Dedupe_BAO_Rule::validateContacts($cid, $oid)) {
CRM_Core_Error::statusBounce(ts('The selected pair of contacts are marked as non duplicates. If these records should be merged, you can remove this exception on the <a href="%1">Dedupe Exceptions</a> page.', array(1 => CRM_Utils_System::url('civicrm/dedupe/exception', 'reset=1'))));
}
$this->_contactType = civicrm_api3('Contact', 'getvalue', array('id' => $cid, 'return' => 'contact_type'));
$isFromDedupeScreen = TRUE;

$browseUrl = CRM_Utils_System::url('civicrm/contact/dedupefind', $urlParams . '&action=browse');

if (!$this->_rgid) {
$isFromDedupeScreen = FALSE;
// Unset browse URL as we have come from the search screen.
$browseUrl = '';
$this->_rgid = civicrm_api3('RuleGroup', 'getvalue', array(
'contact_type' => $this->_contactType,
'used' => 'Supervised',
'return' => 'id',
));
}
$this->assign('browseUrl', $browseUrl);
if ($browseUrl) {
CRM_Core_Session::singleton()->pushUserContext($browseUrl);
}

$cacheKey = CRM_Dedupe_Merger::getMergeCacheKeyString($this->_rgid, $gid);

Expand All @@ -104,14 +105,6 @@ public function preProcess() {

$pos = CRM_Core_BAO_PrevNextCache::getPositions($cacheKey, $cid, $oid, $this->_mergeId, $join, $where, $flip);

// Block access if user does not have EDIT permissions for both contacts.
if (!(CRM_Contact_BAO_Contact_Permission::allow($cid, CRM_Core_Permission::EDIT) &&
CRM_Contact_BAO_Contact_Permission::allow($oid, CRM_Core_Permission::EDIT)
)
) {
CRM_Utils_System::permissionDenied();
}

// get user info of main contact.
$config = CRM_Core_Config::singleton();
$config->doNotResetCache = 1;
Expand Down Expand Up @@ -176,25 +169,9 @@ public function preProcess() {

$session = CRM_Core_Session::singleton();

// context fixed.
if ($isFromDedupeScreen) {
$browseUrl = CRM_Utils_System::url('civicrm/contact/dedupefind', $urlParams . '&action=browse');
$session->pushUserContext($browseUrl);
}
$this->assign('browseUrl', empty($browseUrl) ? '' : $browseUrl);

// ensure that oid is not the current user, if so refuse to do the merge
if ($session->get('userID') == $oid) {
$display_name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $oid, 'display_name');
$message = ts('The contact record which is linked to the currently logged in user account - \'%1\' - cannot be deleted.',
array(1 => $display_name)
);
CRM_Core_Error::statusBounce($message);
}

$rowsElementsAndInfo = CRM_Dedupe_Merger::getRowsElementsAndInfo($cid, $oid);
$main = $this->_mainDetails = &$rowsElementsAndInfo['main_details'];
$other = $this->_otherDetails = &$rowsElementsAndInfo['other_details'];
$main = $this->_mainDetails = $rowsElementsAndInfo['main_details'];
$other = $this->_otherDetails = $rowsElementsAndInfo['other_details'];

if ($main['contact_id'] != $cid) {
CRM_Core_Error::fatal(ts('The main contact record does not exist'));
Expand Down Expand Up @@ -222,6 +199,19 @@ public function preProcess() {

// add elements
foreach ($rowsElementsAndInfo['elements'] as $element) {
// We could push this down to the getRowsElementsAndInfo function but it's
// already so overloaded - let's start moving towards doing form-things
// on the form.
if (substr($element[1], 0, 13) === 'move_location') {
$element[4] = array_merge(
(array) CRM_Utils_Array::value(4, $element, array()),
array('data-location' => substr($element[1], 14), 'data-is_location' => TRUE));
}
if (substr($element[1], 0, 15) === 'location_blocks') {
// @todo We could add some data elements here to make jquery manipulation more straight-forward
// @todo consider enabling if it is an add & defaulting to true.
$element[4] = array_merge((array) CRM_Utils_Array::value(4, $element, array()), array('disabled' => TRUE));
}
$this->addElement($element[0],
$element[1],
array_key_exists('2', $element) ? $element[2] : NULL,
Expand All @@ -241,22 +231,6 @@ public function preProcess() {
$this->assign('userContextURL', $session->readUserContext());
}

/**
* This virtual function is used to set the default values of
* various form elements
*
* access public
*
* @return array
* reference to the array of default values
*/
/**
* @return array
*/
public function setDefaultValues() {
return array('deleteOther' => 1);
}

public function addRules() {
}

Expand Down Expand Up @@ -366,4 +340,39 @@ public function postProcess() {
CRM_Utils_System::redirect($url);
}

/**
* Bounce if the merge action is invalid.
*
* We don't allow the merge if it is nonsensical, marked as a duplicate
* or outside the user's permission.
*
* @param int $cid
* Contact ID to retain
* @param int $oid
* Contact ID to delete.
*/
public function bounceIfInvalid($cid, $oid) {
if ($cid == $oid) {
CRM_Core_Error::statusBounce(ts('Cannot merge a contact with itself.'));
}

if (!CRM_Dedupe_BAO_Rule::validateContacts($cid, $oid)) {
CRM_Core_Error::statusBounce(ts('The selected pair of contacts are marked as non duplicates. If these records should be merged, you can remove this exception on the <a href="%1">Dedupe Exceptions</a> page.', array(1 => CRM_Utils_System::url('civicrm/dedupe/exception', 'reset=1'))));
}

if (!(CRM_Contact_BAO_Contact_Permission::allow($cid, CRM_Core_Permission::EDIT) &&
CRM_Contact_BAO_Contact_Permission::allow($oid, CRM_Core_Permission::EDIT)
)
) {
CRM_Utils_System::permissionDenied();
}
// ensure that oid is not the current user, if so refuse to do the merge
if (CRM_Core_Session::singleton()->getLoggedInContactID() == $oid) {
$message = ts('The contact record which is linked to the currently logged in user account - \'%1\' - cannot be deleted.',
array(1 => CRM_Core_Session::singleton()->getLoggedInContactDisplayName())
);
CRM_Core_Error::statusBounce($message);
}
}

}
64 changes: 36 additions & 28 deletions templates/CRM/Contact/Form/Merge.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,22 @@
$row.title|substr:0:5 == "Phone"}

<td>
{* @TODO check if this is ever an array or a fileName? *}
{* This is on one long line for address formatting *}
{if $row.title|substr:0:7 == "Address"}<span style="white-space: pre" id="main_{$blockName}_{$blockId}">{else}<span id="main_{$blockName}_{$blockId}">{/if}{if !is_array($row.main)}{$row.main}{elseif $row.main.fileName}{$row.main.fileName}{else}{', '|implode:$row.main}{/if}</span>
{strip}
{if $row.title|substr:0:7 == "Address"}
<span style="white-space: pre" id="main_{$blockName}_{$blockId}">
{else}
<span id="main_{$blockName}_{$blockId}">
{/if}
{* @TODO check if this is ever an array or a fileName? *}
{if !is_array($row.main)}
{$row.main}
{elseif $row.main.fileName}
{$row.main.fileName}
{else}
{', '|implode:$row.main}
{/if}
</span>
{/strip}
</td>

<td>
Expand Down Expand Up @@ -220,10 +233,6 @@
{/if}
{/foreach}
</table>
<div class='form-item'>
<!--<p>{$form.moveBelongings.html} {$form.moveBelongings.label}</p>-->
<!--<p>{$form.deleteOther.html} {$form.deleteOther.label}</p>-->
</div>

<div class="crm-submit-buttons">
{include file="CRM/common/formButtons.tpl" location="bottom"}
Expand All @@ -239,7 +248,7 @@
/**
* Triggered when a 'location' or 'type' destination is changed, and when
* the operation or 'set primary' checkboxes are changed.
*
*
* Check to see if the 'main' contact record has a corresponding location
* block when the destination of a field is changed. Allow existing location
* fields to be overwritten with data from the 'other' contact.
Expand Down Expand Up @@ -388,29 +397,26 @@
}
}

CRM.$(function($) {

$('table td input.form-checkbox').each(function() {
var ele = null;
var element = $(this).attr('id').split('_',3);
/**
* Toggle the location type and the is_primary on & off depending on whether the merge box is ticked.
*
* @param element
*/
function toggleRelatedLocationFields(element) {
relatedElements = CRM.$(element).parent().siblings('td').find('input,select,label,hidden');
if (CRM.$(element).is(':checked')) {
relatedElements.removeClass('disabled').attr('disabled', false);

switch ( element['1'] ) {
case 'addressee':
ele = '#' + element['0'] + '_' + element['1'];
break;
}
else {
relatedElements.addClass('disabled').attr('disabled', true);
}

case 'email':
case 'postal':
ele = '#' + element['0'] + '_' + element['1'] + '_' + element['2'];
break;
}
}

if( ele ) {
$(this).on('click', function() {
var val = $(this).prop('checked');
$('input' + ele + ', input' + ele + '_custom').prop('checked', val);
});
}
CRM.$(function($) {
$('input.crm-form-checkbox[data-is_location]').on('click', function(){
toggleRelatedLocationFields(this)
});

// Show/hide matching data rows
Expand All @@ -419,6 +425,8 @@
});

// Call mergeBlock whenever a location type is changed
// (This is applied to the body because the inputs can be added dynamically
// to the form, and we need to catch when they change.)
$('body').on('change', 'select[id$="locTypeId"],select[id$="typeTypeId"],input[id$="[operation]"],input[id$="[set_other_primary]"]', function(event){

// All the information we need is held in the id, separated by underscores
Expand Down

0 comments on commit 431f89f

Please sign in to comment.