refactoring

This commit is contained in:
Yuri Kuznetsov
2021-09-05 16:54:24 +03:00
parent 70cc8fb9e3
commit 392748db57
7 changed files with 541 additions and 420 deletions
@@ -29,8 +29,9 @@
namespace Espo\Classes\ConsoleCommands;
use Espo\Tools\Import\Service;
use Espo\Core\{
ServiceFactory,
Console\Command,
Console\Params,
Console\IO,
@@ -40,11 +41,11 @@ use Throwable;
class Import implements Command
{
protected $serviceFactory;
private $service;
public function __construct(ServiceFactory $serviceFactory)
public function __construct(Service $service)
{
$this->serviceFactory = $serviceFactory;
$this->service = $service;
}
public function run(Params $params, IO $io) : void
@@ -56,8 +57,6 @@ class Import implements Command
$forceResume = $params->hasFlag('resume');
$revert = $params->hasFlag('revert');
$service = $this->serviceFactory->create('Import');
if (!$id && $filePath) {
if (!$paramsId) {
$io->writeLine("You need to specify --params-id option.");
@@ -74,7 +73,7 @@ class Import implements Command
$contents = file_get_contents($filePath);
try {
$result = $service->importFileWithParamsId($contents, $paramsId);
$result = $this->service->importContentsWithParamsId($contents, $paramsId);
$resultId = $result->id;
$countCreated = $result->countCreated;
@@ -95,7 +94,7 @@ class Import implements Command
$io->writeLine("Reverting import...");
try {
$service->revert($id);
$this->service->revert($id);
}
catch (Throwable $e) {
$io->writeLine("Error occurred: " . $e->getMessage() . "");
@@ -112,7 +111,7 @@ class Import implements Command
$io->writeLine("Running import, this may take a while...");
try {
$result = $service->importById($id, true, $forceResume);
$result = $this->service->importById($id, true, $forceResume);
}
catch (Throwable $e) {
$io->writeLine("Error occurred: " . $e->getMessage() . "");
+42 -84
View File
@@ -33,6 +33,7 @@ use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Exceptions\BadRequest;
use Espo\Tools\Import\Params as ImportParams;
use Espo\Tools\Import\Service as Service;
use Espo\Core\{
Controllers\Record,
@@ -40,29 +41,43 @@ use Espo\Core\{
Api\Response,
};
use StdClass;
use Espo\Core\Di\InjectableFactoryAware;
use Espo\Core\Di\InjectableFactorySetter;
use stdClass;
class Import extends Record
implements InjectableFactoryAware
{
use InjectableFactorySetter;
protected function checkAccess(): bool
{
return $this->acl->check('Import');
}
public function postActionUploadFile(Request $request): StdClass
private function getImportService(): Service
{
return $this->injectableFactory->create(Service::class);
}
public function postActionUploadFile(Request $request): stdClass
{
$contents = $request->getBodyContents();
$attachmentId = $this->getService('Import')->uploadFile($contents);
$attachmentId = $this->getImportService()->uploadFile($contents);
return (object) ['attachmentId' => $attachmentId];
return (object) [
'attachmentId' => $attachmentId
];
}
public function postActionRevert(Request $request): bool
{
$data = $request->getParsedBody();
$this->getService('Import')->revert($data->id);
$this->getImportService()->revert($data->id);
return true;
}
@@ -75,97 +90,36 @@ class Import extends Record
throw new BadRequest();
}
$this->getService('Import')->removeDuplicates($data->id);
$this->getImportService()->removeDuplicates($data->id);
return true;
}
public function postActionCreate(Request $request, Response $response): StdClass
public function postActionCreate(Request $request, Response $response): stdClass
{
$data = $request->getParsedBody();
if (!isset($data->delimiter)) {
throw new BadRequest();
$entityType = $data->entityType ?? null;
$attributeList = $data->attributeList ?? null;
$attachmentId = $data->attachmentId ?? null;
if (!is_array($attributeList)) {
throw new BadRequest("No attributeList.");
}
if (!isset($data->textQualifier)) {
throw new BadRequest();
if (!$attachmentId) {
throw new BadRequest("No attachmentId.");
}
if (!isset($data->dateFormat)) {
throw new BadRequest();
if (!$entityType) {
throw new BadRequest("No entityType.");
}
if (!isset($data->timeFormat)) {
throw new BadRequest();
}
$params = ImportParams::fromRaw($data);
if (!isset($data->personNameFormat)) {
throw new BadRequest();
}
if (!isset($data->decimalMark)) {
throw new BadRequest();
}
if (!isset($data->defaultValues)) {
throw new BadRequest();
}
if (!isset($data->action)) {
throw new BadRequest();
}
if (!isset($data->attachmentId)) {
throw new BadRequest();
}
if (!isset($data->entityType)) {
throw new BadRequest();
}
if (!isset($data->attributeList)) {
throw new BadRequest();
}
$timezone = 'UTC';
if (isset($data->timezone)) {
$timezone = $data->timezone;
}
$rawParams = [
'headerRow' => !empty($data->headerRow),
'delimiter' => $data->delimiter,
'textQualifier' => $data->textQualifier,
'dateFormat' => $data->dateFormat,
'timeFormat' => $data->timeFormat,
'timezone' => $timezone,
'personNameFormat' => $data->personNameFormat,
'decimalMark' => $data->decimalMark,
'currency' => $data->currency,
'defaultValues' => $data->defaultValues,
'action' => $data->action,
'skipDuplicateChecking' => !empty($data->skipDuplicateChecking),
'idleMode' => !empty($data->idleMode),
'silentMode' => !empty($data->silentMode),
'manualMode' => !empty($data->manualMode),
];
if (property_exists($data, 'updateBy')) {
$rawParams['updateBy'] = $data->updateBy;
}
$params = ImportParams::fromRaw($rawParams);
$attachmentId = $data->attachmentId;
if (!$this->acl->check($data->entityType, 'edit')) {
throw new Forbidden();
}
return $this->getService('Import')->import(
$data->entityType,
$data->attributeList,
return $this->getImportService()->import(
$entityType,
$attributeList,
$attachmentId,
$params
);
@@ -175,11 +129,15 @@ class Import extends Record
{
$data = $request->getParsedBody();
if (empty($data->id) || empty($data->entityType) || empty($data->entityId)) {
if (
empty($data->id) ||
empty($data->entityType) ||
empty($data->entityId)
) {
throw new BadRequest();
}
$this->getService('Import')->unmarkAsDuplicate($data->id, $data->entityType, $data->entityId);
$this->getImportService()->unmarkAsDuplicate($data->id, $data->entityType, $data->entityId);
return true;
}
+37
View File
@@ -29,7 +29,44 @@
namespace Espo\Entities;
use stdClass;
class Import extends \Espo\Core\ORM\Entity
{
public const ENTITY_TYPE = 'Import';
public const STATUS_STANDBY = 'Standby';
public const STATUS_IN_PROCESS = 'In Process';
public const STATUS_FAILED = 'Failed';
public const STATUS_PENDING = 'Pending';
public const STATUS_COMPLETE = 'Complete';
public function getStatus(): ?string
{
return $this->get('status');
}
public function getParams(): ?stdClass
{
return $this->get('params');
}
public function getFileId(): ?string
{
return $this->get('fileId');
}
public function getTargetEntityType(): ?string
{
return $this->get('entityType');
}
public function getTargetAttributeList(): ?array
{
return $this->get('attributeList');
}
}
+2 -313
View File
@@ -31,33 +31,15 @@ namespace Espo\Services;
use Espo\Core\{
Exceptions\Forbidden,
Exceptions\NotFound,
Exceptions\Error,
Record\Collection as RecordCollection,
Di,
Select\SearchParams,
FieldProcessing\ListLoadProcessor,
};
use Espo\{
Services\Record,
Tools\Import\Import as ImportTool,
Tools\Import\Params as ImportParams,
};
use Espo\Services\Record;
use StdClass;
use DateTime;
class Import extends Record implements
Di\FileManagerAware,
Di\FileStorageManagerAware
class Import extends Record
{
use Di\FileManagerSetter;
use Di\FileStorageManagerSetter;
const REVERT_PERMANENTLY_REMOVE_PERIOD_DAYS = 2;
public function findLinked(string $id, string $link, SearchParams $searchParams): RecordCollection
{
if (!in_array($link, ['imported', 'duplicates', 'updated'])) {
@@ -98,297 +80,4 @@ class Import extends Record implements
return new RecordCollection($collection, $total);
}
public function uploadFile(string $contents): string
{
$attachment = $this->getEntityManager()->getEntity('Attachment');
$attachment->set('type', 'text/csv');
$attachment->set('role', 'Import File');
$attachment->set('name', 'import-file.csv');
$attachment->set('contents', $contents);
$this->getEntityManager()->saveEntity($attachment);
return $attachment->id;
}
public function revert(string $id): void
{
$import = $this->entityManager->getEntity('Import', $id);
if (empty($import)) {
throw new NotFound("Could not find import record.");
}
if (!$this->acl->check($import, 'delete')) {
throw new Forbidden("No access import record.");
}
$importEntityList = $this->entityManager->getRepository('ImportEntity')
->sth()
->where([
'importId' => $import->id,
'isImported' => true,
])
->find();
$removeFromDb = false;
$createdAt = $import->get('createdAt');
if ($createdAt) {
$dtNow = new DateTime();
$createdAtDt = new DateTime($createdAt);
$dayDiff = ($dtNow->getTimestamp() - $createdAtDt->getTimestamp()) / 60 / 60 / 24;
if ($dayDiff < self::REVERT_PERMANENTLY_REMOVE_PERIOD_DAYS) {
$removeFromDb = true;
}
}
foreach ($importEntityList as $importEntity) {
$entityType = $importEntity->get('entityType');
$entityId = $importEntity->get('entityId');
if (!$entityType || !$entityId) {
continue;
}
if (!$this->entityManager->hasRepository($entityType)) {
continue;
}
$entity = $this->entityManager->getRepository($entityType)
->select(['id'])
->where(['id' => $entityId])
->findOne();
if (!$entity) {
continue;
}
$this->entityManager->removeEntity($entity, [
'noStream' => true,
'noNotifications' => true,
'import' => true,
'silent' => true,
]);
if ($removeFromDb) {
$this->entityManager->getRepository($entityType)->deleteFromDb($entityId);
}
}
$this->getEntityManager()->removeEntity($import);
$this->processActionHistoryRecord('delete', $import);
}
public function removeDuplicates(string $id): void
{
$import = $this->entityManager->getEntity('Import', $id);
if (empty($import)) {
throw new NotFound();
}
if (!$this->acl->check($import, 'delete')) {
throw new Forbidden();
}
$importEntityList = $this->entityManager->getRepository('ImportEntity')
->sth()
->where([
'importId' => $import->id,
'isDuplicate' => true,
])
->find();
foreach ($importEntityList as $importEntity) {
$entityType = $importEntity->get('entityType');
$entityId = $importEntity->get('entityId');
if (!$entityType || !$entityId) {
continue;
}
if (!$this->entityManager->hasRepository($entityType)) {
continue;
}
$entity = $this->entityManager->getRepository($entityType)
->select(['id'])
->where(['id' => $entityId])
->findOne();
if (!$entity) {
continue;
}
$this->entityManager->removeEntity($entity, [
'noStream' => true,
'noNotifications' => true,
'import' => true,
'silent' => true,
]);
$this->entityManager->getRepository($entityType)->deleteFromDb($entityId);
}
}
protected function createImportTool(): ImportTool
{
return $this->injectableFactory->create(ImportTool::class);
}
public function jobRunIdleImport(StdClass $data): StdClass
{
if (
empty($data->userId) ||
empty($data->userId) ||
!isset($data->importAttributeList) ||
!isset($data->params) ||
!isset($data->entityType)
) {
throw new Error("Import: Bad job data.");
}
$entityType = $data->entityType;
$attachmentId = $data->attachmentId;
$importId = $data->importId;
$importAttributeList = $data->importAttributeList;
$userId = $data->userId;
$params = ImportParams::fromRaw($data->params);
$user = $this->getEntityManager()->getEntity('User', $userId);
if (!$user) {
throw new Error("Import: User not found.");
}
if (!$user->get('isActive')) {
throw new Error("Import: User is not active.");
}
return $this->createImportTool()
->setEntityType($entityType)
->setAttributeList($importAttributeList)
->setAttachmentId($attachmentId)
->setParams($params)
->setId($importId)
->setUser($user)
->run();
}
public function importById(string $id, bool $startFromLastIndex = false, bool $forceResume = false): StdClass
{
$import = $this->getEntityManager()->getEntity('Import', $id);
if (!$import) {
throw new NotFound("Import '{$id}' not found.");
}
$status = $import->get('status');
if ($status !== 'Standby') {
if (in_array($status, ['In Process', 'Failed'])) {
if (!$forceResume) {
throw new Forbidden("Import has '{$status}' status. Use -r flag to force resume.");
}
} else {
throw new Forbidden("Can't run import with '{$status}' status.");
}
}
$entityType = $import->get('entityType');
$attributeList = $import->get('attributeList') ?? [];
$params = ImportParams
::fromRaw($import->get('params'))
->withStartFromLastIndex($startFromLastIndex);
$attachmentId = $import->get('fileId');
return $this->createImportTool()
->setEntityType($entityType)
->setAttributeList($attributeList)
->setAttachmentId($attachmentId)
->setParams($params)
->setId($id)
->run();
}
public function import(
string $entityType,
array $attributeList,
string $attachmentId,
ImportParams $params
): StdClass {
$result = $this->createImportTool()
->setEntityType($entityType)
->setAttributeList($attributeList)
->setAttachmentId($attachmentId)
->setParams($params)
->run();
$id = $result->id ?? null;
if ($id) {
$import = $this->entityManager->getEntity('Import', $id);
if ($import) {
$this->processActionHistoryRecord('create', $import);
}
}
return $result;
}
public function importFileWithParamsId(string $contents, string $importParamsId): StdClass
{
if (!$contents) {
throw new Error("File contents is empty.");
}
$source = $this->getEntityManager()->getEntity('Import', $importParamsId);
if (!$source) {
throw new Error("Import {$importParamsId} not found.");
}
$entityType = $source->get('entityType');
$attributeList = $source->get('attributeList') ?? [];
$params = ImportParams::fromRaw($source->get('params'))
->withIdleMode(false)
->withManualMode(false);
$attachmentId = $this->uploadFile($contents);
return $this->import($entityType, $attributeList, $attachmentId, $params);
}
public function unmarkAsDuplicate(string $importId, string $entityType, string $entityId): void
{
$e = $this->getEntityManager()
->getRepository('ImportEntity')
->where([
'importId' => $importId,
'entityType' => $entityType,
'entityId' => $entityId,
])
->findOne();
if (!$e) {
throw new NotFound();
}
$e->set('isDuplicate', false);
$this->getEntityManager()->saveEntity($e);
}
}
+23 -14
View File
@@ -29,6 +29,10 @@
namespace Espo\Tools\Import;
use Espo\Core\Job\JobSchedulerFactory;
use Espo\Tools\Import\Jobs\RunIdle;
use Espo\Core\{
Exceptions\Error,
Utils\Json,
@@ -45,6 +49,7 @@ use Espo\ORM\Entity;
use Espo\ORM\EntityManager;
use Espo\Entities\User;
use Espo\Entities\Import as ImportEntity;
use stdClass;
use DateTime;
@@ -87,6 +92,8 @@ class Import
private $fileStorageManager;
private $jobSchedulerFactory;
private $log;
public function __construct(
@@ -97,6 +104,7 @@ class Import
User $user,
FileStorageManager $fileStorageManager,
RecordServiceContainer $recordServiceContainer,
JobSchedulerFactory $jobSchedulerFactory,
Log $log
) {
$this->aclManager = $aclManager;
@@ -106,6 +114,7 @@ class Import
$this->user = $user;
$this->fileStorageManager = $fileStorageManager;
$this->recordServiceContainer = $recordServiceContainer;
$this->jobSchedulerFactory = $jobSchedulerFactory;
$this->log = $log;
$this->params = Params::create();
@@ -247,25 +256,25 @@ class Import
$startFromIndex = $import->get('lastIndex');
}
$import->set('status', 'In Process');
$import->set('status', ImportEntity::STATUS_IN_PROCESS);
}
else {
$import = $this->entityManager->getEntity('Import');
$import = $this->entityManager->getEntity(ImportEntity::ENTITY_TYPE);
$import->set([
'entityType' => $this->entityType,
'fileId' => $this->attachmentId,
]);
$import->set('status', 'In Process');
$import->set('status', ImportEntity::STATUS_IN_PROCESS);
if ($params->isManualMode()) {
$params = $params->withIdleMode(false);
$import->set('status', 'Standby');
$import->set('status', ImportEntity::STATUS_STANDBY);
}
else if ($params->isIdleMode()) {
$import->set('status', 'Pending');
$import->set('status', ImportEntity::STATUS_PENDING);
}
$import->set('params', $params->getRaw());
@@ -284,18 +293,18 @@ class Import
}
if ($params->isIdleMode()) {
$this->entityManager->createEntity('Job', [
'serviceName' => 'Import',
'methodName' => 'jobRunIdleImport',
'data' => [
$this->jobSchedulerFactory
->create()
->setClassName(RunIdle::class)
->setData([
'entityType' => $this->entityType,
'params' => $params->withIdleMode(false)->getRaw(),
'attachmentId' => $this->attachmentId,
'importAttributeList' => $attributeList,
'importId' => $import->getId(),
'userId' => $this->user->getId(),
],
]);
])
->schedule();
return (object) [
'id' => $import->getId(),
@@ -367,15 +376,15 @@ class Import
} catch (Exception $e) {
$this->log->error('Import Error: '. $e->getMessage());
$import->set('status', 'Failed');
$import->set('status', ImportEntity::STATUS_FAILED);
}
$import->set('status', 'Complete');
$import->set('status', ImportEntity::STATUS_COMPLETE);
$this->entityManager->saveEntity($import);
return (object) [
'id' => $import->id,
'id' => $import->getId(),
'countCreated' => count($result->importedIds),
'countUpdated' => count($result->updatedIds),
];
@@ -0,0 +1,87 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Tools\Import\Jobs;
use Espo\Core\Job\Job;
use Espo\Core\Job\JobData;
use Espo\Core\Exceptions\Error;
use Espo\Tools\Import\ImportFactory;
use Espo\Tools\Import\Params as ImportParams;
use Espo\ORM\EntityManager;
use Espo\Entities\User;
class RunIdle implements Job
{
private $factory;
private $entityManager;
public function __construct(ImportFactory $factory, EntityManager $entityManager)
{
$this->factory = $factory;
$this->entityManager = $entityManager;
}
public function run(JobData $data): void
{
$raw = $data->getRaw();
$entityType = $raw->entityType;
$attachmentId = $raw->attachmentId;
$importId = $raw->importId;
$importAttributeList = $raw->importAttributeList;
$userId = $raw->userId;
$params = ImportParams::fromRaw($raw->params);
$user = $this->entityManager->getEntity(User::ENTITY_TYPE, $userId);
if (!$user) {
throw new Error("Import: User not found.");
}
if (!$user->get('isActive')) {
throw new Error("Import: User is not active.");
}
$this->factory
->create()
->setEntityType($entityType)
->setAttributeList($importAttributeList)
->setAttachmentId($attachmentId)
->setParams($params)
->setId($importId)
->setUser($user)
->run();
}
}
+342
View File
@@ -0,0 +1,342 @@
<?php
/************************************************************************
* This file is part of EspoCRM.
*
* EspoCRM - Open Source CRM application.
* Copyright (C) 2014-2021 Yurii Kuznietsov, Taras Machyshyn, Oleksii Avramenko
* Website: https://www.espocrm.com
*
* EspoCRM is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* EspoCRM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
*
* The interactive user interfaces in modified source and object code versions
* of this program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU General Public License version 3.
*
* In accordance with Section 7(b) of the GNU General Public License version 3,
* these Appropriate Legal Notices must retain the display of the "EspoCRM" word.
************************************************************************/
namespace Espo\Tools\Import;
use Espo\Core\Exceptions\Error;
use Espo\Core\Exceptions\NotFound;
use Espo\Core\Exceptions\Forbidden;
use Espo\Core\Record\ServiceContainer;
use Espo\Core\Acl;
use Espo\Core\Acl\Table;
use Espo\ORM\EntityManager;
use Espo\Entities\Import as ImportEntity;
use Espo\Entities\Attachment;
use stdClass;
use DateTime;
class Service
{
private const REVERT_PERMANENTLY_REMOVE_PERIOD_DAYS = 2;
private $factory;
private $recordServiceContainer;
private $entityManager;
private $acl;
public function __construct(
ImportFactory $factory,
ServiceContainer $recordServiceContainer,
EntityManager $entityManager,
Acl $acl
) {
$this->factory = $factory;
$this->recordServiceContainer = $recordServiceContainer;
$this->entityManager = $entityManager;
$this->acl = $acl;
}
public function import(
string $entityType,
array $attributeList,
string $attachmentId,
Params $params
): stdClass {
if (!$this->acl->check($entityType, Table::ACTION_CREATE)) {
throw new Forbidden("No create access for '{$entityType}'.");
}
$result = $this->factory
->create()
->setEntityType($entityType)
->setAttributeList($attributeList)
->setAttachmentId($attachmentId)
->setParams($params)
->run();
$id = $result->id ?? null;
if ($id) {
$import = $this->entityManager->getEntity(ImportEntity::ENTITY_TYPE, $id);
if ($import) {
$this->recordServiceContainer
->get(ImportEntity::ENTITY_TYPE)
->processActionHistoryRecord('create', $import);
}
}
return $result;
}
public function importContentsWithParamsId(string $contents, string $importParamsId): stdClass
{
if (!$contents) {
throw new Error("Contents is empty.");
}
/** @var ImportEntity $source */
$source = $this->entityManager->getEntity(ImportEntity::ENTITY_TYPE, $importParamsId);
if (!$source) {
throw new Error("Import '{$importParamsId}' not found.");
}
$entityType = $source->getTargetEntityType();
$attributeList = $source->getTargetAttributeList() ?? [];
$params = ImportParams::fromRaw($source->getParams())
->withIdleMode(false)
->withManualMode(false);
$attachmentId = $this->uploadFile($contents);
return $this->import($entityType, $attributeList, $attachmentId, $params);
}
public function importById(string $id, bool $startFromLastIndex = false, bool $forceResume = false): stdClass
{
/** @var ImportEntity $import */
$import = $this->entityManager->getEntity(ImportEntity::ENTITY_TYPE, $id);
if (!$import) {
throw new NotFound("Import '{$id}' not found.");
}
$status = $import->getStatus();
if ($status !== ImportEntity::STATUS_STANDBY) {
if (!in_array($status, [ImportEntity::STATUS_IN_PROCESS, ImportEntity::STATUS_FAILED])) {
throw new Forbidden("Can't run import with '{$status}' status.");
}
if (!$forceResume) {
throw new Forbidden("Import has '{$status}' status. Use -r flag to force resume.");
}
}
$entityType = $import->getTargetEntityType();
$attributeList = $import->getTargetAttributeList() ?? [];
$params = ImportParams
::fromRaw($import->getParams())
->withStartFromLastIndex($startFromLastIndex);
$attachmentId = $import->getFileId();
return $this->factory
->create()
->setEntityType($entityType)
->setAttributeList($attributeList)
->setAttachmentId($attachmentId)
->setParams($params)
->setId($id)
->run();
}
public function revert(string $id): void
{
$import = $this->entityManager->getEntity('Import', $id);
if (!$import) {
throw new NotFound("Could not find import record.");
}
if (!$this->acl->checkEntityDelete($import)) {
throw new Forbidden("No access import record.");
}
$importEntityList = $this->entityManager
->getRDBRepository('ImportEntity')
->sth()
->where([
'importId' => $import->getId(),
'isImported' => true,
])
->find();
$removeFromDb = false;
$createdAt = $import->get('createdAt');
if ($createdAt) {
$dtNow = new DateTime();
$createdAtDt = new DateTime($createdAt);
$dayDiff = ($dtNow->getTimestamp() - $createdAtDt->getTimestamp()) / 60 / 60 / 24;
if ($dayDiff < self::REVERT_PERMANENTLY_REMOVE_PERIOD_DAYS) {
$removeFromDb = true;
}
}
foreach ($importEntityList as $importEntity) {
$entityType = $importEntity->get('entityType');
$entityId = $importEntity->get('entityId');
if (!$entityType || !$entityId) {
continue;
}
if (!$this->entityManager->hasRepository($entityType)) {
continue;
}
$entity = $this->entityManager
->getRDBRepository($entityType)
->select(['id'])
->where(['id' => $entityId])
->findOne();
if (!$entity) {
continue;
}
$this->entityManager->removeEntity($entity, [
'noStream' => true,
'noNotifications' => true,
'import' => true,
'silent' => true,
]);
if ($removeFromDb) {
$this->entityManager
->getRDBRepository($entityType)
->deleteFromDb($entityId);
}
}
$this->entityManager->removeEntity($import);
$this->recordServiceContainer
->get(ImportEntity::ENTITY_TYPE)
->processActionHistoryRecord('delete', $import);
}
/**
* @return Attachment ID.
*/
public function uploadFile(string $contents): string
{
$attachment = $this->entityManager->getEntity(Attachment::ENTITY_TYPE);
$attachment->set('type', 'text/csv');
$attachment->set('role', 'Import File');
$attachment->set('name', 'import-file.csv');
$attachment->set('contents', $contents);
$this->entityManager->saveEntity($attachment);
return $attachment->getId();
}
public function removeDuplicates(string $id): void
{
$import = $this->entityManager->getEntity(ImportEntity::ENTITY_TYPE, $id);
if (!$import) {
throw new NotFound("Import '{$id}' not found.");
}
if (!$this->acl->checkEntityDelete($import)) {
throw new Forbidden("No delete access.");
}
$importEntityList = $this->entityManager
->getRDBRepository('ImportEntity')
->sth()
->where([
'importId' => $import->getId(),
'isDuplicate' => true,
])
->find();
foreach ($importEntityList as $importEntity) {
$entityType = $importEntity->get('entityType');
$entityId = $importEntity->get('entityId');
if (!$entityType || !$entityId) {
continue;
}
if (!$this->entityManager->hasRepository($entityType)) {
continue;
}
$entity = $this->entityManager
->getRDBRepository($entityType)
->select(['id'])
->where(['id' => $entityId])
->findOne();
if (!$entity) {
continue;
}
$this->entityManager->removeEntity($entity, [
'noStream' => true,
'noNotifications' => true,
'import' => true,
'silent' => true,
]);
$this->entityManager
->getRDBRepository($entityType)
->deleteFromDb($entityId);
}
}
public function unmarkAsDuplicate(string $importId, string $entityType, string $entityId): void
{
$entity = $this->entityManager
->getRDBRepository('ImportEntity')
->where([
'importId' => $importId,
'entityType' => $entityType,
'entityId' => $entityId,
])
->findOne();
if (!$entity) {
throw new NotFound();
}
$entity->set('isDuplicate', false);
$this->entityManager->saveEntity($entity);
}
}