* 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();
}
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);
}
$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