Passed
Push — devel-3.0 ( 543c48...5b8639 )
by Rubén
03:28
created

AccountRepository::deleteByIdBatch()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 13
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * sysPass
4
 *
5
 * @author    nuxsmin
6
 * @link      https://syspass.org
7
 * @copyright 2012-2018, Rubén Domínguez nuxsmin@$syspass.org
8
 *
9
 * This file is part of sysPass.
10
 *
11
 * sysPass is free software: you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation, either version 3 of the License, or
14
 * (at your option) any later version.
15
 *
16
 * sysPass is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 *  along with sysPass.  If not, see <http://www.gnu.org/licenses/>.
23
 */
24
25
namespace SP\Repositories\Account;
26
27
use SP\Core\Exceptions\ConstraintException;
28
use SP\Core\Exceptions\QueryException;
29
use SP\Core\Exceptions\SPException;
30
use SP\DataModel\AccountData;
31
use SP\DataModel\AccountExtData;
32
use SP\DataModel\AccountPassData;
33
use SP\DataModel\AccountSearchVData;
34
use SP\DataModel\AccountVData;
35
use SP\DataModel\ItemData;
36
use SP\DataModel\ItemSearchData;
37
use SP\Mvc\Model\QueryAssignment;
38
use SP\Mvc\Model\QueryCondition;
39
use SP\Mvc\Model\QueryJoin;
40
use SP\Repositories\Repository;
41
use SP\Repositories\RepositoryItemInterface;
42
use SP\Repositories\RepositoryItemTrait;
43
use SP\Services\Account\AccountPasswordRequest;
44
use SP\Services\Account\AccountRequest;
45
use SP\Services\Account\AccountSearchFilter;
46
use SP\Storage\Database\QueryData;
47
use SP\Storage\Database\QueryResult;
48
49
/**
50
 * Class AccountRepository
51
 *
52
 * @package Services
53
 */
54
final class AccountRepository extends Repository implements RepositoryItemInterface
55
{
56
    use RepositoryItemTrait;
57
58
    /**
59
     * Devolver el número total de cuentas
60
     *
61
     * @return \stdClass
62
     * @throws QueryException
63
     * @throws ConstraintException
64
     */
65
    public function getTotalNumAccounts()
66
    {
67
        $query = /** @lang SQL */
68
            'SELECT SUM(n) AS num FROM 
69
            (SELECT COUNT(*) AS n FROM Account UNION SELECT COUNT(*) AS n FROM AccountHistory) a';
70
71
        $queryData = new QueryData();
72
        $queryData->setQuery($query);
73
74
        return $this->db->doSelect($queryData)->getData();
75
    }
76
77
    /**
78
     * @param                $id
79
     * @param QueryCondition $queryCondition
80
     *
81
     * @return QueryResult
82
     * @throws ConstraintException
83
     * @throws QueryException
84
     */
85
    public function getPasswordForId($id, QueryCondition $queryCondition)
86
    {
87
        $queryCondition->addFilter('Account.id = ?', [$id]);
88
89
        $queryData = new QueryData();
90
        $queryData->setMapClassName(AccountPassData::class);
91
        $queryData->setLimit(1);
92
        $queryData->setSelect('Account.id, Account.name, Account.login, Account.pass, Account.key, Account.parentId');
93
        $queryData->setFrom('Account');
94
        $queryData->setWhere($queryCondition->getFilters());
95
        $queryData->setParams($queryCondition->getParams());
96
97
        return $this->db->doSelect($queryData);
98
    }
99
100
    /**
101
     * @param QueryCondition $queryCondition
102
     *
103
     * @return QueryResult
104
     * @throws ConstraintException
105
     * @throws QueryException
106
     */
107
    public function getPasswordHistoryForId(QueryCondition $queryCondition)
108
    {
109
        $query = /** @lang SQL */
110
            'SELECT 
111
              AccountHistory.id, 
112
              AccountHistory.name,
113
              AccountHistory.login,
114
              AccountHistory.pass,
115
              AccountHistory.key,
116
              AccountHistory.parentId,
117
              AccountHistory.mPassHash 
118
            FROM AccountHistory 
119
            WHERE ' . $queryCondition->getFilters();
120
121
        $queryData = new QueryData();
122
        $queryData->setMapClassName(AccountPassData::class);
123
        $queryData->setQuery($query);
124
        $queryData->setParams($queryCondition->getParams());
125
126
        return $this->db->doSelect($queryData);
127
    }
128
129
    /**
130
     * Incrementa el contador de vista de clave de una cuenta en la BBDD
131
     *
132
     * @param int $id
133
     *
134
     * @return bool
135
     * @throws ConstraintException
136
     * @throws QueryException
137
     */
138
    public function incrementDecryptCounter($id)
139
    {
140
        $query = /** @lang SQL */
141
            'UPDATE Account SET countDecrypt = (countDecrypt + 1) WHERE id = ? LIMIT 1';
142
143
        $queryData = new QueryData();
144
        $queryData->setQuery($query);
145
        $queryData->addParam($id);
146
147
        return $this->db->doQuery($queryData)->getAffectedNumRows() === 1;
148
    }
149
150
    /**
151
     * Crea una nueva cuenta en la BBDD
152
     *
153
     * @param AccountRequest $itemData
154
     *
155
     * @return int
156
     * @throws ConstraintException
157
     * @throws QueryException
158
     */
159
    public function create($itemData)
160
    {
161
        $query = /** @lang SQL */
162
            'INSERT INTO Account SET 
163
            clientId = ?,
164
            categoryId = ?,
165
            `name` = ?,
166
            login = ?,
167
            url = ?,
168
            pass = ?,
169
            `key` = ?,
170
            notes = ?,
171
            dateAdd = NOW(),
172
            userId = ?,
173
            userGroupId = ?,
174
            userEditId = ?,
175
            isPrivate = ?,
176
            isPrivateGroup = ?,
177
            passDate = UNIX_TIMESTAMP(),
178
            passDateChange = ?,
179
            parentId = ?';
180
181
        $queryData = new QueryData();
182
        $queryData->setQuery($query);
183
        $queryData->setParams([
184
            $itemData->clientId,
185
            $itemData->categoryId,
186
            $itemData->name,
187
            $itemData->login,
188
            $itemData->url,
189
            $itemData->pass,
190
            $itemData->key,
191
            $itemData->notes,
192
            $itemData->userId,
193
            $itemData->userGroupId,
194
            $itemData->userId,
195
            $itemData->isPrivate,
196
            $itemData->isPrivateGroup,
197
            $itemData->passDateChange,
198
            $itemData->parentId
199
        ]);
200
        $queryData->setOnErrorMessage(__u('Error al crear la cuenta'));
201
202
        return $this->db->doQuery($queryData)->getLastId();
203
    }
204
205
    /**
206
     * Actualiza la clave de una cuenta en la BBDD.
207
     *
208
     * @param AccountRequest $accountRequest
209
     *
210
     * @return int
211
     * @throws ConstraintException
212
     * @throws QueryException
213
     */
214
    public function editPassword(AccountRequest $accountRequest)
215
    {
216
        $query = /** @lang SQL */
217
            'UPDATE Account SET 
218
            pass = ?,
219
            `key` = ?,
220
            userEditId = ?,
221
            dateEdit = NOW(),
222
            passDate = UNIX_TIMESTAMP(),
223
            passDateChange = ?
224
            WHERE id = ?';
225
226
        $queryData = new QueryData();
227
        $queryData->setQuery($query);
228
        $queryData->setParams([
229
            $accountRequest->pass,
230
            $accountRequest->key,
231
            $accountRequest->userEditId,
232
            $accountRequest->passDateChange,
233
            $accountRequest->id
234
        ]);
235
        $queryData->setOnErrorMessage(__u('Error al actualizar la clave'));
236
237
        return $this->db->doQuery($queryData)->getAffectedNumRows();
238
    }
239
240
    /**
241
     * Actualiza la clave de una cuenta en la BBDD.
242
     *
243
     * @param AccountPasswordRequest $request
244
     *
245
     * @return bool
246
     * @throws ConstraintException
247
     * @throws QueryException
248
     */
249
    public function updatePassword(AccountPasswordRequest $request)
250
    {
251
        $query = /** @lang SQL */
252
            'UPDATE Account SET 
253
            pass = ?,
254
            `key` = ?
255
            WHERE id = ?';
256
257
        $queryData = new QueryData();
258
        $queryData->setQuery($query);
259
        $queryData->setParams([$request->pass, $request->key, $request->id]);
260
        $queryData->setOnErrorMessage(__u('Error al actualizar la clave'));
261
262
        return $this->db->doQuery($queryData)->getAffectedNumRows() === 1;
263
    }
264
265
    /**
266
     * Restaurar una cuenta desde el histórico.
267
     *
268
     * @param int $historyId El Id del registro en el histórico
269
     * @param int $userId    User's Id
270
     *
271
     * @return bool
272
     * @throws ConstraintException
273
     * @throws QueryException
274
     */
275
    public function editRestore($historyId, $userId)
276
    {
277
        $query = /** @lang SQL */
278
            'UPDATE Account dst, 
279
            (SELECT * FROM AccountHistory AH WHERE AH.id = ?) src SET 
280
            dst.clientId = src.clientId,
281
            dst.categoryId = src.categoryId,
282
            dst.name = src.name,
283
            dst.login = src.login,
284
            dst.url = src.url,
285
            dst.notes = src.notes,
286
            dst.userGroupId = src.userGroupId,
287
            dst.userEditId = ?,
288
            dst.dateEdit = NOW(),
289
            dst.pass = src.pass,
290
            dst.key = src.key,
291
            dst.passDate = src.passDate,
292
            dst.passDateChange = src.passDateChange, 
293
            dst.parentId = src.parentId, 
294
            dst.isPrivate = src.isPrivate,
295
            dst.isPrivateGroup = src.isPrivateGroup
296
            WHERE dst.id = src.accountId';
297
298
        $queryData = new QueryData();
299
        $queryData->setQuery($query);
300
        $queryData->setParams([$historyId, $userId]);
301
        $queryData->setOnErrorMessage(__u('Error al restaurar cuenta'));
302
303
        return $this->db->doQuery($queryData)->getAffectedNumRows() === 1;
304
    }
305
306
    /**
307
     * Elimina los datos de una cuenta en la BBDD.
308
     *
309
     * @param int $id
310
     *
311
     * @return int EL número de cuentas eliminadas
312
     * @throws ConstraintException
313
     * @throws QueryException
314
     */
315
    public function delete($id)
316
    {
317
        $queryData = new QueryData();
318
319
        $queryData->setQuery('DELETE FROM Account WHERE id = ? LIMIT 1');
320
        $queryData->addParam($id);
321
        $queryData->setOnErrorMessage(__u('Error al eliminar la cuenta'));
322
323
        return $this->db->doQuery($queryData)->getAffectedNumRows();
324
    }
325
326
    /**
327
     * Updates an item
328
     *
329
     * @param \SP\Services\Account\AccountRequest $itemData
330
     *
331
     * @return mixed
332
     * @throws SPException
333
     */
334
    public function update($itemData)
335
    {
336
        $queryAssignment = new QueryAssignment();
337
338
        $queryAssignment->setFields([
339
            'clientId',
340
            'categoryId',
341
            'name',
342
            'login',
343
            'url',
344
            'notes',
345
            'userEditId',
346
            'dateEdit = NOW()',
347
            'passDateChange',
348
            'isPrivate',
349
            'isPrivateGroup',
350
            'parentId'
351
        ], [
352
            $itemData->clientId,
353
            $itemData->categoryId,
354
            $itemData->name,
355
            $itemData->login,
356
            $itemData->url,
357
            $itemData->notes,
358
            $itemData->userEditId,
359
            $itemData->passDateChange,
360
            $itemData->isPrivate,
361
            $itemData->isPrivateGroup,
362
            $itemData->parentId
363
        ]);
364
365
366
        $queryData = new QueryData();
367
368
        if ($itemData->changeUserGroup) {
369
            $queryAssignment->addField('userGroupId', $itemData->userGroupId);
370
        }
371
372
        if ($itemData->changeOwner) {
373
            $queryAssignment->addField('userId', $itemData->userId);
374
        }
375
376
        $query = /** @lang SQL */
377
            'UPDATE Account SET ' . $queryAssignment->getAssignments() . ' WHERE id = ?';
378
379
        $queryData->setQuery($query);
380
        $queryData->setParams($queryAssignment->getValues());
381
        $queryData->addParam($itemData->id);
382
        $queryData->setOnErrorMessage(__u('Error al modificar la cuenta'));
383
384
        return $this->db->doQuery($queryData)->getAffectedNumRows();
385
    }
386
387
    /**
388
     * Updates an item for bulk action
389
     *
390
     * @param \SP\Services\Account\AccountRequest $itemData
391
     *
392
     * @return mixed
393
     * @throws SPException
394
     */
395
    public function updateBulk($itemData)
396
    {
397
        $queryAssignment = new QueryAssignment();
398
399
        $queryAssignment->setFields([
400
            'userEditId',
401
            'dateEdit = NOW()'
402
        ], [
403
            $itemData->userEditId,
404
        ]);
405
406
        $queryData = new QueryData();
407
408
        $optional = ['clientId', 'categoryId', 'userId', 'userGroupId', 'passDateChange'];
409
410
        $optionalCount = 0;
411
412
        foreach ($optional as $field) {
413
            if (isset($itemData->{$field}) && !empty($itemData->{$field})) {
414
                $queryAssignment->addField($field, $itemData->{$field});
415
                $optionalCount++;
416
            } else {
417
                logger(sprintf('Field \'%s\' not found in $itemData', $field), 'ERROR');
418
            }
419
        }
420
421
        if ($optionalCount === 0) {
422
            return 0;
423
        }
424
425
        $query = /** @lang SQL */
426
            'UPDATE Account SET ' . $queryAssignment->getAssignments() . ' WHERE id = ?';
427
428
        $queryData->setQuery($query);
429
        $queryData->setParams($queryAssignment->getValues());
430
        $queryData->addParam($itemData->id);
431
        $queryData->setOnErrorMessage(__u('Error al modificar la cuenta'));
432
433
        return $this->db->doQuery($queryData)->getAffectedNumRows();
434
    }
435
436
    /**
437
     * Returns the item for given id
438
     *
439
     * @param int $id
440
     *
441
     * @return QueryResult
442
     * @throws QueryException
443
     * @throws ConstraintException
444
     */
445
    public function getById($id)
446
    {
447
        $queryData = new QueryData();
448
        $queryData->setQuery('SELECT * FROM account_data_v WHERE id = ? LIMIT 1');
449
        $queryData->setMapClassName(AccountVData::class);
450
        $queryData->addParam($id);
451
        $queryData->setOnErrorMessage(__u('No se pudieron obtener los datos de la cuenta'));
452
453
        return $this->db->doSelect($queryData);
454
    }
455
456
    /**
457
     * Returns all the items
458
     *
459
     * @return QueryResult
460
     * @throws ConstraintException
461
     * @throws QueryException
462
     */
463
    public function getAll()
464
    {
465
        $queryData = new QueryData();
466
        $queryData->setMapClassName(AccountData::class);
467
        $queryData->setQuery('SELECT * FROM Account ORDER BY id');
468
469
        return $this->db->doSelect($queryData);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->db->doSelect($queryData) returns the type SP\Storage\Database\QueryResult which is incompatible with the return type mandated by SP\Repositories\RepositoryItemInterface::getAll() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
470
    }
471
472
    /**
473
     * Returns all the items for given ids
474
     *
475
     * @param array $ids
476
     */
477
    public function getByIdBatch(array $ids)
478
    {
479
        throw new \RuntimeException('Not implemented');
480
    }
481
482
    /**
483
     * Deletes all the items for given ids
484
     *
485
     * @param array $ids
486
     *
487
     * @return int
488
     * @throws ConstraintException
489
     * @throws QueryException
490
     */
491
    public function deleteByIdBatch(array $ids)
492
    {
493
        if (empty($ids)) {
494
            return 0;
0 ignored issues
show
Bug Best Practice introduced by
The expression return 0 returns the type integer which is incompatible with the return type mandated by SP\Repositories\Reposito...face::deleteByIdBatch() of SP\Repositories\RepositoryItemInterface.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
495
        }
496
497
        $queryData = new QueryData();
498
499
        $queryData->setQuery('DELETE FROM Account WHERE id IN (' . $this->getParamsFromArray($ids) . ')');
500
        $queryData->setParams($ids);
501
        $queryData->setOnErrorMessage(__u('Error al eliminar las cuentas'));
502
503
        return $this->db->doQuery($queryData)->getAffectedNumRows();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->db->doQuer...)->getAffectedNumRows() returns the type integer which is incompatible with the return type mandated by SP\Repositories\Reposito...face::deleteByIdBatch() of SP\Repositories\RepositoryItemInterface.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
504
    }
505
506
    /**
507
     * Checks whether the item is in use or not
508
     *
509
     * @param $id int
510
     */
511
    public function checkInUse($id)
512
    {
513
        throw new \RuntimeException('Not implemented');
514
    }
515
516
    /**
517
     * Checks whether the item is duplicated on updating
518
     *
519
     * @param mixed $itemData
520
     */
521
    public function checkDuplicatedOnUpdate($itemData)
522
    {
523
        throw new \RuntimeException('Not implemented');
524
    }
525
526
    /**
527
     * Checks whether the item is duplicated on adding
528
     *
529
     * @param mixed $itemData
530
     */
531
    public function checkDuplicatedOnAdd($itemData)
532
    {
533
        throw new \RuntimeException('Not implemented');
534
    }
535
536
    /**
537
     * Searches for items by a given filter
538
     *
539
     * @param ItemSearchData $itemSearchData
540
     *
541
     * @return QueryResult
542
     * @throws ConstraintException
543
     * @throws QueryException
544
     */
545
    public function search(ItemSearchData $itemSearchData)
546
    {
547
        $queryData = new QueryData();
548
        $queryData->setSelect('id, name, clientName, categoryName, userName, userGroupName');
549
        $queryData->setFrom('account_search_v');
550
        $queryData->setOrder('name, clientName');
551
552
        if ($itemSearchData->getSeachString() !== '') {
553
            $queryData->setWhere('name LIKE ? 
554
            OR clientName LIKE ? 
555
            OR categoryName LIKE ? 
556
            OR userName LIKE ? 
557
            OR userGroupName LIKE ?');
558
559
            $search = '%' . $itemSearchData->getSeachString() . '%';
560
            $queryData->addParam($search);
561
            $queryData->addParam($search);
562
            $queryData->addParam($search);
563
            $queryData->addParam($search);
564
            $queryData->addParam($search);
565
        }
566
567
        $queryData->setLimit(
568
            '?,?',
569
            [$itemSearchData->getLimitStart(), $itemSearchData->getLimitCount()]
570
        );
571
572
        return $this->db->doSelect($queryData, true);
573
    }
574
575
    /**
576
     * Incrementa el contador de visitas de una cuenta en la BBDD
577
     *
578
     * @param int $id
579
     *
580
     * @return bool
581
     * @throws ConstraintException
582
     * @throws QueryException
583
     */
584
    public function incrementViewCounter($id)
585
    {
586
        $queryData = new QueryData();
587
        $queryData->setQuery('UPDATE Account SET countView = (countView + 1) WHERE id = ? LIMIT 1');
588
        $queryData->addParam($id);
589
590
        return $this->db->doQuery($queryData)->getAffectedNumRows() === 1;
591
    }
592
593
    /**
594
     * Obtener los datos de una cuenta.
595
     *
596
     * @param $id
597
     *
598
     * @return QueryResult
599
     * @throws QueryException
600
     * @throws ConstraintException
601
     */
602
    public function getDataForLink($id)
603
    {
604
        $query = /** @lang SQL */
605
            'SELECT Account.id, 
606
            Account.name,
607
            Account.login,
608
            Account.pass,
609
            Account.key,
610
            Account.url,
611
            Account.notes,
612
            Client.name AS clientName,
613
            Category.name AS categoryName
614
            FROM Account
615
            INNER JOIN Client ON Account.clientId = Client.id
616
            INNER JOIN Category ON Account.categoryId = Category.id 
617
            WHERE Account.id = ? LIMIT 1';
618
619
        $queryData = new QueryData();
620
        $queryData->setQuery($query);
621
        $queryData->setMapClassName(AccountExtData::class);
622
        $queryData->addParam($id);
623
        $queryData->setOnErrorMessage(__u('No se pudieron obtener los datos de la cuenta'));
624
625
        return $this->db->doSelect($queryData);
626
    }
627
628
    /**
629
     * Obtener las cuentas de una búsqueda.
630
     *
631
     * @param AccountSearchFilter $accountSearchFilter
632
     * @param QueryCondition      $queryFilterUser
633
     *
634
     * @return QueryResult
635
     * @throws ConstraintException
636
     * @throws QueryException
637
     * @throws SPException
638
     */
639
    public function getByFilter(AccountSearchFilter $accountSearchFilter, QueryCondition $queryFilterUser)
640
    {
641
        $queryFilters = new QueryCondition();
642
643
        // Sets the search text depending on if special search filters are being used
644
        $searchText = $accountSearchFilter->getCleanTxtSearch();
645
646
        if (!empty($searchText)) {
647
            $queryFilters->addFilter(
648
                'Account.name LIKE ? OR Account.login LIKE ? OR Account.url LIKE ? OR Account.notes LIKE ?',
649
                array_fill(0, 4, '%' . $searchText . '%')
650
            );
651
        }
652
653
        // Gets special search filters
654
        $stringFilters = $accountSearchFilter->getStringFilters();
655
656
        if ($stringFilters->hasFilters()) {
657
            $queryFilters->addFilter($stringFilters->getFilters(), $stringFilters->getParams());
658
        }
659
660
        if (!empty($accountSearchFilter->getCategoryId())) {
661
            $queryFilters->addFilter('Account.categoryId = ?', [$accountSearchFilter->getCategoryId()]);
662
        }
663
664
        if (!empty($accountSearchFilter->getClientId())) {
665
            $queryFilters->addFilter('Account.clientId = ?', [$accountSearchFilter->getClientId()]);
666
        }
667
668
        $where = [];
669
670
        if ($queryFilterUser->hasFilters()) {
671
            $where[] = $queryFilterUser->getFilters();
672
        }
673
674
        $queryData = new QueryData();
675
        $queryJoins = new QueryJoin();
676
677
        if ($accountSearchFilter->isSearchFavorites() === true) {
678
            $queryJoins->addJoin(
679
                'INNER JOIN AccountToFavorite ON (AccountToFavorite.accountId = Account.id AND AccountToFavorite.userId = ?)',
680
                [$this->context->getUserData()->getId()]
681
            );
682
        }
683
684
        if ($accountSearchFilter->hasTags()) {
685
            $queryJoins->addJoin('INNER JOIN AccountToTag ON AccountToTag.accountId = Account.id');
686
            $queryFilters->addFilter(
687
                'AccountToTag.tagId IN (' . $this->getParamsFromArray($accountSearchFilter->getTagsId()) . ')',
688
                $accountSearchFilter->getTagsId()
689
            );
690
691
            if (QueryCondition::CONDITION_AND === $accountSearchFilter->getFilterOperator()) {
692
                $queryData->setGroupBy('Account.id HAVING COUNT(DISTINCT AccountToTag.tagId) = ' . count($accountSearchFilter->getTagsId()));
693
            }
694
        }
695
696
        if ($queryFilters->hasFilters()) {
697
            $where[] = $queryFilters->getFilters($accountSearchFilter->getFilterOperator());
698
        }
699
700
        $queryData->setWhere($where);
701
        $queryData->setParams(array_merge($queryJoins->getParams(), $queryFilterUser->getParams(), $queryFilters->getParams()));
702
        $queryData->setSelect('DISTINCT Account.*');
703
        $queryData->setFrom('account_search_v Account ' . $queryJoins->getJoins());
704
        $queryData->setOrder($accountSearchFilter->getOrderString());
705
706
        if ($accountSearchFilter->getLimitCount() > 0) {
707
            $queryLimit = '?, ?';
708
709
            $queryData->addParam($accountSearchFilter->getLimitStart());
710
            $queryData->addParam($accountSearchFilter->getLimitCount());
711
            $queryData->setLimit($queryLimit);
712
        }
713
714
        $queryData->setMapClassName(AccountSearchVData::class);
715
716
        return $this->db->doSelect($queryData, true);
717
    }
718
719
    /**
720
     * @param QueryCondition $queryFilter
721
     *
722
     * @return QueryResult
723
     * @throws ConstraintException
724
     * @throws QueryException
725
     */
726
    public function getForUser(QueryCondition $queryFilter)
727
    {
728
        $query = /** @lang SQL */
729
            'SELECT Account.id, Account.name, C.name AS clientName 
730
            FROM Account
731
            LEFT JOIN Client C ON Account.clientId = C.id 
732
            WHERE ' . $queryFilter->getFilters() . ' ORDER BY name';
733
734
        $queryData = new QueryData();
735
        $queryData->setMapClassName(ItemData::class);
736
        $queryData->setQuery($query);
737
        $queryData->setParams($queryFilter->getParams());
738
739
        return $this->db->doSelect($queryData);
740
    }
741
742
    /**
743
     * @param QueryCondition $queryFilter
744
     *
745
     * @return QueryResult
746
     * @throws ConstraintException
747
     * @throws QueryException
748
     */
749
    public function getLinked(QueryCondition $queryFilter)
750
    {
751
        $query = /** @lang SQL */
752
            'SELECT Account.id, Account.name, Client.name AS clientName 
753
            FROM Account
754
            INNER JOIN Client ON Account.clientId = Client.id 
755
            WHERE ' . $queryFilter->getFilters() . ' ORDER  BY Account.name';
756
757
        $queryData = new QueryData();
758
        $queryData->setQuery($query);
759
        $queryData->setParams($queryFilter->getParams());
760
761
        return $this->db->doSelect($queryData);
762
    }
763
764
    /**
765
     * Obtener los datos relativos a la clave de todas las cuentas.
766
     *
767
     * @return array Con los datos de la clave
768
     * @throws ConstraintException
769
     * @throws QueryException
770
     */
771
    public function getAccountsPassData()
772
    {
773
        $queryData = new QueryData();
774
        $queryData->setQuery('SELECT id, `name`, pass, `key` FROM Account WHERE BIT_LENGTH(pass) > 0');
775
776
        return $this->db->doSelect($queryData)->getDataAsArray();
777
    }
778
}