Skip to content

Commit

Permalink
Merge pull request #16856 from colemanw/writeRecord
Browse files Browse the repository at this point in the history
Add DAO::writeRecord and DAO::deleteRecord methods
  • Loading branch information
eileenmcnaughton authored Mar 19, 2020
2 parents fd04bde + 2ee9afa commit 86938d4
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 58 deletions.
56 changes: 56 additions & 0 deletions CRM/Core/DAO.php
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,62 @@ public static function getAttribute($class, $fieldName = NULL) {
return NULL;
}

/**
* Create or update a record from supplied params.
*
* If 'id' is supplied, an existing record will be updated
* Otherwise a new record will be created.
*
* @param array $record
* @return CRM_Core_DAO
* @throws CRM_Core_Exception
*/
public static function writeRecord(array $record) {
$hook = empty($record['id']) ? 'create' : 'edit';
$className = CRM_Core_DAO_AllCoreTables::getCanonicalClassName(static::class);
if ($className === 'CRM_Core_DAO') {
throw new CRM_Core_Exception('Function writeRecord must be called on a subclass of CRM_Core_DAO');
}
$entityName = CRM_Core_DAO_AllCoreTables::getBriefName($className);

\CRM_Utils_Hook::pre($hook, $entityName, $record['id'] ?? NULL, $record);
$instance = new $className();
$instance->copyValues($record);
$instance->save();
\CRM_Utils_Hook::post($hook, $entityName, $instance->id, $instance);

return $instance;
}

/**
* Delete a record from supplied params.
*
* @param array $record
* 'id' is required.
* @return CRM_Core_DAO
* @throws CRM_Core_Exception
*/
public static function deleteRecord(array $record) {
$className = CRM_Core_DAO_AllCoreTables::getCanonicalClassName(static::class);
if ($className === 'CRM_Core_DAO') {
throw new CRM_Core_Exception('Function deleteRecord must be called on a subclass of CRM_Core_DAO');
}
$entityName = CRM_Core_DAO_AllCoreTables::getBriefName($className);
if (empty($record['id'])) {
throw new CRM_Core_Exception("Cannot delete {$entityName} with no id.");
}

CRM_Utils_Hook::pre('delete', $entityName, $record['id'], $record);
$instance = new $className();
$instance->id = $record['id'];
if (!$instance->delete()) {
throw new CRM_Core_Exception("Could not delete {$entityName} id {$record['id']}");
}
CRM_Utils_Hook::post('delete', $entityName, $record['id'], $instance);

return $instance;
}

/**
* Check if there is a record with the same name in the db.
*
Expand Down
17 changes: 5 additions & 12 deletions Civi/Api4/Generic/DAODeleteAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ protected function deleteObjects($items) {
$baoName = $this->getBaoName();

if ($this->getCheckPermissions()) {
foreach ($items as $item) {
$this->checkContactPermissions($baoName, $item);
foreach (array_keys($items) as $key) {
$items[$key]['check_permissions'] = TRUE;
$this->checkContactPermissions($baoName, $items[$key]);
}
}

Expand All @@ -73,16 +74,8 @@ protected function deleteObjects($items) {
}
else {
foreach ($items as $item) {
$bao = new $baoName();
$bao->id = $item['id'];
// delete it
$action_result = $bao->delete();
if ($action_result) {
$ids[] = ['id' => $item['id']];
}
else {
throw new \API_Exception("Could not delete {$this->getEntityName()} id {$item['id']}");
}
$baoName::deleteRecord($item);
$ids[] = ['id' => $item['id']];
}
}
return $ids;
Expand Down
24 changes: 2 additions & 22 deletions Civi/Api4/Generic/Traits/DAOActionTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ protected function writeObjects($items) {
$createResult = $baoName::$method($item);
}
else {
$createResult = $this->genericCreateMethod($item);
$createResult = $baoName::writeRecord($item);
}

if (!$createResult) {
Expand All @@ -180,26 +180,6 @@ protected function writeObjects($items) {
return $result;
}

/**
* Fallback when a BAO does not contain create or add functions
*
* @param $params
* @return mixed
*/
private function genericCreateMethod($params) {
$baoName = $this->getBaoName();
$hook = empty($params['id']) ? 'create' : 'edit';

\CRM_Utils_Hook::pre($hook, $this->getEntityName(), $params['id'] ?? NULL, $params);
/** @var \CRM_Core_DAO $instance */
$instance = new $baoName();
$instance->copyValues($params);
$instance->save();
\CRM_Utils_Hook::post($hook, $this->getEntityName(), $instance->id, $instance);

return $instance;
}

/**
* @param array $params
* @param int $entityId
Expand Down Expand Up @@ -281,7 +261,7 @@ protected function checkContactPermissions($baoName, $item) {
else {
// Fixme: decouple from v3
require_once 'api/v3/utils.php';
_civicrm_api3_check_edit_permissions($baoName, ['check_permissions' => 1] + $item);
_civicrm_api3_check_edit_permissions($baoName, $item);
}
}

Expand Down
27 changes: 3 additions & 24 deletions api/v3/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -1325,37 +1325,16 @@ function _civicrm_api3_basic_create($bao_name, &$params, $entity = NULL) {
/**
* For BAO's which don't have a create() or add() functions, use this fallback implementation.
*
* @fixme There's an intuitive sense that this behavior should be defined somehow in the BAO/DAO class
* structure. In practice, that requires a fair amount of refactoring and/or kludgery.
*
* @param string $bao_name
* @param string|CRM_Core_DAO $bao_name
* @param array $params
*
* @throws API_Exception
*
* @return CRM_Core_DAO|NULL
* An instance of the BAO
*/
function _civicrm_api3_basic_create_fallback($bao_name, &$params) {
$dao_name = get_parent_class($bao_name);
if ($dao_name === 'CRM_Core_DAO' || !$dao_name) {
$dao_name = $bao_name;
}
$entityName = CRM_Core_DAO_AllCoreTables::getBriefName($dao_name);
if (empty($entityName)) {
throw new API_Exception("Class \"$bao_name\" does not map to an entity name", "unmapped_class_to_entity", [
'class_name' => $bao_name,
]);
}
$hook = empty($params['id']) ? 'create' : 'edit';

CRM_Utils_Hook::pre($hook, $entityName, CRM_Utils_Array::value('id', $params), $params);
$instance = new $dao_name();
$instance->copyValues($params);
$instance->save();
CRM_Utils_Hook::post($hook, $entityName, $instance->id, $instance);

return $instance;
function _civicrm_api3_basic_create_fallback($bao_name, $params) {
return $bao_name::writeRecord($params);
}

/**
Expand Down

0 comments on commit 86938d4

Please sign in to comment.