getRepository()->get($id); $foreignEntityType = $entity->get('entityType'); if (!$this->acl->check($entity, 'read')) { throw new Forbidden(); } if (!$this->acl->check($foreignEntityType, 'read')) { throw new Forbidden(); } $query = $this->selectBuilderFactory ->create() ->from($foreignEntityType) ->withStrictAccessControl() ->withSearchParams($searchParams) ->build(); $collection = $this->getRepository()->findResultRecords($entity, $link, $query); $listLoadProcessor = $this->injectableFactory->create(ListLoadProcessor::class); $recordService = $this->recordServiceContainer->get($foreignEntityType); foreach ($collection as $e) { $listLoadProcessor->process($e); $recordService->prepareEntityForOutput($e); } $total = $this->getRepository()->countResultRecords($entity, $link, $query); 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; $params = json_decode(json_encode($data->params), true); $attachmentId = $data->attachmentId; $importId = $data->importId; $importAttributeList = $data->importAttributeList; $userId = $data->userId; $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 = $import->get('params') ?? (object) []; $params = json_decode(json_encode($params), true); $params['startFromLastIndex'] = $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, array $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 = $source->get('params') ?? (object) []; $params = json_decode(json_encode($params), true); unset($params['idleMode']); unset($params['manualMode']); $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); } }