category save in transaction

This commit is contained in:
Yurii
2026-02-21 12:37:27 +02:00
parent d3da6fc8cc
commit 3321bf1020

View File

@@ -40,8 +40,57 @@ use Espo\ORM\Query\Part\Order;
*/
class CategoryTree extends Database
{
private const ATTR_ORDER = 'order';
private const ATTR_PARENT_ID = 'parentId';
private const string ATTR_ORDER = 'order';
private const string ATTR_PARENT_ID = 'parentId';
private const string PATH_ATTR_ASCENDOR_ID = 'ascendorId';
private const string PATH_ATTR_DESCENDOR_ID = 'descendorId';
/**
* @inheritDoc
*/
public function save(Entity $entity, array $options = []): void
{
$this->entityManager
->getTransactionManager()
->run(function () use ($entity, $options) {
if (!$entity->isNew() && $entity->isAttributeChanged(self::ATTR_PARENT_ID)) {
$this->lockPathEntries($entity);
}
parent::save($entity, $options);
});
}
/**
* @inheritDoc
*/
public function remove(Entity $entity, array $options = []): void
{
$this->entityManager
->getTransactionManager()
->run(function () use ($entity, $options) {
$this->lockPathEntries($entity);
parent::remove($entity, $options);
});
}
private function lockPathEntries(Entity $entity): void
{
$this->entityManager
->getRDBRepository($this->getPathEntityType())
->sth()
->select(Attribute::ID)
->where([
'OR' => [
self::PATH_ATTR_ASCENDOR_ID => $entity->getId(),
self::PATH_ATTR_DESCENDOR_ID => $entity->getId(),
]
])
->forUpdate()
->find();
}
protected function beforeSave(Entity $entity, array $options = [])
{
@@ -64,7 +113,7 @@ class CategoryTree extends Database
$em = $this->entityManager;
$pathEntityType = $entity->getEntityType() . 'Path';
$pathEntityType = $this->getPathEntityType();
if ($entity->isNew()) {
if ($parentId) {
@@ -173,7 +222,7 @@ class CategoryTree extends Database
{
parent::afterRemove($entity, $options);
$pathEntityType = $entity->getEntityType() . 'Path';
$pathEntityType = $this->getPathEntityType();
$em = $this->entityManager;
@@ -215,4 +264,9 @@ class CategoryTree extends Database
$entity->set(self::ATTR_ORDER, $order);
}
private function getPathEntityType(): string
{
return $this->entityType . 'Path';
}
}