serviceContainer = $serviceContainer; $this->config = $config; $this->entityManager = $entityManager; $this->acl = $acl; $this->dataLoaderManager = $dataLoaderManager; $this->selectBuilderFactory = $selectBuilderFactory; $this->builder = $builder; $this->defaultLanguage = $defaultLanguage; $this->jobSchedulerFactory = $jobSchedulerFactory; $this->fileStorageManager = $fileStorageManager; } /** * Generate a PDF for multiple records. * * @param string[] $idList * @throws Error * @throws NotFound * @throws Forbidden */ public function generate( string $entityType, array $idList, string $templateId, bool $withAcl = true ): string { $service = $this->serviceContainer->get($entityType); $maxCount = $this->config->get('massPrintPdfMaxCount'); if ($maxCount && count($idList) > $maxCount) { throw new Error("Mass print to PDF max count exceeded."); } /** @var ?TemplateEntity $template */ $template = $this->entityManager->getEntityById(TemplateEntity::ENTITY_TYPE, $templateId); if (!$template) { throw new NotFound(); } $params = Params::create(); if ($withAcl) { if (!$this->acl->check($template)) { throw new Forbidden(); } if (!$this->acl->checkScope($entityType)) { throw new Forbidden(); } $params = $params->withAcl(); } $selectBuilder = $this->selectBuilderFactory ->create() ->from($entityType); if ($withAcl) { $selectBuilder->withAccessControlFilter(); } $collection = $this->entityManager ->getRDBRepository($entityType) ->clone($selectBuilder->build()) ->where([ 'id' => $idList, ]) ->find(); $idDataMap = IdDataMap::create(); foreach ($collection as $entity) { $service->loadAdditionalFields($entity); $idDataMap->set( $entity->getId(), $this->dataLoaderManager->load($entity, $params) ); // For bc. if (method_exists($service, 'loadAdditionalFieldsForPdf')) { $service->loadAdditionalFieldsForPdf($entity); } } $templateWrapper = new TemplateWrapper($template); $engine = $this->config->get('pdfEngine') ?? self::DEFAULT_ENGINE; $printer = $this->builder ->setTemplate($templateWrapper) ->setEngine($engine) ->build(); $contents = $printer->printCollection($collection, $params, $idDataMap); $entityTypeTranslated = $this->defaultLanguage->translateLabel($entityType, 'scopeNamesPlural'); $type = $contents instanceof ZipContents ? 'application/zip' : 'application/pdf'; $filename = $contents instanceof ZipContents ? Util::sanitizeFileName($entityTypeTranslated) . '.zip' : Util::sanitizeFileName($entityTypeTranslated) . '.pdf'; /** @var Attachment $attachment */ $attachment = $this->entityManager->getNewEntity(Attachment::ENTITY_TYPE); $attachment ->setName($filename) ->setType($type) ->setRole(self::ATTACHMENT_MASS_PDF_ROLE) ->setSize($contents->getStream()->getSize()); $this->entityManager->saveEntity($attachment); $this->fileStorageManager->putStream($attachment, $contents->getStream()); $this->jobSchedulerFactory ->create() ->setClassName(RemoveMassFile::class) ->setData( JobData ::create() ->withTargetId($attachment->getId()) ->withTargetType(Attachment::ENTITY_TYPE) ) ->setTime( (new DateTime())->modify('+' . self::REMOVE_MASS_PDF_PERIOD) ) ->setQueue(QueueName::Q1) ->schedule(); return $attachment->getId(); } }