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

LibreSign / libresign / 19875332299

02 Dec 2025 10:16PM UTC coverage: 41.686%. First build
19875332299

Pull #4464

github

web-flow
Merge b1d57ae77 into da0973853
Pull Request #4464: refactor: attach document

113 of 256 new or added lines in 15 files covered. (44.14%)

5122 of 12287 relevant lines covered (41.69%)

4.18 hits per line

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

63.7
/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 OCP\AppFramework\Db\DoesNotExistException;
12
use OCP\AppFramework\Db\QBMapper;
13
use OCP\Comments\ICommentsManager;
14
use OCP\DB\QueryBuilder\IQueryBuilder;
15
use OCP\IDBConnection;
16
use OCP\IL10N;
17

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

170
        /**
171
         * @return File[]
172
         */
173
        public function getFilesOfAccount(string $userId): array {
174
                $qb = $this->db->getQueryBuilder();
×
175

176
                $qb->select('lf.*')
×
177
                        ->from($this->getTableName(), 'lf')
×
NEW
178
                        ->join('lf', 'libresign_id_docs', 'lid', 'lid.file_id = lf.id')
×
179
                        ->where(
×
NEW
180
                                $qb->expr()->eq('lid.user_id', $qb->createNamedParameter($userId))
×
181
                        );
×
182

183
                $cursor = $qb->executeQuery();
×
184
                $return = [];
×
185
                while ($row = $cursor->fetch()) {
×
186
                        /** @var File */
187
                        $file = $this->mapRowToEntity($row);
×
188
                        $this->file[] = $file;
×
189
                        $return[] = $file;
×
190
                }
191
                return $return;
×
192
        }
193

194
        public function getFileType(int $id): string {
195
                $fullOuterJoin = $this->db->getQueryBuilder();
36✔
196
                $fullOuterJoin->select($fullOuterJoin->expr()->literal(1));
36✔
197

198
                $qb = $this->db->getQueryBuilder();
36✔
199
                $qb
36✔
200
                        ->selectAlias('f.id', 'file')
36✔
201
                        ->selectAlias('sf.signed_node_id', 'signed_file')
36✔
202
                        ->selectAlias('ue.id', 'user_element')
36✔
203
                        ->selectAlias('fe.id', 'file_element')
36✔
204
                        ->from($qb->createFunction('(' . $fullOuterJoin->getSQL() . ')'), 'foj')
36✔
205
                        ->leftJoin('foj', 'libresign_file', 'f', $qb->expr()->eq('f.node_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
36✔
206
                        ->leftJoin('foj', 'libresign_file', 'sf', $qb->expr()->eq('sf.signed_node_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
36✔
207
                        ->leftJoin('foj', 'libresign_user_element', 'ue', $qb->expr()->eq('ue.file_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
36✔
208
                        ->leftJoin('foj', 'libresign_file_element', 'fe', $qb->expr()->eq('fe.file_id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
36✔
209
                $cursor = $qb->executeQuery();
36✔
210
                $row = $cursor->fetch();
36✔
211
                if ($row) {
36✔
212
                        foreach ($row as $key => $value) {
36✔
213
                                if ($value) {
36✔
214
                                        return $key;
1✔
215
                                }
216
                        }
217
                }
218
                return 'not_libresign_file';
36✔
219
        }
220

221
        public function getTextOfStatus(int $status): ?string {
222
                return match ($status) {
×
223
                        // TRANSLATORS Name of the status when document is not a LibreSign file
224
                        File::STATUS_NOT_LIBRESIGN_FILE => $this->l->t('not LibreSign file'),
4✔
225
                        // TRANSLATORS Name of the status that the document is still as a draft
226
                        File::STATUS_DRAFT => $this->l->t('draft'),
4✔
227
                        // TRANSLATORS Name of the status that the document can be signed
228
                        File::STATUS_ABLE_TO_SIGN => $this->l->t('available for signature'),
4✔
229
                        // TRANSLATORS Name of the status when the document has already been partially signed
230
                        File::STATUS_PARTIAL_SIGNED => $this->l->t('partially signed'),
×
231
                        // TRANSLATORS Name of the status when the document has been completely signed
232
                        File::STATUS_SIGNED => $this->l->t('signed'),
×
233
                        // TRANSLATORS Name of the status when the document was deleted
234
                        File::STATUS_DELETED => $this->l->t('deleted'),
×
235
                        default => '',
4✔
236
                };
×
237
        }
238

239
        public function neutralizeDeletedUser(string $userId, string $displayName): void {
240
                $update = $this->db->getQueryBuilder();
×
241
                $qb = $this->db->getQueryBuilder();
×
242
                $qb->select('f.id')
×
243
                        ->addSelect('f.metadata')
×
244
                        ->from($this->getTableName(), 'f')
×
245
                        ->where($qb->expr()->eq('f.user_id', $qb->createNamedParameter($userId)));
×
246
                $cursor = $qb->executeQuery();
×
247
                while ($row = $cursor->fetch()) {
×
248
                        $row['metadata'] = json_decode((string)$row['metadata'], true);
×
249
                        $row['metadata']['deleted_account'] = [
×
250
                                'account' => $userId,
×
251
                                'display_name' => $displayName,
×
252
                        ];
×
253
                        $update->update($this->getTableName())
×
254
                                ->set('user_id', $update->createNamedParameter(ICommentsManager::DELETED_USER))
×
255
                                ->set('metadata', $update->createNamedParameter($row['metadata'], IQueryBuilder::PARAM_JSON))
×
256
                                ->where($update->expr()->eq('id', $update->createNamedParameter($row['id'])));
×
257
                        $update->executeStatement();
×
258
                }
259
        }
260
}
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