Completed
Pull Request — master (#4220)
by Craig
05:14
created

UserRepository::paginatedQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 5
dl 0
loc 10
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 Foundation - 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\UsersModule\Entity\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\Bundle\CoreBundle\Doctrine\Paginator;
23
use Zikula\Bundle\CoreBundle\Doctrine\WhereFromFilterTrait;
24
use Zikula\UsersModule\Constant as UsersConstant;
25
use Zikula\UsersModule\Entity\RepositoryInterface\UserRepositoryInterface;
26
use Zikula\UsersModule\Entity\UserAttributeEntity;
27
use Zikula\UsersModule\Entity\UserEntity;
28
29
class UserRepository extends ServiceEntityRepository implements UserRepositoryInterface
30
{
31
    use WhereFromFilterTrait;
32
33
    public function __construct(ManagerRegistry $registry)
34
    {
35
        parent::__construct($registry, UserEntity::class);
36
    }
37
38
    public function findByUids(array $userIds = []): array
39
    {
40
        // using queryBuilder allows to index collection by the uid
41
        $qb = $this->createQueryBuilder('u', 'u.uid')
42
            ->where('u.uid IN (:uids)')
43
            ->setParameter('uids', $userIds);
44
45
        return $qb->getQuery()->getResult();
46
    }
47
48
    public function persistAndFlush(UserEntity $user): void
49
    {
50
        $this->_em->persist($user);
51
        $this->_em->flush();
52
    }
53
54
    public function removeAndFlush(UserEntity $user): void
55
    {
56
        // the following process should be unnecessary because cascade = all but MySQL 5.7 not working with that (#3726)
57
        $qb = $this->_em->createQueryBuilder();
58
        $qb->delete(UserAttributeEntity::class, 'a')
59
           ->where('a.user = :userId')
60
           ->setParameter('userId', $user->getUid());
61
        $query = $qb->getQuery();
62
        $query->execute();
63
        // end of theoretically unrequired process
64
65
        $user->setAttributes(new ArrayCollection());
66
        $this->_em->remove($user);
67
        $this->_em->flush();
68
    }
69
70
    public function setApproved(UserEntity $user, DateTime $approvedOn, int $approvedBy = null): void
71
    {
72
        $user->setApprovedDate($approvedOn);
73
        $user->setApprovedBy($approvedBy ?? $user->getUid());
74
        $this->_em->flush();
75
    }
76
77
    public function queryBySearchForm(array $formData = [])
78
    {
79
        $filter = [];
80
        foreach ($formData as $k => $v) {
81
            if (!empty($v)) {
82
                switch ($k) {
83
                    case 'registered_before':
84
                        $filter['registrationDate'] = ['operator' => '<=', 'operand' => $v];
85
                        break;
86
                    case 'registered_after':
87
                        $filter['registrationDate'] = ['operator' => '>=', 'operand' => $v];
88
                        break;
89
                    case 'groups':
90
                        /** @var ArrayCollection $v */
91
                        if (!$v->isEmpty()) {
92
                            $filter['groups'] = ['operator' => 'in', 'operand' => $v->getValues()];
93
                        }
94
                        break;
95
                    case 'activated':
96
                        $filter['activated'] = ['operator' => '=', 'operand' => $v];
97
                        break;
98
                    default:
99
                        $filter[$k] = ['operator' => 'like', 'operand' => "%${v}%"];
100
                }
101
            }
102
        }
103
104
        return $this->query($filter);
105
    }
106
107
    public function getSearchResults(array $words = [])
108
    {
109
        $qb = $this->createQueryBuilder('u')
110
            ->andWhere('u.activated != :activated')
111
            ->setParameter('activated', UsersConstant::ACTIVATED_PENDING_REG);
112
        $where = $qb->expr()->orX();
113
        $i = 1;
114
        foreach ($words as $word) {
115
            $subWhere = $qb->expr()->orX();
116
            $expr = $qb->expr()->like('u.uname', "?${i}");
117
            $subWhere->add($expr);
118
            $qb->setParameter($i, '%' . $word . '%');
119
            $i++;
120
            $where->add($subWhere);
121
        }
122
        $qb->andWhere($where);
123
124
        return $qb->getQuery()->getResult();
125
    }
126
127
    private function makeQueryBuilder(
128
        array $filter = [],
129
        array $sort = [],
130
        string $exprType = 'and'
131
    ) {
132
        $qb = $this->createQueryBuilder('u')
133
            ->select('u');
134
        if (!empty($filter['groups'])) {
135
            $qb->join('u.groups', 'g');
136
        }
137
        if (!empty($filter)) {
138
            $where = $this->whereFromFilter($qb, $filter, $exprType);
139
            $qb->andWhere($where);
140
        }
141
        if (!empty($sort)) {
142
            $qb->orderBy($this->orderByFromArray($sort));
143
        }
144
145
        return $qb;
146
    }
147
148
    public function query(
149
        array $filter = [],
150
        array $sort = [],
151
        string $exprType = 'and'
152
    ) {
153
        $qb = $this->makeQueryBuilder($filter, $sort, $exprType);
154
155
        return $qb->getQuery()->getResult();
156
    }
157
158
    public function paginatedQuery(
159
        array $filter = [],
160
        array $sort = [],
161
        string $exprType = 'and',
162
        int $page = 1,
163
        int $pageSize = 25
164
    ) {
165
        $qb = $this->makeQueryBuilder($filter, $sort, $exprType);
166
167
        return (new Paginator($qb, $pageSize))->paginate($page);
168
    }
169
170
    public function count(array $filter = [], string $exprType = 'and'): int
171
    {
172
        $qb = $this->createQueryBuilder('u')
173
            ->select('count(u.uid)');
174
        if (!empty($filter)) {
175
            $where = $this->whereFromFilter($qb, $filter, $exprType);
176
            $qb->andWhere($where);
177
        }
178
        $query = $qb->getQuery();
179
180
        return (int) $query->getSingleScalarResult();
181
    }
182
183
    /**
184
     * Construct a QueryBuilder Expr\OrderBy object suitable for use in QueryBuilder->orderBy() from an array.
185
     * sort = [field => dir, field => dir, ...]
186
     */
187
    private function orderByFromArray(array $sort = []): OrderBy
188
    {
189
        $orderBy = new OrderBy();
190
        foreach ($sort as $field => $direction) {
191
            $orderBy->add('u.' . $field, $direction);
192
        }
193
194
        return $orderBy;
195
    }
196
197
    public function findAllAsIterable(): IterableResult
198
    {
199
        $qb = $this->createQueryBuilder('u');
200
201
        return $qb->getQuery()->iterate();
202
    }
203
204
    public function searchActiveUser(array $unameFilter = [])
205
    {
206
        if (!count($unameFilter)) {
207
            return [];
208
        }
209
210
        $filter = [
211
            'activated' => ['operator' => 'notIn', 'operand' => [
212
                UsersConstant::ACTIVATED_PENDING_REG,
213
                UsersConstant::ACTIVATED_PENDING_DELETE
214
            ]],
215
            'uname' => $unameFilter
216
        ];
217
218
        return $this->query($filter, ['uname' => 'asc']);
219
    }
220
}
221