From a0edf1cb6ac130a286cca03ba98d7e246bf45a2d Mon Sep 17 00:00:00 2001 From: Coleman Watts Date: Sun, 29 Aug 2021 12:17:05 -0400 Subject: [PATCH] APIv4 - Add useTrash option to soft-delete contacts This sets Contact::delete to move contacts to the trash by default. --- Civi/Api4/Action/Contact/Delete.php | 37 +++++++++++++++++++ Civi/Api4/Contact.php | 9 +++++ Civi/Api4/Generic/Traits/SoftDelete.php | 27 ++++++++++++++ Civi/Test/Api3TestTrait.php | 4 ++ tests/phpunit/api/v3/ContactTest.php | 13 +++++-- .../phpunit/api/v4/Entity/ConformanceTest.php | 11 ++++-- 6 files changed, 94 insertions(+), 7 deletions(-) create mode 100644 Civi/Api4/Action/Contact/Delete.php create mode 100644 Civi/Api4/Generic/Traits/SoftDelete.php diff --git a/Civi/Api4/Action/Contact/Delete.php b/Civi/Api4/Action/Contact/Delete.php new file mode 100644 index 0000000000..5d2267441a --- /dev/null +++ b/Civi/Api4/Action/Contact/Delete.php @@ -0,0 +1,37 @@ +useTrash, $this->checkPermissions)) { + throw new \API_Exception("Could not delete {$this->getEntityName()} id {$item['id']}"); + } + $ids[] = ['id' => $item['id']]; + } + return $ids; + } + +} diff --git a/Civi/Api4/Contact.php b/Civi/Api4/Contact.php index 1fe634a085..34f6463f55 100644 --- a/Civi/Api4/Contact.php +++ b/Civi/Api4/Contact.php @@ -26,6 +26,15 @@ namespace Civi\Api4; */ class Contact extends Generic\DAOEntity { + /** + * @param bool $checkPermissions + * @return Action\Contact\Delete + */ + public static function delete($checkPermissions = TRUE) { + return (new Action\Contact\Delete(__CLASS__, __FUNCTION__)) + ->setCheckPermissions($checkPermissions); + } + /** * @param bool $checkPermissions * @return Action\Contact\GetChecksum diff --git a/Civi/Api4/Generic/Traits/SoftDelete.php b/Civi/Api4/Generic/Traits/SoftDelete.php new file mode 100644 index 0000000000..108495d7fc --- /dev/null +++ b/Civi/Api4/Generic/Traits/SoftDelete.php @@ -0,0 +1,27 @@ + $val) { diff --git a/tests/phpunit/api/v3/ContactTest.php b/tests/phpunit/api/v3/ContactTest.php index b161260412..af6e0df138 100644 --- a/tests/phpunit/api/v3/ContactTest.php +++ b/tests/phpunit/api/v3/ContactTest.php @@ -3154,14 +3154,17 @@ class api_v3_ContactTest extends CiviUnitTestCase { /** * Test that delete with skip undelete respects permissions. - * TODO: Api4 + * + * @param int $version * * @throws \CRM_Core_Exception - * @throws \CiviCRM_API3_Exception + * @dataProvider versionThreeAndFour */ - public function testContactDeletePermissions(): void { + public function testContactDeletePermissions(int $version): void { + $this->_apiversion = $version; $contactID = $this->individualCreate(); - $tag = $this->callAPISuccess('Tag', 'create', ['name' => 'to be deleted']); + $this->quickCleanup(['civicrm_entity_tag', 'civicrm_tag']); + $tag = $this->callAPISuccess('Tag', 'create', ['name' => uniqid('to be deleted')]); $this->callAPISuccess('EntityTag', 'create', ['entity_id' => $contactID, 'tag_id' => $tag['id']]); CRM_Core_Config::singleton()->userPermissionClass->permissions = ['access CiviCRM']; $this->callAPIFailure('Contact', 'delete', [ @@ -3169,12 +3172,14 @@ class api_v3_ContactTest extends CiviUnitTestCase { 'check_permissions' => 1, 'skip_undelete' => 1, ]); + $this->callAPISuccessGetCount('EntityTag', ['entity_id' => $contactID], 1); $this->callAPISuccess('Contact', 'delete', [ 'id' => $contactID, 'check_permissions' => 0, 'skip_undelete' => 1, ]); $this->callAPISuccessGetCount('EntityTag', ['entity_id' => $contactID], 0); + $this->quickCleanup(['civicrm_entity_tag', 'civicrm_tag']); } /** diff --git a/tests/phpunit/api/v4/Entity/ConformanceTest.php b/tests/phpunit/api/v4/Entity/ConformanceTest.php index 85a069a180..0b22857262 100644 --- a/tests/phpunit/api/v4/Entity/ConformanceTest.php +++ b/tests/phpunit/api/v4/Entity/ConformanceTest.php @@ -424,10 +424,15 @@ class ConformanceTest extends UnitTestCase implements HookInterface { $this->assertEquals(0, $this->checkAccessCounts["{$entity}::delete"]); $isReadOnly = $this->isReadOnly($entityClass); - $deleteResult = $entityClass::delete() + $deleteAction = $entityClass::delete() ->setCheckPermissions(!$isReadOnly) - ->addWhere('id', '=', $id) - ->execute(); + ->addWhere('id', '=', $id); + + if (property_exists($deleteAction, 'useTrash')) { + $deleteAction->setUseTrash(FALSE); + } + + $deleteResult = $deleteAction->execute(); // should get back an array of deleted id $this->assertEquals([['id' => $id]], (array) $deleteResult); -- 2.25.1