Passed
Push — main ( 1624e8...f4f78e )
by Axel
06:01 queued 01:50
created

UserRepository::findAllAsIterable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\UsersBundle\Repository;
15
16
use DateTime;
17
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
18
use Doctrine\Common\Collections\ArrayCollection;
19
use Doctrine\ORM\Internal\Hydration\IterableResult;
20
use Doctrine\ORM\Query\Expr\OrderBy;
21
use Doctrine\Persistence\ManagerRegistry;
22
use Zikula\CoreBundle\Doctrine\Paginator;
0 ignored issues
show
Bug introduced by
The type Zikula\CoreBundle\Doctrine\Paginator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
23
use Zikula\CoreBundle\Doctrine\WhereFromFilterTrait;
24
use Zikula\UsersBundle\Entity\User;
25
use Zikula\UsersBundle\Entity\UserAttribute;
26
use Zikula\UsersBundle\UsersConstant;
27
28
class UserRepository extends ServiceEntityRepository implements UserRepositoryInterface
29
{
30
    use WhereFromFilterTrait;
31
32
    public function __construct(ManagerRegistry $registry)
33
    {
34
        parent::__construct($registry, User::class);
35
    }
36
37
    public function findByUids(array $userIds = []): array
38
    {
39
        // using queryBuilder allows to index collection by the uid
40
        $qb = $this->createQueryBuilder('u', 'u.uid')
41
            ->where('u.uid IN (:uids)')
42
            ->setParameter('uids', $userIds);
43
44
        return $qb->getQuery()->getResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb->getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
45
    }
46
47
    public function setApproved(User $user, DateTime $approvedOn, int $approvedBy = null): void
48
    {
49
        $user->setApprovedDate($approvedOn);
50
        $user->setApprovedBy($approvedBy ?? $user->getUid());
0 ignored issues
show
Bug introduced by
The method getUid() does not exist on Zikula\UsersBundle\Entity\User. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
        $user->setApprovedBy($approvedBy ?? $user->/** @scrutinizer ignore-call */ getUid());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
51
    }
52
53
    public function queryBySearchForm(array $formData = [])
54
    {
55
        $filter = [];
56
        foreach ($formData as $k => $v) {
57
            if (!empty($v)) {
58
                switch ($k) {
59
                    case 'registered_before':
60
                        $filter['registrationDate'] = ['operator' => '<=', 'operand' => $v];
61
                        break;
62
                    case 'registered_after':
63
                        $filter['registrationDate'] = ['operator' => '>=', 'operand' => $v];
64
                        break;
65
                    case 'groups':
66
                        /** @var ArrayCollection $v */
67
                        if (!$v->isEmpty()) {
68
                            $filter['groups'] = ['operator' => 'in', 'operand' => $v->getValues()];
69
                        }
70
                        break;
71
                    case 'activated':
72
                        $filter['activated'] = ['operator' => '=', 'operand' => $v];
73
                        break;
74
                    default:
75
                        $filter[$k] = ['operator' => 'like', 'operand' => '%' . $v . '%'];
76
                }
77
            }
78
        }
79
80
        return $this->query($filter);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->query($filter) also could return the type integer which is incompatible with the return type mandated by Zikula\UsersBundle\Repos...ce::queryBySearchForm() of Zikula\UsersBundle\Entity\User[].
Loading history...
81
    }
82
83
    public function getSearchResults(array $words = [])
84
    {
85
        $qb = $this->createQueryBuilder('u')
86
            ->andWhere('u.activated != :activated')
87
            ->setParameter('activated', UsersConstant::ACTIVATED_PENDING_REG);
88
        $where = $qb->expr()->orX();
89
        $i = 1;
90
        foreach ($words as $word) {
91
            $subWhere = $qb->expr()->orX();
92
            $expr = $qb->expr()->like('u.uname', '?' . $i);
93
            $subWhere->add($expr);
94
            $qb->setParameter($i, '%' . $word . '%');
95
            $i++;
96
            $where->add($subWhere);
97
        }
98
        $qb->andWhere($where);
99
100
        return $qb->getQuery()->getResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb->getQuery()->getResult() also could return the type integer which is incompatible with the return type mandated by Zikula\UsersBundle\Repos...ace::getSearchResults() of Zikula\UsersBundle\Entity\User[].
Loading history...
101
    }
102
103
    private function makeQueryBuilder(
104
        array $filter = [],
105
        array $sort = [],
106
        string $exprType = 'and'
107
    ) {
108
        $qb = $this->createQueryBuilder('u')
109
            ->select('u');
110
        if (!empty($filter['groups'])) {
111
            $qb->join('u.groups', 'g');
112
        }
113
        if (!empty($filter)) {
114
            $where = $this->whereFromFilter($qb, $filter, $exprType);
115
            $qb->andWhere($where);
116
        }
117
        if (!empty($sort)) {
118
            $qb->orderBy($this->orderByFromArray($sort));
119
        }
120
121
        return $qb;
122
    }
123
124
    public function query(
125
        array $filter = [],
126
        array $sort = [],
127
        string $exprType = 'and'
128
    ) {
129
        $qb = $this->makeQueryBuilder($filter, $sort, $exprType);
130
131
        return $qb->getQuery()->getResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb->getQuery()->getResult() also could return the type integer which is incompatible with the return type mandated by Zikula\UsersBundle\Repos...itoryInterface::query() of Zikula\UsersBundle\Entity\User[].
Loading history...
132
    }
133
134
    public function paginatedQuery(
135
        array $filter = [],
136
        array $sort = [],
137
        string $exprType = 'and',
138
        int $page = 1,
139
        int $pageSize = 25
140
    ) {
141
        $qb = $this->makeQueryBuilder($filter, $sort, $exprType);
142
143
        return (new Paginator($qb, $pageSize))->paginate($page);
144
    }
145
146
    public function count(array $filter = [], string $exprType = 'and'): int
147
    {
148
        $qb = $this->createQueryBuilder('u')
149
            ->select('count(u.uid)');
150
        if (!empty($filter)) {
151
            $where = $this->whereFromFilter($qb, $filter, $exprType);
152
            $qb->andWhere($where);
153
        }
154
        $query = $qb->getQuery();
155
156
        return (int) $query->getSingleScalarResult();
157
    }
158
159
    /**
160
     * Construct a QueryBuilder Expr\OrderBy object suitable for use in QueryBuilder->orderBy() from an array.
161
     * sort = [field => dir, field => dir, ...]
162
     */
163
    private function orderByFromArray(array $sort = []): OrderBy
164
    {
165
        $orderBy = new OrderBy();
166
        foreach ($sort as $field => $direction) {
167
            $orderBy->add('u.' . $field, $direction);
168
        }
169
170
        return $orderBy;
171
    }
172
173
    public function findAllAsIterable(): IterableResult
174
    {
175
        $qb = $this->createQueryBuilder('u');
176
177
        return $qb->getQuery()->iterate();
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\ORM\Query::iterate() has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

177
        return /** @scrutinizer ignore-deprecated */ $qb->getQuery()->iterate();
Loading history...
178
    }
179
180
    public function searchActiveUser(array $unameFilter = [])
181
    {
182
        if (!count($unameFilter)) {
183
            return [];
184
        }
185
186
        $filter = [
187
            'activated' => ['operator' => 'notIn', 'operand' => [
188
                UsersConstant::ACTIVATED_PENDING_REG,
189
                UsersConstant::ACTIVATED_PENDING_DELETE
190
            ]],
191
            'uname' => $unameFilter
192
        ];
193
194
        return $this->query($filter, ['uname' => 'asc']);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->query($fil...rray('uname' => 'asc')) also could return the type integer which is incompatible with the return type mandated by Zikula\UsersBundle\Repos...ace::searchActiveUser() of Zikula\UsersBundle\Entity\User[].
Loading history...
195
    }
196
197
    public function countDuplicateUnames(string $uname, ?int $uid = null): int
198
    {
199
        $qb = $this->createQueryBuilder('u');
200
        $qb->select('count(u.uid)')
201
            ->where($qb->expr()->eq('LOWER(u.uname)', ':uname'))
202
            ->setParameter('uname', mb_strtolower($uname));
203
        // when updating an existing User, the existing Uid must be excluded.
204
        if (isset($uid)) {
205
            $qb->andWhere('u.uid != :excludedUid')
206
                ->setParameter('excludedUid', $uid);
207
        }
208
209
        return (int) $qb->getQuery()->getSingleScalarResult();
210
    }
211
212
    public function getByEmailAndAuthMethod(string $email, string $authMethod): array
213
    {
214
        $qb = $this->createQueryBuilder('u');
215
        $qb->join('u.attributes', 'a')
216
            ->where('u.email = :email')
217
            ->setParameter('email', $email)
218
            ->andWhere($qb->expr()->andX(
219
                $qb->expr()->eq('a.name', ':attributeName'),
220
                $qb->expr()->neq('a.value', ':authMethod')
221
            ))
222
            ->setParameter('attributeName', UsersConstant::AUTHENTICATION_METHOD_ATTRIBUTE_KEY)
0 ignored issues
show
Bug introduced by
The constant Zikula\UsersBundle\Users...ON_METHOD_ATTRIBUTE_KEY was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
223
            ->setParameter('authMethod', $authMethod);
224
225
        return $qb->getQuery()->getArrayResult();
226
    }
227
}
228