Completed
Pull Request — master (#317)
by Guilherme
04:03
created

PersonRepository::getPhoneSearchQuery()   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
rs 10
c 0
b 0
f 0
ccs 0
cts 4
cp 0
crap 2
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
    /**
163
     * @param PhoneNumber $phone
164
     * @return int
165
     */
166
    public function countByPhone(PhoneNumber $phone)
167
    {
168
        try {
169
            $phoneUtil = PhoneNumberUtil::getInstance();
170
171
            return $this->createQueryBuilder('p')
172
                ->select('COUNT(p)')
173
                ->where('p.mobile = :mobile')
174
                ->setParameter('mobile', $phoneUtil->format($phone, PhoneNumberFormat::E164))
175
                ->getQuery()->getSingleScalarResult();
176
        } catch (NoResultException $e) {
177
            return 0;
178
        } catch (NonUniqueResultException $e) {
179
            return 0;
180
        }
181
    }
182
183
    /**
184
     * @return \Doctrine\ORM\QueryBuilder
185
     */
186
    private function getBaseSearchQuery()
187
    {
188
        return $this->createQueryBuilder('p')
189
            ->addOrderBy('p.id', 'DESC');
190
    }
191
192
    public function getCpfSearchQuery($cpf)
193
    {
194
        return $this->getBaseSearchQuery()
195
            ->where('p.cpf = :cpf')
196
            ->setParameter('cpf', $cpf);
197
    }
198
199
    public function getEmailSearchQuery($email)
200
    {
201
        return $this->getBaseSearchQuery()
202
            ->where('p.emailCanonical = LOWER(:email)')
203
            ->setParameter('email', $email);
204
    }
205
206
    public function getNameSearchQuery($name)
207
    {
208
        $sanitized = addcslashes($name, "%_");
209
210
        return $this->getBaseSearchQuery()
211
            ->where('LowerUnaccent(p.username) LIKE LowerUnaccent(:name)')
212
            ->orWhere('LowerUnaccent(p.firstName) LIKE LowerUnaccent(:name)')
213
            ->orWhere('LowerUnaccent(p.surname) LIKE LowerUnaccent(:name)')
214
            ->setParameter('name', "%{$sanitized}%");
215
    }
216
217
    public function getPhoneSearchQuery(PhoneNumber $phoneNumber)
218
    {
219
        return $this->getBaseSearchQuery()
220
            ->where('p.mobile = :mobile')
221
            ->setParameter('mobile', $phoneNumber, PhoneNumberType::NAME);
222
    }
223
224
    /**
225
     * This will return the appropriate query for the input given.
226
     * @param $query
227
     * @return \Doctrine\ORM\QueryBuilder
228
     */
229
    public function getSmartSearchQuery($query)
230
    {
231
        $query = trim($query);
232
233
        if (strlen($query) == 0) {
234
            return $this->getBaseSearchQuery();
235
        }
236
237
        $cpfRegex = '/^(?:\d{3}\.?){2}\d{3}-?\d{2}$/';
238
        // Check CPF
239
        if (preg_match($cpfRegex, $query) === 1) {
240
            $cpf = str_replace(['.', '-'], '', $query);
241
242
            return $this->getCpfSearchQuery($cpf);
243
        }
244
245
        // Check email
246
        $emailValidator = new EmailValidator();
247
        if ($emailValidator->isValid($query, new RFCValidation())) {
248
            return $this->getEmailSearchQuery($query);
249
        }
250
251
        // Defaults to name search
252
        return $this->getNameSearchQuery($query);
253
    }
254
}
255