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

LibreSign / libresign / 20395868261

20 Dec 2025 02:42PM UTC coverage: 43.246%. First build
20395868261

Pull #6242

github

web-flow
Merge b81fd641a into fae2922ee
Pull Request #6242: feat: envelope support

162 of 510 new or added lines in 13 files covered. (31.76%)

6064 of 14022 relevant lines covered (43.25%)

5.07 hits per line

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

48.57
/lib/Db/FileMapper.php
1
<?php
2

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

9
namespace OCA\Libresign\Db;
10

11
use OCA\Libresign\Enum\FileStatus;
12
use OCA\Libresign\Enum\NodeType;
13
use OCP\AppFramework\Db\DoesNotExistException;
14
use OCP\AppFramework\Db\QBMapper;
15
use OCP\Comments\ICommentsManager;
16
use OCP\DB\QueryBuilder\IQueryBuilder;
17
use OCP\IDBConnection;
18
use OCP\IL10N;
19

20
/**
21
 * Class FileMapper
22
 *
23
 * @package OCA\Libresign\DB
24
 * @template-extends QBMapper<File>
25
 */
26
class FileMapper extends QBMapper {
27
        /** @var File[] */
28
        private $file = [];
29

30
        public function __construct(
31
                IDBConnection $db,
32
                private IL10N $l,
33
        ) {
34
                parent::__construct($db, 'libresign_file');
47✔
35
        }
36

37
        /**
38
         * Return LibreSign file by ID
39
         *
40
         * @throws DoesNotExistException
41
         * @return File Row of table libresign_file
42
         */
43
        public function getById(int $id): File {
44
                foreach ($this->file as $file) {
14✔
45
                        if ($file->getId() === $id) {
14✔
46
                                return $file;
14✔
47
                        }
48
                }
49
                $qb = $this->db->getQueryBuilder();
13✔
50

51
                $qb->select('*')
13✔
52
                        ->from($this->getTableName())
13✔
53
                        ->where(
13✔
54
                                $qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT))
13✔
55
                        );
13✔
56

57
                /** @var File */
58
                $file = $this->findEntity($qb);
13✔
59
                $this->file[] = $file;
13✔
60
                return $file;
13✔
61
        }
62

63
        /**
64
         * Return LibreSign file by signed hash
65
         *
66
         * @throws DoesNotExistException
67
         * @return File Row of table libresign_file
68
         */
69
        public function getBySignedHash(string $hash): File {
70
                foreach ($this->file as $file) {
3✔
71
                        if ($file->getSignedHash() === $hash) {
×
72
                                return $file;
×
73
                        }
74
                }
75
                $qb = $this->db->getQueryBuilder();
3✔
76

77
                $qb->select('f.*')
3✔
78
                        ->from($this->getTableName(), 'f')
3✔
79
                        ->join('f', 'libresign_sign_request', 'sr', $qb->expr()->eq('f.id', 'sr.file_id'))
3✔
80
                        ->where(
3✔
81
                                $qb->expr()->orX(
3✔
82
                                        $qb->expr()->eq('f.signed_hash', $qb->createNamedParameter($hash)),
3✔
83
                                        $qb->expr()->eq('sr.signed_hash', $qb->createNamedParameter($hash))
3✔
84
                                )
3✔
85
                        )
3✔
86
                        ->setMaxResults(1);
3✔
87

88
                /** @var File */
89
                $file = $this->findEntity($qb);
3✔
90
                $this->file[] = $file;
×
91
                return $file;
×
92
        }
93

94
        /**
95
         * Return LibreSign file by file UUID
96
         */
97
        public function getByUuid(?string $uuid = null): File {
98
                if (is_null($uuid) && !empty($this->file)) {
7✔
99
                        return current($this->file);
×
100
                }
101
                foreach ($this->file as $file) {
7✔
102
                        if ($file->getUuid() === $uuid) {
6✔
103
                                return $file;
6✔
104
                        }
105
                }
106
                $qb = $this->db->getQueryBuilder();
3✔
107

108
                $qb->select('*')
3✔
109
                        ->from($this->getTableName())
3✔
110
                        ->where(
3✔
111
                                $qb->expr()->eq('uuid', $qb->createNamedParameter($uuid))
3✔
112
                        );
3✔
113

114
                /** @var File */
115
                $file = $this->findEntity($qb);
3✔
116
                $this->file[] = $file;
2✔
117
                return $file;
2✔
118
        }
119

120
        /**
121
         * Return LibreSign file by signer UUID
122
         */
123
        public function getBySignerUuid(?string $uuid = null): File {
124
                if (is_null($uuid) && !empty($this->file)) {
1✔
125
                        return current($this->file);
×
126
                }
127
                $qb = $this->db->getQueryBuilder();
1✔
128

129
                $qb->select('f.*')
1✔
130
                        ->from($this->getTableName(), 'f')
1✔
131
                        ->join('f', 'libresign_sign_request', 'sr', $qb->expr()->eq('f.id', 'sr.file_id'))
1✔
132
                        ->where(
1✔
133
                                $qb->expr()->eq('sr.uuid', $qb->createNamedParameter($uuid))
1✔
134
                        );
1✔
135

136
                /** @var File */
137
                $file = $this->findEntity($qb);
1✔
138
                $this->file[] = $file;
×
139
                return $file;
×
140
        }
141

142
        /**
143
         * Return LibreSign file by nodeId
144
         */
145
        public function getByFileId(?int $nodeId = null): File {
146
                $exists = array_filter($this->file, fn ($f) => $f->getNodeId() === $nodeId || $f->getSignedNodeId() === $nodeId);
12✔
147
                if (!empty($exists)) {
12✔
148
                        return current($exists);
8✔
149
                }
150
                foreach ($this->file as $file) {
4✔
151
                        if ($file->getNodeId() === $nodeId) {
×
152
                                return $file;
×
153
                        }
154
                }
155
                $qb = $this->db->getQueryBuilder();
4✔
156

157
                $qb->select('*')
4✔
158
                        ->from($this->getTableName())
4✔
159
                        ->where(
4✔
160
                                $qb->expr()->orX(
4✔
161
                                        $qb->expr()->eq('node_id', $qb->createNamedParameter($nodeId, IQueryBuilder::PARAM_INT)),
4✔
162
                                        $qb->expr()->eq('signed_node_id', $qb->createNamedParameter($nodeId, IQueryBuilder::PARAM_INT))
4✔
163
                                )
4✔
164
                        );
4✔
165

166
                /** @var File */
167
                $file = $this->findEntity($qb);
4✔
168
                $this->file[] = $file;
×
169
                return $file;
×
170
        }
171

172
        public function fileIdExists(int $nodeId): bool {
173
                $exists = array_filter($this->file, fn ($f) => $f->getNodeId() === $nodeId || $f->getSignedNodeId() === $nodeId);
×
174
                if (!empty($exists)) {
×
175
                        return true;
×
176
                }
177

178
                $qb = $this->db->getQueryBuilder();
×
179

180
                $qb->select('*')
×
181
                        ->from($this->getTableName())
×
182
                        ->where(
×
183
                                $qb->expr()->orX(
×
184
                                        $qb->expr()->eq('node_id', $qb->createNamedParameter($nodeId, IQueryBuilder::PARAM_INT)),
×
185
                                        $qb->expr()->eq('signed_node_id', $qb->createNamedParameter($nodeId, IQueryBuilder::PARAM_INT))
×
186
                                )
×
187
                        );
×
188

189
                $files = $this->findEntities($qb);
×
190
                if (!empty($files)) {
×
191
                        foreach ($files as $file) {
×
192
                                $this->file[] = $file;
×
193
                        }
194
                        return true;
×
195
                }
196
                return false;
×
197
        }
198

199
        /**
200
         * @return File[]
201
         */
202
        public function getFilesOfAccount(string $userId): array {
203
                $qb = $this->db->getQueryBuilder();
×
204

205
                $qb->select('lf.*')
×
206
                        ->from($this->getTableName(), 'lf')
×
207
                        ->join('lf', 'libresign_id_docs', 'lid', 'lid.file_id = lf.id')
×
208
                        ->where(
×
209
                                $qb->expr()->eq('lid.user_id', $qb->createNamedParameter($userId))
×
210
                        );
×
211

212
                $cursor = $qb->executeQuery();
×
213
                $return = [];
×
214
                while ($row = $cursor->fetch()) {
×
215
                        /** @var File */
216
                        $file = $this->mapRowToEntity($row);
×
217
                        $this->file[] = $file;
×
218
                        $return[] = $file;
×
219
                }
220
                return $return;
×
221
        }
222

223
        public function getFileType(int $id): string {
224
                $fullOuterJoin = $this->db->getQueryBuilder();
36✔
225
                $fullOuterJoin->select($fullOuterJoin->expr()->literal(1));
36✔
226

227
                $qb = $this->db->getQueryBuilder();
36✔
228
                $qb
36✔
229
                        ->selectAlias('f.id', 'file')
36✔
230
                        ->selectAlias('sf.signed_node_id', 'signed_file')
36✔
231
                        ->selectAlias('ue.id', 'user_element')
36✔
232
                        ->selectAlias('fe.id', 'file_element')
36✔
233
                        ->from($qb->createFunction('(' . $fullOuterJoin->getSQL() . ')'), 'foj')
36✔
234
                        ->leftJoin('foj', 'libresign_file', 'f', $qb->expr()->eq('f.node_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
36✔
235
                        ->leftJoin('foj', 'libresign_file', 'sf', $qb->expr()->eq('sf.signed_node_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
36✔
236
                        ->leftJoin('foj', 'libresign_user_element', 'ue', $qb->expr()->eq('ue.file_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
36✔
237
                        ->leftJoin('foj', 'libresign_file_element', 'fe', $qb->expr()->eq('fe.file_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
36✔
238
                $cursor = $qb->executeQuery();
36✔
239
                $row = $cursor->fetch();
36✔
240
                if ($row) {
36✔
241
                        foreach ($row as $key => $value) {
36✔
242
                                if ($value) {
36✔
243
                                        return $key;
1✔
244
                                }
245
                        }
246
                }
247
                return 'not_libresign_file';
36✔
248
        }
249

250
        public function getTextOfStatus(int|FileStatus $status): string {
251
                if (is_int($status)) {
5✔
252
                        $status = FileStatus::from($status);
5✔
253
                }
254
                return $status->getLabel($this->l);
5✔
255
        }
256

257
        public function neutralizeDeletedUser(string $userId, string $displayName): void {
258
                $update = $this->db->getQueryBuilder();
×
259
                $qb = $this->db->getQueryBuilder();
×
260
                $qb->select('f.id')
×
261
                        ->addSelect('f.metadata')
×
262
                        ->from($this->getTableName(), 'f')
×
263
                        ->where($qb->expr()->eq('f.user_id', $qb->createNamedParameter($userId)));
×
264
                $cursor = $qb->executeQuery();
×
265
                while ($row = $cursor->fetch()) {
×
266
                        $row['metadata'] = json_decode((string)$row['metadata'], true);
×
267
                        $row['metadata']['deleted_account'] = [
×
268
                                'account' => $userId,
×
269
                                'display_name' => $displayName,
×
270
                        ];
×
271
                        $update->update($this->getTableName())
×
272
                                ->set('user_id', $update->createNamedParameter(ICommentsManager::DELETED_USER))
×
273
                                ->set('metadata', $update->createNamedParameter($row['metadata'], IQueryBuilder::PARAM_JSON))
×
274
                                ->where($update->expr()->eq('id', $update->createNamedParameter($row['id'])));
×
275
                        $update->executeStatement();
×
276
                }
277
        }
278

279
        /**
280
         * @return File[]
281
         */
282
        public function getChildrenFiles(int $parentId): array {
NEW
283
                $qb = $this->db->getQueryBuilder();
×
284

NEW
285
                $qb->select('*')
×
NEW
286
                        ->from($this->getTableName())
×
NEW
287
                        ->where(
×
NEW
288
                                $qb->expr()->eq('parent_file_id', $qb->createNamedParameter($parentId, IQueryBuilder::PARAM_INT))
×
NEW
289
                        )
×
NEW
290
                        ->andWhere(
×
NEW
291
                                $qb->expr()->eq('node_type', $qb->createNamedParameter(NodeType::FILE->value))
×
NEW
292
                        )
×
NEW
293
                        ->orderBy('id', 'ASC');
×
294

NEW
295
                return $this->findEntities($qb);
×
296
        }
297

298
        public function getParentEnvelope(int $fileId): ?File {
NEW
299
                $file = $this->getById($fileId);
×
300

NEW
301
                if (!$file->hasParent()) {
×
NEW
302
                        return null;
×
303
                }
304

NEW
305
                return $this->getById($file->getParentFileId());
×
306
        }
307

308
        public function countChildrenFiles(int $envelopeId): int {
NEW
309
                $qb = $this->db->getQueryBuilder();
×
310

NEW
311
                $qb->select($qb->func()->count('*', 'count'))
×
NEW
312
                        ->from($this->getTableName())
×
NEW
313
                        ->where(
×
NEW
314
                                $qb->expr()->eq('parent_file_id', $qb->createNamedParameter($envelopeId, IQueryBuilder::PARAM_INT))
×
NEW
315
                        )
×
NEW
316
                        ->andWhere(
×
NEW
317
                                $qb->expr()->eq('node_type', $qb->createNamedParameter(NodeType::FILE->value))
×
NEW
318
                        );
×
319

NEW
320
                $cursor = $qb->executeQuery();
×
NEW
321
                $row = $cursor->fetch();
×
NEW
322
                $cursor->closeCursor();
×
323

NEW
324
                return $row ? (int)$row['count'] : 0;
×
325
        }
326
}
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

© 2025 Coveralls, Inc