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

ManagedEntities - Allow "match" param to convert existing records to … #22883

Merged
merged 1 commit into from
Mar 5, 2022
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
30 changes: 20 additions & 10 deletions CRM/Core/ManagedEntities.php
Original file line number Diff line number Diff line change
Expand Up @@ -311,22 +311,30 @@ protected function reconcileUnknownModules() {
* Entity specification (per hook_civicrm_managedEntities).
*/
protected function insertNewEntity($todo) {
if ($todo['params']['version'] == 4) {
$todo['params']['checkPermissions'] = FALSE;
}

$result = civicrm_api($todo['entity_type'], 'create', ['debug' => TRUE] + $todo['params']);
if (!empty($result['is_error'])) {
$this->onApiError($todo['entity_type'], 'create', $todo['params'], $result);
$params = $todo['params'];
// APIv4
if ($params['version'] == 4) {
$params['checkPermissions'] = FALSE;
// Use "save" instead of "create" action to accommodate a "match" param
$params['records'] = [$params['values']];
unset($params['values']);
$result = civicrm_api4($todo['entity_type'], 'save', $params);
$id = $result->first()['id'];
}
// APIv3
else {
$result = civicrm_api($todo['entity_type'], 'create', $params);
if (!empty($result['is_error'])) {
$this->onApiError($todo['entity_type'], 'create', $params, $result);
}
$id = $result['id'];
}

$dao = new CRM_Core_DAO_Managed();
$dao->module = $todo['module'];
$dao->name = $todo['name'];
$dao->entity_type = $todo['entity_type'];
// A fatal error will result if there is no valid id but if
// this is v4 api we might need to access it via ->first().
$dao->entity_id = $result['id'] ?? $result->first()['id'];
$dao->entity_id = $id;
$dao->cleanup = $todo['cleanup'] ?? NULL;
$dao->save();
}
Expand Down Expand Up @@ -382,6 +390,8 @@ protected function updateExistingEntity($dao, $todo) {
elseif ($doUpdate && $todo['params']['version'] == 4) {
$params = ['checkPermissions' => FALSE] + $todo['params'];
$params['values']['id'] = $dao->entity_id;
// 'match' param doesn't apply to "update" action
unset($params['match']);
civicrm_api4($dao->entity_type, 'update', $params);
}

Expand Down
51 changes: 51 additions & 0 deletions tests/phpunit/api/v4/Entity/ManagedEntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,57 @@ public function testExportAndCreateGroup() {
$this->assertGreaterThan($original['id'], $created['id']);
}

/**
* Tests a scenario where a record may already exist and we want to make it a managed entity
*/
public function testMatchExisting() {
$optionGroup = OptionGroup::create(FALSE)
->addValue('title', 'My pre-existing group')
->addValue('name', 'My_pre_existing_group')
->execute()->first();

$managed = [
'module' => 'civicrm',
'name' => 'preExistingGroup',
'entity' => 'OptionGroup',
'cleanup' => 'always',
'update' => 'always',
'params' => [
'version' => 4,
'values' => [
'name' => $optionGroup['name'],
'title' => "Cool new title",
'description' => 'Cool new description',
],
],
];
$this->_managedEntities = [$managed];

// Without "match" in the params, it will try and fail to add a duplicate managed record
try {
\CRM_Core_ManagedEntities::singleton(TRUE)->reconcile();
}
catch (\Exception $e) {
}
$this->assertStringContainsString('already exists', $e->getMessage());

// Now reconcile using a match param
$managed['params']['match'] = ['name'];
$this->_managedEntities = [$managed];
\CRM_Core_ManagedEntities::singleton(TRUE)->reconcile();

$managedGroup = OptionGroup::get(FALSE)
->addWhere('name', '=', $optionGroup['name'])
->addSelect('id', 'title', 'description', 'base_module')
->execute()->single();

$this->assertEquals($optionGroup['id'], $managedGroup['id']);
$this->assertEquals('Cool new title', $managedGroup['title']);
$this->assertEquals('Cool new description', $managedGroup['description']);
// The existing record has been converted to a managed entity!
$this->assertEquals('civicrm', $managedGroup['base_module']);
}

/**
* @dataProvider sampleEntityTypes
* @param string $entityName
Expand Down