Skip to content

Commit

Permalink
Merge pull request #23041 from christianwach/lab-core-2103
Browse files Browse the repository at this point in the history
Event Location fixes
  • Loading branch information
eileenmcnaughton authored Apr 4, 2022
2 parents 61e00c4 + 546afbd commit 5cd2310
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 37 deletions.
145 changes: 115 additions & 30 deletions CRM/Event/Form/ManageEvent/Location.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,36 +203,84 @@ public function postProcess() {
$params = $this->exportValues();
$deleteOldBlock = FALSE;

// if 'use existing location' option is selected -
if (CRM_Utils_Array::value('location_option', $params) == 2 && !empty($params['loc_event_id']) &&
($params['loc_event_id'] != $this->_oldLocBlockId)
) {
// if new selected loc is different from old loc, update the loc_block_id
// so that loc update would affect the selected loc and not the old one.
$deleteOldBlock = TRUE;
// If 'Use existing location' is selected.
if (CRM_Utils_Array::value('location_option', $params) == 2) {

/*
* If there is an existing LocBlock and the selected LocBlock is different,
* flag the existing LocBlock for deletion.
*/
if ($this->_oldLocBlockId && !empty($params['loc_event_id']) &&
($params['loc_event_id'] != $this->_oldLocBlockId)
) {
$deleteOldBlock = TRUE;
}

/*
* Always update the loc_block_id in this Event so that LocBlock update
* affects the selected LocBlock and not the previous one - whether or not
* there is a previous LocBlock.
*/
CRM_Core_DAO::setFieldValue('CRM_Event_DAO_Event', $this->_id,
'loc_block_id', $params['loc_event_id']
);

}

// if 'create new loc' option is selected, set the loc_block_id for this event to null
// so that an update would result in creating a new loc.
/*
* If there is an existing LocBlock and 'Create new location' is selected,
* set the loc_block_id for this Event to null so that an update results in
* creating a new LocBlock.
*/
if ($this->_oldLocBlockId && (CRM_Utils_Array::value('location_option', $params) == 1)) {
$deleteOldBlock = TRUE;
CRM_Core_DAO::setFieldValue('CRM_Event_DAO_Event', $this->_id,
'loc_block_id', 'null'
);
}

// if 'create new loc' option is selected OR selected new loc is different
// from old one, go ahead and delete the old loc provided thats not being
// used by any other event
/*
* If there is a previous LocBlock and we have determined that it should be
* deleted, go ahead and do so now. The method that is called will only delete
* the LocBlock if it is not being used by another Event.
*/
if ($this->_oldLocBlockId && $deleteOldBlock) {
CRM_Event_BAO_Event::deleteEventLocBlock($this->_oldLocBlockId, $this->_id);
}

$isUpdateToExistingLocationBlock = !$deleteOldBlock && !empty($params['loc_event_id']) && (int) $params['loc_event_id'] === $this->locationBlock['loc_block_id'];
// It should be impossible for there to be no default location type. Consider removing this handling
// Assume a new LocBlock is needed.
$isUpdateToExistingLocationBlock = FALSE;

/*
* If there is a previous LocBlock and it was not deleted, check if the new
* LocBlock ID matches the previous one. If so, then it needs to be updated.
*/
if (!empty($this->locationBlock['loc_block_id']) && !$deleteOldBlock) {
if (!empty($params['loc_event_id']) && (int) $params['loc_event_id'] === $this->locationBlock['loc_block_id']) {
$isUpdateToExistingLocationBlock = TRUE;
}
}

/*
* If 'Use existing location' is selected and there isn't a previous LocBlock
* but a LocBlock has been selected, then that LocBlock should be updated.
* In order to do so, the IDs of the Address, Phone and Email "Blocks" have
* to be retrieved and added in to the elements in the $params array.
*/
if (CRM_Utils_Array::value('location_option', $params) == 2) {
if (empty($this->locationBlock['loc_block_id']) && !empty($params['loc_event_id'])) {
$isUpdateToExistingLocationBlock = TRUE;
$existingLocBlock = LocBlock::get()
->addWhere('id', '=', (int) $params['loc_event_id'])
->setCheckPermissions(FALSE)
->execute()->first();
}
}

/*
* It should be impossible for there to be no default location type.
* Consider removing this handling.
*/
$defaultLocationTypeID = CRM_Core_BAO_LocationType::getDefault()->id ?? 1;

foreach ([
Expand All @@ -243,37 +291,74 @@ public function postProcess() {

$params[$block][1]['is_primary'] = 1;
foreach ($locationEntities as $index => $locationEntity) {

$fieldKey = (int) $index === 1 ? '_id' : '_2_id';

// Assume there's no Block ID.
$blockId = FALSE;

// Check the existing LocBlock for an ID.
if (!empty($this->locationBlock['loc_block_id.' . $block . $fieldKey])) {
$blockId = $this->locationBlock['loc_block_id.' . $block . $fieldKey];
}
else {
// Check the queried LocBlock for an ID.
if (!empty($existingLocBlock[$block . $fieldKey])) {
$blockId = $existingLocBlock[$block . $fieldKey];
}
}

/*
* Unsetting the array element excludes the Block from being updated and
* removes it from the LocBlock. However, the intention of clearing a Block
* is presumably to delete it.
*/
if (!$this->isLocationHasData($block, $locationEntity)) {
unset($params[$block][$index]);
if (!empty($blockId)) {
// The Block can be deleted here.
}
continue;
}

$params[$block][$index]['location_type_id'] = $defaultLocationTypeID;
$fieldKey = (int) $index === 1 ? '_id' : '_2_id';
if ($isUpdateToExistingLocationBlock && !empty($this->locationBlock['loc_block_id.' . $block . $fieldKey])) {
$params[$block][$index]['id'] = $this->locationBlock['loc_block_id.' . $block . $fieldKey];

// Assign the existing Block ID if an update is needed.
if ($isUpdateToExistingLocationBlock && !empty($blockId)) {
$params[$block][$index]['id'] = $blockId;
}
}

}

// Update the Blocks.
$addresses = empty($params['address']) ? [] : Address::save(FALSE)->setRecords($params['address'])->execute();
$emails = empty($params['email']) ? [] : Email::save(FALSE)->setRecords($params['email'])->execute();
$phones = empty($params['phone']) ? [] : Phone::save(FALSE)->setRecords($params['phone'])->execute();

$params['loc_block_id'] = LocBlock::save(FALSE)->setRecords([
[
'email_id' => $emails[0]['id'] ?? NULL,
'address_id' => $addresses[0]['id'] ?? NULL,
'phone_id' => $phones[0]['id'] ?? NULL,
'email_2_id' => $emails[1]['id'] ?? NULL,
'address_2_id' => $addresses[1]['id'] ?? NULL,
'phone_2_id' => $phones[1]['id'] ?? NULL,
],
])->execute()->first()['id'];

// finally update event params
// Build the LocBlock record.
$record = [
'email_id' => $emails[0]['id'] ?? NULL,
'address_id' => $addresses[0]['id'] ?? NULL,
'phone_id' => $phones[0]['id'] ?? NULL,
'email_2_id' => $emails[1]['id'] ?? NULL,
'address_2_id' => $addresses[1]['id'] ?? NULL,
'phone_2_id' => $phones[1]['id'] ?? NULL,
];

// Maybe trigger LocBlock update.
if ($isUpdateToExistingLocationBlock) {
$record['id'] = (int) $params['loc_event_id'];
}

// Update the LocBlock.
$params['loc_block_id'] = LocBlock::save(FALSE)->setRecords([$record])->execute()->first()['id'];

// Finally update Event params.
$params['id'] = $this->_id;
CRM_Event_BAO_Event::add($params);

// Update tab "disabled" css class
// Update tab "disabled" CSS class.
$this->ajaxResponse['tabValid'] = TRUE;
parent::endPostProcess();
}
Expand Down
20 changes: 13 additions & 7 deletions templates/CRM/Event/Form/ManageEvent/Location.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
dataType: 'json',
success: function(data) {
var selectLocBlockId = $('#loc_event_id').val();
// Only change state when options are loaded
// Only change state when options are loaded.
if (data.address_1_state_province_id) {
var defaultState = data.address_1_state_province_id;
$('#address_1_state_province_id', $form).one('crmOptionsUpdated', function() {
Expand All @@ -100,7 +100,8 @@
if ( i == 'count_loc_used' ) {
if ( ((selectLocBlockId == locBlockId) && data.count_loc_used > 1) ||
((selectLocBlockId != locBlockId) && data.count_loc_used > 0) ) {
displayMessage(data.count_loc_used);
// Counts retrieved via AJAX are already "other" Event counts.
displayMessage(parseInt(data.count_loc_used) + 1);
} else {
displayMessage(0);
}
Expand All @@ -117,12 +118,12 @@
var createNew = document.getElementsByName("location_option")[0].checked;
if (createNew) {
$('#existingLoc', $form).hide();
//clear all location fields values.
// Clear all location fields values.
if (clear !== false) {
$(":input[id *= 'address_1_'], :input[id *= 'email_1_'], :input[id *= 'phone_1_']", $form).val("").change();
{/literal}{if $config->defaultContactCountry}
{if $config->defaultContactStateProvince}
// Set default state once options are loaded
// Set default state once options are loaded.
var defaultState = {$config->defaultContactStateProvince}
{literal}
$('#address_1_state_province_id', $form).one('crmOptionsUpdated', function() {
Expand All @@ -147,9 +148,14 @@
showLocFields(false);
function displayMessage(count) {
if (count) {
var msg = {/literal}'{ts escape="js" 1="%1"}This location is used by %1 other events. Modifying location information will change values for all events.{/ts}'{literal};
$('#locUsedMsg', $form).text(ts(msg, {1: count})).addClass('status');
if (parseInt(count) > 1) {
var otherCount = parseInt(count) - 1;
if (otherCount > 1) {
var msg = {/literal}'{ts escape="js" 1="%1"}This location is used by %1 other events. Modifying location information will change values for all events.{/ts}'{literal};
} else {
var msg = {/literal}'{ts escape="js" 1="%1"}This location is used by %1 other event. Modifying location information will also change values for that event.{/ts}'{literal};
}
$('#locUsedMsg', $form).text(ts(msg, {1: otherCount})).addClass('status');
} else {
$('#locUsedMsg', $form).text(' ').removeClass('status');
}
Expand Down

0 comments on commit 5cd2310

Please sign in to comment.