From c004beab02245ad689eae3293f8a46546fb41b19 Mon Sep 17 00:00:00 2001 From: Yuri Kuznetsov Date: Wed, 21 Apr 2021 12:21:08 +0300 Subject: [PATCH] file field processing --- .../FieldProcessing/File/SaveProcessor.php | 148 ++++++++++++++++++ .../Core/FieldProcessing/SaveProcessor.php | 8 +- .../Espo/Core/Repositories/Database.php | 74 --------- .../Espo/Core/FieldProcessing/FileTest.php | 73 +++++++++ 4 files changed, 228 insertions(+), 75 deletions(-) create mode 100644 application/Espo/Core/FieldProcessing/File/SaveProcessor.php create mode 100644 tests/integration/Espo/Core/FieldProcessing/FileTest.php diff --git a/application/Espo/Core/FieldProcessing/File/SaveProcessor.php b/application/Espo/Core/FieldProcessing/File/SaveProcessor.php new file mode 100644 index 0000000000..541dda2cdc --- /dev/null +++ b/application/Espo/Core/FieldProcessing/File/SaveProcessor.php @@ -0,0 +1,148 @@ +entityManager = $entityManager; + $this->metadata = $metadata; + } + + public function process(Entity $entity, array $options): void + { + foreach ($this->getFieldList($entity->getEntityType()) as $name) { + $this->processItem($entity, $name); + } + + if ($entity->isNew()) { + return; + } + } + + private function processItem(Entity $entity, string $name): void + { + $attribute = $name . 'Id'; + + if (!$entity->get($attribute)) { + return; + } + + if (!$entity->isAttributeChanged($attribute)) { + return; + } + + $attachment = $this->entityManager->getEntity('Attachment', $entity->get($attribute)); + + if (!$attachment) { + return; + } + + $attachment->set([ + 'relatedId' => $entity->getId(), + 'relatedType' => $entity->getEntityType(), + ]); + + $this->entityManager->saveEntity($attachment); + + if ($entity->isNew()) { + return; + } + + $previousAttachmentId = $entity->getFetched($attribute); + + if (!$previousAttachmentId) { + return; + } + + $previousAttachment = $this->entityManager->getEntity('Attachment', $previousAttachmentId); + + if (!$previousAttachment) { + return; + } + + $this->entityManager->removeEntity($previousAttachment); + } + + 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->getRelationNameList() as $name) { + $defs = $entityDefs->getRelation($name); + + $type = $defs->getType(); + + if (!$defs->hasForeignEntityType()) { + continue; + } + + $foreignEntityType = $defs->getForeignEntityType(); + + if ($type !== Entity::BELONGS_TO || $foreignEntityType !== 'Attachment') { + continue; + } + + + if (!$entityDefs->hasAttribute($name . 'Id')) { + continue; + } + + $list[] = $name; + } + + $this->fieldListMapCache[$entityType] = $list; + + return $list; + } +} diff --git a/application/Espo/Core/FieldProcessing/SaveProcessor.php b/application/Espo/Core/FieldProcessing/SaveProcessor.php index 89b86caa5f..7324f7f79a 100644 --- a/application/Espo/Core/FieldProcessing/SaveProcessor.php +++ b/application/Espo/Core/FieldProcessing/SaveProcessor.php @@ -35,6 +35,7 @@ use Espo\Core\{ FieldProcessing\EmailAddress\SaveProcessor as EmailAddressSaveProcessor, FieldProcessing\PhoneNumber\SaveProcessor as PhoneNumberSaveProcessor, FieldProcessing\Relation\SaveProcessor as RelationSaveProcessor, + FieldProcessing\File\SaveProcessor as FileSaveProcessor, }; /** @@ -48,14 +49,18 @@ class SaveProcessor private $relationSaveProcessor; + private $fileSaveProcessor; + public function __construct( EmailAddressSaveProcessor $emailAddressSaveProcessor, PhoneNumberSaveProcessor $phoneNumberSaveProcessor, - RelationSaveProcessor $relationSaveProcessor + RelationSaveProcessor $relationSaveProcessor, + FileSaveProcessor $fileSaveProcessor ) { $this->emailAddressSaveProcessor = $emailAddressSaveProcessor; $this->phoneNumberSaveProcessor = $phoneNumberSaveProcessor; $this->relationSaveProcessor = $relationSaveProcessor; + $this->fileSaveProcessor = $fileSaveProcessor; } public function process(Entity $entity, array $options): void @@ -63,5 +68,6 @@ class SaveProcessor $this->emailAddressSaveProcessor->process($entity, $options); $this->phoneNumberSaveProcessor->process($entity, $options); $this->relationSaveProcessor->process($entity, $options); + $this->fileSaveProcessor->process($entity, $options); } } diff --git a/application/Espo/Core/Repositories/Database.php b/application/Espo/Core/Repositories/Database.php index 93baf55d18..2e24a3a58c 100644 --- a/application/Espo/Core/Repositories/Database.php +++ b/application/Espo/Core/Repositories/Database.php @@ -247,7 +247,6 @@ class Database extends RDBRepository parent::afterSave($entity, $options); if (!$this->processFieldsAfterSaveDisabled) { - $this->processFileFieldsSave($entity); $this->processArrayFieldsSave($entity); $this->processWysiwygFieldsSave($entity); } @@ -315,79 +314,6 @@ class Database extends RDBRepository } } - protected function processFileFieldsSave(Entity $entity) - { - $entityDefs = $this->entityManager - ->getDefs() - ->getEntity($entity->getEntityType()); - - foreach ($entity->getRelationList() as $name) { - $defs = $entityDefs->getRelation($name); - - $type = $defs->getType(); - - if (!$defs->hasForeignEntityType()) { - continue; - } - - $foreignEntityType = $defs->getForeignEntityType(); - - if (!($type === $entity::BELONGS_TO && $foreignEntityType === 'Attachment')) { - continue; - } - - $attribute = $name . 'Id'; - - if (!$entity->hasAttribute($attribute)) { - continue; - } - - if (!$entity->get($attribute)) { - continue; - } - - if (!$entity->isAttributeChanged($attribute)) { - continue; - } - - $attachment = $this->getEntityManager()->getEntity('Attachment', $entity->get($attribute)); - - if (!$attachment) { - continue; - } - - $attachment->set([ - 'relatedId' => $entity->id, - 'relatedType' => $entity->getEntityType(), - ]); - - $this->getEntityManager()->saveEntity($attachment); - } - - if ($entity->isNew()) { - return; - } - - foreach ($this->getMetadata()->get(['entityDefs', $entity->getEntityType(), 'fields']) as $name => $defs) { - if (!empty($defs['type']) && in_array($defs['type'], ['file', 'image'])) { - $attribute = $name . 'Id'; - - if ($entity->isAttributeChanged($attribute)) { - $previousAttachmentId = $entity->getFetched($attribute); - - if ($previousAttachmentId) { - $attachment = $this->getEntityManager() - ->getEntity('Attachment', $previousAttachmentId); - - if ($attachment) { - $this->getEntityManager()->removeEntity($attachment); - } - } - } - } - } - } - protected function processArrayFieldsSave(Entity $entity) { foreach ($entity->getAttributeList() as $attribute) { diff --git a/tests/integration/Espo/Core/FieldProcessing/FileTest.php b/tests/integration/Espo/Core/FieldProcessing/FileTest.php new file mode 100644 index 0000000000..edb625100d --- /dev/null +++ b/tests/integration/Espo/Core/FieldProcessing/FileTest.php @@ -0,0 +1,73 @@ +getContainer()->get('entityManager'); + + $attachment1 = $entityManager->createEntity('Attachment', [ + 'contents' => 'test-1', + 'relatedType' => 'Document', + ]); + + $document = $entityManager->createEntity('Document', [ + 'fileId' => $attachment1->getId(), + ]); + + $attachment1 = $entityManager->getEntity('Attachment', $attachment1->getId()); + + $this->assertEquals($document->getId(), $attachment1->get('relatedId')); + + $attachment2 = $entityManager->createEntity('Attachment', [ + 'contents' => 'test-2', + 'relatedType' => 'Document', + ]); + + $document->set('fileId', $attachment2->getId()); + + $entityManager->saveEntity($document); + + $attachment2 = $entityManager->getEntity('Attachment', $attachment2->getId()); + + $this->assertEquals($document->getId(), $attachment2->get('relatedId')); + + $attachment1 = $entityManager->getEntity('Attachment', $attachment1->getId()); + + $this->assertNull($attachment1); + } +}