diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 0d2e6d259b..a8d4dbc1b4 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -171,7 +171,6 @@ public function sign(string $uuid): TemplateResponse { ->formatFile(); $this->initialState->provideInitialState('status', $file['status']); $this->initialState->provideInitialState('statusText', $file['statusText']); - $this->initialState->provideInitialState('visibleElements', $file['visibleElements']); $this->initialState->provideInitialState('signers', $file['signers']); $this->provideSignerSignatues(); $signatureMethods = $this->identifyMethodService->getSignMethodsOfIdentifiedFactors($this->getSignRequestEntity()->getId()); diff --git a/lib/Db/SignRequestMapper.php b/lib/Db/SignRequestMapper.php index 202397e67c..0f8fa5492a 100644 --- a/lib/Db/SignRequestMapper.php +++ b/lib/Db/SignRequestMapper.php @@ -24,6 +24,7 @@ namespace OCA\Libresign\Db; +use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use OCA\Libresign\Helper\Pagination; use OCA\Libresign\Service\IdentifyMethod\IIdentifyMethod; use OCA\Libresign\Service\IdentifyMethodService; @@ -368,11 +369,41 @@ public function getFilesAssociatedFilesWithMeFormatted( } $signers = $this->getByMultipleFileId($fileIds); $identifyMethods = $this->getIdentifyMethodsFromSigners($signers); - $return['data'] = $this->associateAllAndFormat($user, $data, $signers, $identifyMethods); + $visibleElements = $this->getVisibleElementsFromSigners($signers); + $return['data'] = $this->associateAllAndFormat($user, $data, $signers, $identifyMethods, $visibleElements); $return['pagination'] = $pagination; return $return; } + /** + * @param array $signRequests + * @return FileElement[][] + */ + private function getVisibleElementsFromSigners(array $signRequests): array { + $signRequestIds = array_map(function (SignRequest $signRequest): int { + return $signRequest->getId(); + }, $signRequests); + if (!$signRequestIds) { + return []; + } + $qb = $this->db->getQueryBuilder(); + $qb->select('fe.*') + ->from('libresign_file_element', 'fe') + ->where( + $qb->expr()->in('fe.sign_request_id', $qb->createParameter('signRequestIds')) + ); + $return = []; + foreach (array_chunk($signRequestIds, 1000) as $signRequestIdsChunk) { + $qb->setParameter('signRequestIds', $signRequestIdsChunk, IQueryBuilder::PARAM_INT_ARRAY); + $cursor = $qb->executeQuery(); + while ($row = $cursor->fetch()) { + $fileElement = new FileElement(); + $return[$row['sign_request_id']][] = $fileElement->fromRow($row); + } + } + return $return; + } + /** * @param array $signRequests * @return array> @@ -435,6 +466,13 @@ private function getFilesAssociatedFilesWithMeQueryBuilder(string $userId, ?stri 'f.status', 'f.created_at', ); + // metadata is a json column, the right way is to use f.metadata::text + // when the database is PostgreSQL. The problem is that the command + // addGroupBy add quotes over all text send as argument. With + // PostgreSQL json columns don't have problem if not added to group by. + if (!$qb->getConnection()->getDatabasePlatform() instanceof PostgreSQLPlatform) { + $qb->addGroupBy('f.metadata'); + } $or = [ $qb->expr()->eq('f.user_id', $qb->createNamedParameter($userId)), @@ -473,7 +511,8 @@ private function getFilesAssociatedFilesWithMeStmt(string $userId, ?string $emai 'f.user_id', 'f.uuid', 'f.name', - 'f.status' + 'f.status', + 'f.metadata', ); $qb->selectAlias('f.created_at', 'request_date'); @@ -497,8 +536,9 @@ private function getFilesAssociatedFilesWithMeStmt(string $userId, ?string $emai * @param array $files * @param array $signers * @param array> $identifyMethods + * @param SignRequest[][] */ - private function associateAllAndFormat(IUser $user, array $files, array $signers, array $identifyMethods): array { + private function associateAllAndFormat(IUser $user, array $files, array $signers, array $identifyMethods, array $visibleElements): array { foreach ($files as $key => $file) { $totalSigned = 0; foreach ($signers as $signerKey => $signer) { @@ -540,6 +580,29 @@ private function associateAllAndFormat(IUser $user, array $files, array $signers } return $carry; }, false), + 'visibleElements' => array_map(function (FileElement $visibleElement) use ($file) { + $element = [ + 'elementId' => $visibleElement->getId(), + 'signRequestId' => $visibleElement->getSignRequestId(), + 'type' => $visibleElement->getType(), + 'coordinates' => [ + 'page' => $visibleElement->getPage(), + 'urx' => $visibleElement->getUrx(), + 'ury' => $visibleElement->getUry(), + 'llx' => $visibleElement->getLlx(), + 'lly' => $visibleElement->getLly() + ] + ]; + $metadata = json_decode($file['metadata'], true); + $dimension = $metadata['d'][$element['coordinates']['page'] - 1]; + + $element['coordinates']['left'] = $element['coordinates']['llx']; + $element['coordinates']['height'] = abs($element['coordinates']['ury'] - $element['coordinates']['lly']); + $element['coordinates']['top'] = $dimension['h'] - $element['coordinates']['ury']; + $element['coordinates']['width'] = $element['coordinates']['urx'] - $element['coordinates']['llx']; + + return $element; + }, $visibleElements[$signer->getId()] ?? []), 'identifyMethods' => array_map(function (IdentifyMethod $identifyMethod) use ($signer): array { return [ 'method' => $identifyMethod->getIdentifierKey(), diff --git a/lib/Service/FileElementService.php b/lib/Service/FileElementService.php index 8e276824fc..6d71c85287 100644 --- a/lib/Service/FileElementService.php +++ b/lib/Service/FileElementService.php @@ -136,7 +136,7 @@ public function translateCoordinatesFromInternalNotation(array $properties, File $translated['left'] = $properties['coordinates']['llx']; $translated['height'] = abs($properties['coordinates']['ury'] - $properties['coordinates']['lly']); - $translated['top'] = $dimension->h - $properties['coordinates']['ury']; + $translated['top'] = $dimension['h'] - $properties['coordinates']['ury']; $translated['width'] = $properties['coordinates']['urx'] - $properties['coordinates']['llx']; return $translated; diff --git a/lib/Service/FileService.php b/lib/Service/FileService.php index 5867f4ff40..c3ba5d63a5 100644 --- a/lib/Service/FileService.php +++ b/lib/Service/FileService.php @@ -191,6 +191,7 @@ private function getSigners(): array { 'signRequestId' => $signer->getId(), 'description' => $signer->getDescription(), 'identifyMethods' => $this->identifyMethodService->getIdentifyMethodsFromSignRequestId($signer->getId()), + 'visibleElements' => $this->getVisibleElements(), 'request_sign_date' => (new \DateTime()) ->setTimestamp($signer->getCreatedAt()) ->format('Y-m-d H:i:s'), @@ -391,7 +392,6 @@ private function getFile(): array { if ($this->showSigners) { $return['signers'] = $this->getSigners(); } - $return['visibleElements'] = $this->getVisibleElements(); ksort($return); return $return; } diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml index 0e69cf47a7..0c7fde2668 100644 --- a/tests/psalm-baseline.xml +++ b/tests/psalm-baseline.xml @@ -55,6 +55,14 @@ callable(QueryBuilder): void + + + PostgreSQLPlatform + + + $qb->getConnection()->getDatabasePlatform() + + LoadSidebar