From 63b471780d59d2bb2bd895e4921314adeb68aa46 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Fri, 23 Apr 2021 12:19:22 +0300 Subject: [PATCH] next number refactoring --- .../NextNumber/BeforeSaveProcessor.php | 154 ++++++++++++++++++ application/Espo/Hooks/Common/NextNumber.php | 81 +-------- 2 files changed, 160 insertions(+), 75 deletions(-) create mode 100644 application/Espo/Core/FieldProcessing/NextNumber/BeforeSaveProcessor.php diff --git a/application/Espo/Core/FieldProcessing/NextNumber/BeforeSaveProcessor.php b/application/Espo/Core/FieldProcessing/NextNumber/BeforeSaveProcessor.php new file mode 100644 index 0000000000..0be79534de --- /dev/null +++ b/application/Espo/Core/FieldProcessing/NextNumber/BeforeSaveProcessor.php @@ -0,0 +1,154 @@ +metadata = $metadata; + $this->entityManager = $entityManager; + } + + public function process(Entity $entity, array $options): void + { + $fieldList = $this->getFieldList($entity->getEntityType()); + + foreach ($fieldList as $field) { + $this->processItem($entity, $field, $options); + } + } + + private function processItem(Entity $entity, string $field, array $options): void + { + if (!empty($options['import'])) { + if ($entity->has($field)) { + return; + } + } + + if (!$entity->isNew()) { + if ($entity->isAttributeChanged($field)) { + $entity->set($field, $entity->getFetched($field)); + } + + return; + } + + $this->entityManager->getTransactionManager()->start(); + + $nextNumber = $this->entityManager + ->getRepository('NextNumber') + ->where([ + 'fieldName' => $field, + 'entityType' => $entity->getEntityType(), + ]) + ->forUpdate() + ->findOne(); + + if (!$nextNumber) { + $nextNumber = $this->entityManager->getEntity('NextNumber'); + + $nextNumber->set('entityType', $entity->getEntityType()); + $nextNumber->set('fieldName', $field); + } + + $entity->set($field, $this->composeNumberAttribute($nextNumber)); + + $value = $nextNumber->get('value'); + + if (!$value) { + $value = 1; + } + + $value++; + + $nextNumber->set('value', $value); + + $this->entityManager->saveEntity($nextNumber); + + $this->entityManager->getTransactionManager()->commit(); + } + + private function composeNumberAttribute(NextNumber $nextNumber): string + { + $entityType = $nextNumber->get('entityType'); + $fieldName = $nextNumber->get('fieldName'); + $value = $nextNumber->get('value'); + + $prefix = $this->metadata->get(['entityDefs', $entityType, 'fields', $fieldName, 'prefix'], ''); + $padLength = $this->metadata->get(['entityDefs', $entityType, 'fields', $fieldName, 'padLength'], 0); + + return $prefix . str_pad(strval($value), $padLength, '0', STR_PAD_LEFT); + } + + private function getFieldList(string $entityType): array + { + if (array_key_exists($entityType, $this->fieldListMapCache)) { + return $this->fieldListMapCache[$entityType]; + } + + $entityDefs = $this->entityManager + ->getDefs() + ->getEntity($entityType); + + $list = []; + + foreach ($entityDefs->getFieldNameList() as $name) { + $defs = $entityDefs->getField($name); + + if ($defs->getType() !== 'number') { + continue; + } + + $list[] = $name; + } + + $this->fieldListMapCache[$entityType] = $list; + + return $list; + } +} diff --git a/application/Espo/Hooks/Common/NextNumber.php b/application/Espo/Hooks/Common/NextNumber.php index f5f75d6f9b..9b966bcda2 100644 --- a/application/Espo/Hooks/Common/NextNumber.php +++ b/application/Espo/Hooks/Common/NextNumber.php @@ -32,89 +32,20 @@ namespace Espo\Hooks\Common; use Espo\ORM\Entity; use Espo\Core\{ - Utils\Metadata, - ORM\EntityManager, + FieldProcessing\NextNumber\BeforeSaveProcessor as Processor, }; class NextNumber { - protected $metadata; + protected $processor; - protected $entityManager; - - public function __construct(Metadata $metadata, EntityManager $entityManager) + public function __construct(Processor $processor) { - $this->metadata = $metadata; - $this->entityManager = $entityManager; + $this->processor = $processor; } - protected function composeNumberAttribute(Entity $nextNumber) + public function beforeSave(Entity $entity, array $options = []): void { - $entityType = $nextNumber->get('entityType'); - $fieldName = $nextNumber->get('fieldName'); - $value = $nextNumber->get('value'); - - $prefix = $this->metadata->get(['entityDefs', $entityType, 'fields', $fieldName, 'prefix'], ''); - $padLength = $this->metadata->get(['entityDefs', $entityType, 'fields', $fieldName, 'padLength'], 0); - - return $prefix . str_pad(strval($value), $padLength, '0', \STR_PAD_LEFT); - } - - public function beforeSave(Entity $entity, array $options = []) - { - $fieldDefs = $this->metadata->get(['entityDefs', $entity->getEntityType(), 'fields'], []); - - foreach ($fieldDefs as $fieldName => $defs) { - if (isset($defs['type']) && $defs['type'] !== 'number') { - continue; - } - - if (!empty($options['import'])) { - if ($entity->has($fieldName)) { - continue; - } - } - - if (!$entity->isNew()) { - if ($entity->isAttributeChanged($fieldName)) { - $entity->set($fieldName, $entity->getFetched($fieldName)); - } - - continue; - } - - $this->entityManager->getTransactionManager()->start(); - - $nextNumber = $this->entityManager - ->getRepository('NextNumber') - ->where([ - 'fieldName' => $fieldName, - 'entityType' => $entity->getEntityType(), - ]) - ->forUpdate() - ->findOne(); - - if (!$nextNumber) { - $nextNumber = $this->entityManager->getEntity('NextNumber'); - $nextNumber->set('entityType', $entity->getEntityType()); - $nextNumber->set('fieldName', $fieldName); - } - - $entity->set($fieldName, $this->composeNumberAttribute($nextNumber)); - - $value = $nextNumber->get('value'); - - if (!$value) { - $value = 1; - } - - $value++; - - $nextNumber->set('value', $value); - - $this->entityManager->saveEntity($nextNumber); - - $this->entityManager->getTransactionManager()->commit(); - } + $this->processor->process($entity, $options); } }