Completed
Push — preview-1.22.0 ( feac42...3f8d5c )
by Guilherme
15:10 queued 07:58
created

PersonRepository::getPartialPhoneSearchQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
ccs 0
cts 4
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * This file is part of the login-cidadao project or it's bundles.
4
 *
5
 * (c) Guilherme Donato <guilhermednt on github>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LoginCidadao\CoreBundle\Entity;
12
13
use Doctrine\ORM\EntityRepository;
14
use Doctrine\ORM\NonUniqueResultException;
15
use Doctrine\ORM\NoResultException;
16
use Egulias\EmailValidator\EmailValidator;
17
use Egulias\EmailValidator\Validation\RFCValidation;
18
use libphonenumber\PhoneNumber;
19
use libphonenumber\PhoneNumberFormat;
20
use libphonenumber\PhoneNumberUtil;
21
use Misd\PhoneNumberBundle\Doctrine\DBAL\Types\PhoneNumberType;
22
23
class PersonRepository extends EntityRepository
24
{
25
26
    public function findAllPendingCPF()
27
    {
28
        return $this->getEntityManager()
29
                ->createQuery('SELECT p FROM LoginCidadaoCoreBundle:Person p WHERE p.cpf IS NULL')
30
                ->getResult();
31
    }
32
33
    public function findUnconfirmedEmailUntilDate(\DateTime $dateLimit)
34
    {
35
        return $this->getEntityManager()
36
            ->createQuery(
37
                'SELECT p FROM LoginCidadaoCoreBundle:Person p WHERE p.emailConfirmedAt IS NULL AND p.emailExpiration <= :date'
38
            )
39
                ->setParameter('date', $dateLimit)
40
                ->getResult();
41
    }
42
43
    public function getFindAuthorizedByClientIdQuery($clientId)
44
    {
45
        return $this->createQueryBuilder('p')
46
            ->innerJoin(
47
                'LoginCidadaoCoreBundle:Authorization',
48
                'a',
49
                'WITH',
50
                'a.person = p'
51
            )
52
            ->innerJoin(
53
                'LoginCidadaoOAuthBundle:Client',
54
                'c',
55
                'WITH',
56
                'a.client = c'
57
            )
58
                ->andWhere('c.id = :clientId')
59
            ->setParameter('clientId', $clientId);
60
    }
61
62
    public function getCountByCountry()
63
    {
64
        $qb = $this->getEntityManager()->createQueryBuilder();
65
66
        return $qb
67
                ->select('count(p.country) AS qty, c.name')
68
                ->from('LoginCidadaoCoreBundle:Person', 'p')
69
            ->innerJoin(
70
                'LoginCidadaoCoreBundle:Country',
71
                'c',
72
                'WITH',
73
                'p.country = c'
74
            )
75
                ->where('p.country IS NOT NULL')
76
                ->groupBy('p.country, c.name')
77
                ->orderBy('qty', 'DESC')
78
                ->getQuery()->getResult();
79
    }
80
81
    public function getCountByState()
82
    {
83
        $qb = $this->getEntityManager()->createQueryBuilder();
84
85
        return $qb
86
                ->select('count(p.state) AS qty, s.id, s.name, c.name AS country')
87
                ->from('LoginCidadaoCoreBundle:Person', 'p')
88
            ->innerJoin(
89
                'LoginCidadaoCoreBundle:State',
90
                's',
91
                'WITH',
92
                'p.state = s'
93
            )
94
            ->innerJoin(
95
                'LoginCidadaoCoreBundle:Country',
96
                'c',
97
                'WITH',
98
                's.country = c'
99
            )
100
                ->where('p.state IS NOT NULL')
101
                ->groupBy('p.state, s.name, country, s.id')
102
                ->orderBy('qty', 'DESC')
103
                ->getQuery()->getResult();
104
    }
105
106
    public function getCountByCity($stateId)
107
    {
108
        $qb = $this->getEntityManager()->createQueryBuilder();
109
110
        return $qb
111
                ->select('count(p.city) AS qty, c.name')
112
                ->from('LoginCidadaoCoreBundle:Person', 'p')
113
            ->innerJoin(
114
                'LoginCidadaoCoreBundle:City',
115
                'c',
116
                'WITH',
117
                'p.city = c'
118
            )
119
            ->innerJoin(
120
                'LoginCidadaoCoreBundle:State',
121
                's',
122
                'WITH',
123
                'c.state = s'
124
            )
125
                ->where('p.city IS NOT NULL')
126
                ->andWhere('s.id = :stateId')
127
                ->groupBy('p.city, c.name')
128
                ->orderBy('qty', 'DESC')
129
                ->setParameter('stateId', $stateId)
130
                ->getQuery()->getResult();
131
    }
132
133
    public function getCountAll()
134
    {
135
        $qb = $this->getEntityManager()->createQueryBuilder();
136
137
        return $qb
138
                ->select('count(p.id) AS qty')
139
                ->from('LoginCidadaoCoreBundle:Person', 'p')
140
                ->orderBy('qty', 'DESC')
141
                ->getQuery()->getSingleResult();
142
    }
143
144
    public function getUserSearchQuery($query)
145
    {
146
        return $this->createQueryBuilder('p')
147
            ->where(
148
                'p.cpf LIKE :query OR p.username LIKE :query OR p.email LIKE :query OR p.firstName LIKE :query OR p.surname LIKE :query'
149
            )
150
                ->setParameter('query', '%'.addcslashes($query, '\\%_').'%')
151
                ->addOrderBy('p.id', 'DESC');
152
    }
153
154
    public function getFindByIdIn($ids)
155
    {
156
        return $this->createQueryBuilder('p')
157
                ->where('p.id in(:ids)')
158
                ->setParameters(compact('ids'))
159
                ->addOrderBy('p.id', 'desc');
160
    }
161
162
    public function findOneByEmail($email)
163
    {
164
        return $this->createQueryBuilder('p')
165
            ->where('p.email = :email')
166
            ->orWhere('p.emailCanonical = :email')
167
            ->setParameter('email', $email)
168
            ->getQuery()->getOneOrNullResult();
169
    }
170
171
    /**
172
     * @param PhoneNumber $phone
173
     * @return int
174
     */
175
    public function countByPhone(PhoneNumber $phone)
176
    {
177
        try {
178
            $phoneUtil = PhoneNumberUtil::getInstance();
179
180
            return $this->createQueryBuilder('p')
181
                ->select('COUNT(p)')
182
                ->where('p.mobile = :mobile')
183
                ->setParameter('mobile', $phoneUtil->format($phone, PhoneNumberFormat::E164))
184
                ->getQuery()->getSingleScalarResult();
185
        } catch (NoResultException $e) {
186
            return 0;
187
        } catch (NonUniqueResultException $e) {
188
            return 0;
189
        }
190
    }
191
192
    /**
193
     * @return \Doctrine\ORM\QueryBuilder
194
     */
195
    private function getBaseSearchQuery()
196
    {
197
        return $this->createQueryBuilder('p')
198
            ->addOrderBy('p.id', 'DESC');
199
    }
200
201
    public function getCpfSearchQuery($cpf)
202
    {
203
        return $this->getBaseSearchQuery()
204
            ->where('p.cpf = :cpf')
205
            ->setParameter('cpf', $cpf);
206
    }
207
208
    public function getEmailSearchQuery($email)
209
    {
210
        return $this->getBaseSearchQuery()
211
            ->where('p.emailCanonical = LOWER(:email)')
212
            ->setParameter('email', $email);
213
    }
214
215
    public function getNameSearchQuery($name)
216
    {
217
        $sanitized = addcslashes($name, "%_");
218
219
        return $this->getBaseSearchQuery()
220
            ->where('LowerUnaccent(p.username) LIKE LowerUnaccent(:name)')
221
            ->orWhere('LowerUnaccent(p.firstName) LIKE LowerUnaccent(:name)')
222
            ->orWhere('LowerUnaccent(p.surname) LIKE LowerUnaccent(:name)')
223
            ->setParameter('name', "%{$sanitized}%");
224
    }
225
226
    public function getPhoneSearchQuery(PhoneNumber $phoneNumber)
227
    {
228
        return $this->getBaseSearchQuery()
229
            ->where('p.mobile = :mobile')
230
            ->setParameter('mobile', $phoneNumber, PhoneNumberType::NAME);
231
    }
232
233
    public function getPartialPhoneSearchQuery(string $phoneNumber)
234
    {
235
        return $this->getBaseSearchQuery()
236
            ->where('p.mobile LIKE :mobile')
237
            ->setParameter('mobile', "{$phoneNumber}%");
238
    }
239
240
    /**
241
     * This will return the appropriate query for the input given.
242
     * @param $query
243
     * @return \Doctrine\ORM\QueryBuilder
244
     */
245
    public function getSmartSearchQuery($query)
246
    {
247
        $query = trim($query);
248
249
        if (strlen($query) == 0) {
250
            return $this->getBaseSearchQuery();
251
        }
252
253
        $cpfRegex = '/^(?:\d{3}\.?){2}\d{3}-?\d{2}$/';
254
        // Check CPF
255
        if (preg_match($cpfRegex, $query) === 1) {
256
            $cpf = str_replace(['.', '-'], '', $query);
257
258
            return $this->getCpfSearchQuery($cpf);
259
        }
260
261
        // Check email
262
        $emailValidator = new EmailValidator();
263
        if ($emailValidator->isValid($query, new RFCValidation())) {
264
            return $this->getEmailSearchQuery($query);
265
        }
266
267
        if ($query[0] === '+') {
268
            return $this->getPartialPhoneSearchQuery($query);
269
        }
270
271
        // Defaults to name search
272
        return $this->getNameSearchQuery($query);
273
    }
274
}
275