mirror of
https://github.com/espocrm/espocrm.git
synced 2026-06-27 22:46:04 +00:00
transactional save
This commit is contained in:
@@ -69,6 +69,13 @@ class Database extends RDBRepository
|
||||
*/
|
||||
protected $hooksDisabled = false;
|
||||
|
||||
/**
|
||||
* To save and remove in a DB transaction.
|
||||
*
|
||||
* @since 9.4.0
|
||||
*/
|
||||
protected bool $transactionalSave = false;
|
||||
|
||||
/** @var ?array<string, mixed> */
|
||||
private $restoreData = null;
|
||||
/** @var Metadata */
|
||||
@@ -97,6 +104,8 @@ class Database extends RDBRepository
|
||||
$this->recordIdGenerator = $recordIdGenerator;
|
||||
|
||||
$this->hooksDisabled = $this->hooksDisabled || $metadata->get("entityDefs.$entityType.hooksDisabled");
|
||||
$this->transactionalSave = $this->transactionalSave ||
|
||||
$metadata->get("entityDefs.$entityType.transactionalSave");
|
||||
|
||||
$hookMediator = null;
|
||||
|
||||
@@ -126,6 +135,23 @@ class Database extends RDBRepository
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
public function save(Entity $entity, array $options = []): void
|
||||
{
|
||||
if ($this->transactionalSave) {
|
||||
$this->entityManager->getTransactionManager()->run(function () use ($entity, $options) {
|
||||
$this->saveInternal($entity, $options);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->saveInternal($entity, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TEntity $entity
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
private function saveInternal(Entity $entity, array $options = []): void
|
||||
{
|
||||
if (
|
||||
$entity->isNew() &&
|
||||
@@ -144,6 +170,31 @@ class Database extends RDBRepository
|
||||
parent::save($entity, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a record (mark as deleted).
|
||||
*/
|
||||
public function remove(Entity $entity, array $options = []): void
|
||||
{
|
||||
if ($this->transactionalSave) {
|
||||
$this->entityManager->getTransactionManager()->run(function () use ($entity, $options) {
|
||||
$this->removeInternal($entity, $options);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->removeInternal($entity, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param TEntity $entity
|
||||
* @param array<string, mixed> $options
|
||||
*/
|
||||
private function removeInternal(Entity $entity, array $options = []): void
|
||||
{
|
||||
parent::remove($entity, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Do not extend. Use hooks.
|
||||
*
|
||||
|
||||
@@ -35,6 +35,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Contact": {
|
||||
@@ -73,6 +80,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Lead": {
|
||||
@@ -111,6 +125,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Opportunity": {
|
||||
@@ -134,6 +155,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Document": {
|
||||
@@ -157,6 +185,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Case": {
|
||||
@@ -180,6 +215,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"KnowledgeBaseArticle": {
|
||||
@@ -203,6 +245,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Meeting": {
|
||||
@@ -248,6 +297,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Call": {
|
||||
@@ -293,6 +349,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"Task": {
|
||||
@@ -334,6 +397,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"TargetList": {
|
||||
@@ -350,6 +420,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@Event": {
|
||||
@@ -427,6 +504,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
"aclContactLink": "ACL Contact Link",
|
||||
"aclAccountLink": "ACL Account Link",
|
||||
"categories": "Categories",
|
||||
"lockable": "Lockable"
|
||||
"lockable": "Lockable",
|
||||
"transactionalSave": "Transactional Save"
|
||||
},
|
||||
"options": {
|
||||
"type": {
|
||||
@@ -100,6 +101,7 @@
|
||||
"beforeSaveApiScript": "A script called on create and update API requests before an entity is saved. Use for custom validation and duplicate checking."
|
||||
},
|
||||
"tooltips": {
|
||||
"transactionalSave": "Record saves and removals will be wrapped into DB transactions.",
|
||||
"lockable": "Enables the ability to lock records.",
|
||||
"categories": "Enable the category tree feature. Records can be placed into categories.",
|
||||
"aclContactLink": "The link with Contact to use when applying access control for portal users.",
|
||||
|
||||
@@ -76,6 +76,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@Person": {
|
||||
@@ -132,6 +139,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@Base": {
|
||||
@@ -195,6 +209,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@BasePlus": {
|
||||
@@ -258,6 +279,13 @@
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
},
|
||||
"transactionalSave": {
|
||||
"location": "entityDefs",
|
||||
"fieldDefs": {
|
||||
"type": "bool",
|
||||
"tooltip": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Disable hooks. As of v8.2."
|
||||
},
|
||||
"transactionalSave": {
|
||||
"type": "boolean",
|
||||
"description": "Enables record saving and removing in a DB transaction. As of v9.4."
|
||||
},
|
||||
"entityClassName": {
|
||||
"type": "string",
|
||||
"description": "An entity. Should implement Espo\\ORM\\Entity. Usually should extend Espo\\Core\\ORM\\Entity. As of v8.2."
|
||||
|
||||
Reference in New Issue
Block a user