Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize deletion mechanics across ~13 BAOs #22207

Merged
merged 13 commits into from
Dec 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions CRM/Case/BAO/CaseType.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
/**
* This class contains the functions for Case Type management.
*/
class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType {
class CRM_Case_BAO_CaseType extends CRM_Case_DAO_CaseType implements \Civi\Test\HookInterface {

/**
* Static field for all the case information that we can potentially export.
Expand Down Expand Up @@ -65,7 +65,6 @@ public static function add(&$params) {

$caseTypeDAO->copyValues($params);
$result = $caseTypeDAO->save();
CRM_Case_XMLRepository::singleton()->flush();
return $result;
}

Expand Down Expand Up @@ -407,13 +406,10 @@ public static function &create(&$params) {
$transaction->rollback();
return $caseType;
}
$transaction->commit();

CRM_Utils_Hook::post($action, 'CaseType', $caseType->id, $case);

$transaction->commit();
CRM_Case_XMLRepository::singleton(TRUE);
CRM_Core_OptionGroup::flushAll();

return $caseType;
}

Expand All @@ -438,20 +434,40 @@ public static function retrieve(&$params, &$defaults) {
/**
* @param int $caseTypeId
*
* @deprecated
* @throws CRM_Core_Exception
* @return mixed
* @return CRM_Case_DAO_CaseType
*/
public static function del($caseTypeId) {
$caseType = new CRM_Case_DAO_CaseType();
$caseType->id = $caseTypeId;
$refCounts = $caseType->getReferenceCounts();
$total = array_sum(CRM_Utils_Array::collect('count', $refCounts));
if ($total) {
throw new CRM_Core_Exception(ts("You can not delete this case type -- it is assigned to %1 existing case record(s). If you do not want this case type to be used going forward, consider disabling it instead.", [1 => $total]));
return static::deleteRecord(['id' => $caseTypeId]);
}

/**
* Callback for hook_civicrm_pre().
* @param \Civi\Core\Event\PreEvent $event
* @throws CRM_Core_Exception
*/
public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) {
// Before deleting a caseType, check references
if ($event->action === 'delete') {
$caseType = new CRM_Case_DAO_CaseType();
$caseType->id = $event->id;
$refCounts = $caseType->getReferenceCounts();
$total = array_sum(CRM_Utils_Array::collect('count', $refCounts));
if (array_sum(CRM_Utils_Array::collect('count', $refCounts))) {
throw new CRM_Core_Exception(ts("You can not delete this case type -- it is assigned to %1 existing case record(s). If you do not want this case type to be used going forward, consider disabling it instead.", [1 => $total]));
}
}
$result = $caseType->delete();
CRM_Case_XMLRepository::singleton(TRUE);
return $result;
}

/**
* Callback for hook_civicrm_post().
* @param \Civi\Core\Event\PostEvent $event
*/
public static function self_hook_civicrm_post(\Civi\Core\Event\PostEvent $event) {
// When a caseType is saved or deleted, flush xml and optionGroup cache
CRM_Case_XMLRepository::singleton()->flush();
CRM_Core_OptionGroup::flushAll();
}

/**
Expand Down
85 changes: 51 additions & 34 deletions CRM/Contact/BAO/ContactType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @package CRM
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
class CRM_Contact_BAO_ContactType extends CRM_Contact_DAO_ContactType {
class CRM_Contact_BAO_ContactType extends CRM_Contact_DAO_ContactType implements \Civi\Test\HookInterface {

/**
* Fetch object based on array of properties.
Expand Down Expand Up @@ -460,52 +460,69 @@ public static function getCreateNewList() {
*
* @param int $contactTypeId
* ID of the Contact Subtype to be deleted.
*
* @deprecated
* @return bool
*/
public static function del($contactTypeId) {

if (!$contactTypeId) {
return FALSE;
}

$params = ['id' => $contactTypeId];
self::retrieve($params, $typeInfo);
$name = $typeInfo['name'];
// check if any custom group
$custom = new CRM_Core_DAO_CustomGroup();
$custom->whereAdd("extends_entity_column_value LIKE '%" .
CRM_Core_DAO::VALUE_SEPARATOR .
$name .
CRM_Core_DAO::VALUE_SEPARATOR . "%'"
);
if ($custom->find()) {
try {
static::deleteRecord(['id' => $contactTypeId]);
return TRUE;
}
catch (CRM_Core_Exception $e) {
return FALSE;
}
}

// remove subtype for existing contacts
$sql = "
/**
* Callback for hook_civicrm_pre().
* @param \Civi\Core\Event\PreEvent $event
* @throws CRM_Core_Exception
*/
public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) {
// Before deleting a contactType, check references by custom groups
if ($event->action === 'delete') {
$name = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_ContactType', $event->id);
$sep = CRM_Core_DAO::VALUE_SEPARATOR;
$custom = new CRM_Core_DAO_CustomGroup();
$custom->whereAdd("extends_entity_column_value LIKE '%{$sep}{$name}{$sep}%'");
if ($custom->find()) {
throw new CRM_Core_Exception(ts("You can not delete this contact type -- it is used by %1 custom field group(s). The custom fields must be deleted first.", [1 => $custom->N]));
}
}
}

/**
* Callback for hook_civicrm_post().
* @param \Civi\Core\Event\PostEvent $event
*/
public static function self_hook_civicrm_post(\Civi\Core\Event\PostEvent $event) {
if ($event->action === 'delete') {
$sep = CRM_Core_DAO::VALUE_SEPARATOR;
$subType = "$sep{$event->object->name}$sep";
// For contacts with just the one sub-type, set to null
$sql = "
UPDATE civicrm_contact SET contact_sub_type = NULL
WHERE contact_sub_type = '$name'";
CRM_Core_DAO::executeQuery($sql);
WHERE contact_sub_type = '$subType'";
CRM_Core_DAO::executeQuery($sql);
// For contacts with multipe sub-types, remove this one
$sql = "
UPDATE civicrm_contact SET contact_sub_type = REPLACE(contact_sub_type, '$subType', '$sep')
WHERE contact_sub_type LIKE '%{$subType}%'";
CRM_Core_DAO::executeQuery($sql);

// remove navigation entry which was auto-created when this sub-type was added
\Civi\Api4\Navigation::delete(FALSE)
->addWhere('name', '=', "New {$event->object->name}")
->addWhere('url', 'LIKE', 'civicrm/contact/add%')
// Overide the default which limits to a single domain
->addWhere('domain_id', '>', 0)
->execute();

// remove subtype from contact type table
$contactType = new CRM_Contact_DAO_ContactType();
$contactType->id = $contactTypeId;
$contactType->delete();

// remove navigation entry if any
if ($name) {
$sql = '
DELETE
FROM civicrm_navigation
WHERE name = %1';
$params = [1 => ["New $name", 'String']];
CRM_Core_DAO::executeQuery($sql, $params);
CRM_Core_BAO_Navigation::resetNavigation();
Civi::cache('contactTypes')->clear();
}
return TRUE;
}

/**
Expand Down
48 changes: 15 additions & 33 deletions CRM/Contact/BAO/RelationshipType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @package CRM
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
class CRM_Contact_BAO_RelationshipType extends CRM_Contact_DAO_RelationshipType {
class CRM_Contact_BAO_RelationshipType extends CRM_Contact_DAO_RelationshipType implements \Civi\Test\HookInterface {

/**
* Class constructor.
Expand Down Expand Up @@ -99,6 +99,7 @@ public static function add($params) {
*
* @param int $relationshipTypeId
*
* @deprecated
* @throws CRM_Core_Exception
* @return mixed
*/
Expand All @@ -109,40 +110,21 @@ public static function del($relationshipTypeId) {
if (!CRM_Utils_Rule::positiveInteger($relationshipTypeId)) {
throw new CRM_Core_Exception(ts('Invalid relationship type'));
}
return static::deleteRecord(['id' => $relationshipTypeId]);
}

//check dependencies

// delete all relationships
$relationship = new CRM_Contact_DAO_Relationship();
$relationship->relationship_type_id = $relationshipTypeId;
$relationship->delete();

// remove this relationship type from membership types
$mems = civicrm_api3('MembershipType', 'get', [
'relationship_type_id' => ['LIKE' => "%{$relationshipTypeId}%"],
'return' => ['id', 'relationship_type_id', 'relationship_direction'],
]);
foreach ($mems['values'] as $membershipTypeId => $membershipType) {
$pos = array_search($relationshipTypeId, $membershipType['relationship_type_id']);
// Api call may have returned false positives but currently the relationship_type_id uses
// nonstandard serialization which makes anything more accurate impossible.
if ($pos !== FALSE) {
unset($membershipType['relationship_type_id'][$pos], $membershipType['relationship_direction'][$pos]);
civicrm_api3('MembershipType', 'create', $membershipType);
}
}

//fixed for CRM-3323
$mappingField = new CRM_Core_DAO_MappingField();
$mappingField->relationship_type_id = $relationshipTypeId;
$mappingField->find();
while ($mappingField->fetch()) {
$mappingField->delete();
/**
* Callback for hook_civicrm_pre().
* @param \Civi\Core\Event\PreEvent $event
* @throws CRM_Core_Exception
*/
public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) {
if ($event->action === 'delete') {
// need to delete all option value field before deleting group
\Civi\Api4\Relationship::delete(FALSE)
->addWhere('relationship_type_id', '=', $event->id)
->execute();
}

$relationshipType = new CRM_Contact_DAO_RelationshipType();
$relationshipType->id = $relationshipTypeId;
return $relationshipType->delete();
}

}
37 changes: 18 additions & 19 deletions CRM/Core/BAO/LocationType.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @package CRM
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
class CRM_Core_BAO_LocationType extends CRM_Core_DAO_LocationType {
class CRM_Core_BAO_LocationType extends CRM_Core_DAO_LocationType implements \Civi\Test\HookInterface {

/**
* Static holder for the default LT.
Expand Down Expand Up @@ -126,28 +126,27 @@ public static function create(&$params) {
* Delete location Types.
*
* @param int $locationTypeId
* ID of the location type to be deleted.
*
* @deprecated
*/
public static function del($locationTypeId) {
$entity = ['address', 'phone', 'email', 'im'];
//check dependencies
foreach ($entity as $key) {
if ($key == 'im') {
$name = strtoupper($key);
}
else {
$name = ucfirst($key);
static::deleteRecord(['id' => $locationTypeId]);
}

/**
* Callback for hook_civicrm_pre().
* @param \Civi\Core\Event\PreEvent $event
* @throws CRM_Core_Exception
*/
public static function self_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) {
// When deleting a location type, delete related records
if ($event->action === 'delete') {
foreach (['Address', 'IM', 'Email', 'Phone'] as $entity) {
civicrm_api4($entity, 'delete', [
'checkPermissions' => FALSE,
'where' => [['location_type_id', '=', $event->id]],
]);
}
$baoString = 'CRM_Core_BAO_' . $name;
$object = new $baoString();
$object->location_type_id = $locationTypeId;
$object->delete();
}

$locationType = new CRM_Core_DAO_LocationType();
$locationType->id = $locationTypeId;
$locationType->delete();
}

}
16 changes: 15 additions & 1 deletion CRM/Core/BAO/Mapping.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* @package CRM
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/
class CRM_Core_BAO_Mapping extends CRM_Core_DAO_Mapping {
class CRM_Core_BAO_Mapping extends CRM_Core_DAO_Mapping implements \Civi\Test\HookInterface {

/**
* Class constructor.
Expand Down Expand Up @@ -1211,4 +1211,18 @@ public static function removeFieldFromMapping($fieldName): void {
$mappingField->delete();
}

/**
* Callback for hook_civicrm_pre().
* @param \Civi\Core\Event\PreEvent $event
* @throws CRM_Core_Exception
*/
public static function on_hook_civicrm_pre(\Civi\Core\Event\PreEvent $event) {
if ($event->action === 'delete' && $event->entity === 'RelationshipType') {
// CRM-3323 - Delete mappingField records when deleting relationship type
\Civi\Api4\MappingField::delete(FALSE)
->addWhere('relationship_type_id', '=', $event->id)
->execute();
}
}

}
Loading