• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LibreSign / libresign / 20621495436

31 Dec 2025 02:59PM UTC coverage: 44.647%. First build
20621495436

Pull #6256

github

web-flow
Merge 4343635f1 into 27812ed76
Pull Request #6256: feat: add dashboard pending signatures widget

57 of 239 new or added lines in 16 files covered. (23.85%)

6618 of 14823 relevant lines covered (44.65%)

5.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.31
/lib/Service/EnvelopeService.php
1
<?php
2

3
declare(strict_types=1);
4
/**
5
 * SPDX-FileCopyrightText: 2025 LibreCode coop and contributors
6
 * SPDX-License-Identifier: AGPL-3.0-or-later
7
 */
8

9
namespace OCA\Libresign\Service;
10

11
use DateTime;
12
use OCA\Libresign\AppInfo\Application;
13
use OCA\Libresign\Db\File as FileEntity;
14
use OCA\Libresign\Db\FileMapper;
15
use OCA\Libresign\Enum\NodeType;
16
use OCA\Libresign\Exception\LibresignException;
17
use OCP\AppFramework\Db\DoesNotExistException;
18
use OCP\IAppConfig;
19
use OCP\IL10N;
20
use Sabre\DAV\UUIDUtil;
21

22
class EnvelopeService {
23
        public function __construct(
24
                protected FileMapper $fileMapper,
25
                protected IL10N $l10n,
26
                protected IAppConfig $appConfig,
27
                protected FolderService $folderService,
28
        ) {
29
        }
50✔
30

31
        public function isEnabled(): bool {
32
                return $this->appConfig->getValueBool(Application::APP_ID, 'envelope_enabled', true);
×
33
        }
34

35
        /**
36
         * @throws LibresignException
37
         */
38
        public function validateEnvelopeConstraints(int $fileCount): void {
39
                if (!$this->isEnabled()) {
×
40
                        throw new LibresignException($this->l10n->t('Envelope feature is disabled'));
×
41
                }
42

43
                $maxFiles = $this->getMaxFilesPerEnvelope();
×
44
                if ($fileCount > $maxFiles) {
×
45
                        throw new LibresignException(
×
46
                                $this->l10n->t('Maximum number of files per envelope (%s) exceeded', [$maxFiles])
×
47
                        );
×
48
                }
49
        }
50

51
        public function createEnvelope(string $name, string $userId, int $filesCount = 0): FileEntity {
52
                $this->folderService->setUserId($userId);
3✔
53

54
                $parentFolder = $this->folderService->getFolder();
3✔
55

56
                $uuid = UUIDUtil::getUUID();
3✔
57
                $folderName = $name . '_' . $uuid;
3✔
58
                $envelopeFolder = $parentFolder->newFolder($folderName);
3✔
59

60
                $envelope = new FileEntity();
3✔
61
                $envelope->setNodeId($envelopeFolder->getId());
3✔
62
                $envelope->setNodeTypeEnum(NodeType::ENVELOPE);
3✔
63
                $envelope->setName($name);
3✔
64
                $envelope->setUuid($uuid);
3✔
65
                $envelope->setCreatedAt(new DateTime());
3✔
66
                $envelope->setStatus(FileEntity::STATUS_DRAFT);
3✔
67

68
                $envelope->setMetadata(['filesCount' => $filesCount]);
3✔
69

70
                if ($userId) {
3✔
71
                        $envelope->setUserId($userId);
3✔
72
                }
73

74
                return $this->fileMapper->insert($envelope);
3✔
75
        }
76

77
        public function addFileToEnvelope(int $envelopeId, FileEntity $file): FileEntity {
78
                $envelope = $this->fileMapper->getById($envelopeId);
5✔
79

80
                if (!$envelope->isEnvelope()) {
5✔
81
                        throw new LibresignException($this->l10n->t('The specified ID is not an envelope'));
1✔
82
                }
83

84
                if ($envelope->getStatus() > FileEntity::STATUS_DRAFT) {
4✔
85
                        throw new LibresignException($this->l10n->t('Cannot add files to an envelope that is already in signing process'));
1✔
86
                }
87

88
                $maxFiles = $this->getMaxFilesPerEnvelope();
3✔
89
                $currentCount = $this->fileMapper->countChildrenFiles($envelopeId);
3✔
90
                if ($currentCount >= $maxFiles) {
3✔
91
                        throw new LibresignException(
1✔
92
                                $this->l10n->t('Maximum number of files per envelope (%s) exceeded', [$maxFiles])
1✔
93
                        );
1✔
94
                }
95

96
                $file->setParentFileId($envelopeId);
2✔
97
                $file->setNodeTypeEnum(NodeType::FILE);
2✔
98

99
                return $this->fileMapper->update($file);
2✔
100
        }
101

102
        public function getEnvelopeByFileId(int $fileId): ?FileEntity {
103
                try {
104
                        return $this->fileMapper->getParentEnvelope($fileId);
2✔
105
                } catch (DoesNotExistException) {
1✔
106
                        return null;
1✔
107
                }
108
        }
109

110
        public function getEnvelopeFolder(FileEntity $envelope): \OCP\Files\Folder {
NEW
111
                $userId = $envelope->getUserId();
×
NEW
112
                if (!$userId) {
×
NEW
113
                        throw new LibresignException('Envelope does not have a user');
×
114
                }
115

NEW
116
                $this->folderService->setUserId($userId);
×
NEW
117
                $userFolder = $this->folderService->getFolder();
×
118

NEW
119
                $envelopeFolderNode = $userFolder->getFirstNodeById($envelope->getNodeId());
×
NEW
120
                if (!$envelopeFolderNode instanceof \OCP\Files\Folder) {
×
NEW
121
                        throw new LibresignException('Envelope folder not found');
×
122
                }
123

NEW
124
                return $envelopeFolderNode;
×
125
        }
126

127
        private function getMaxFilesPerEnvelope(): int {
128
                return $this->appConfig->getValueInt(Application::APP_ID, 'envelope_max_files', 50);
3✔
129
        }
130
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc