Completed
Push — release/3.1 ( 66615d...065b4e )
by
unknown
02:43 queued 37s
created

RaListingRepository::createSearchQuery()   D

Complexity

Conditions 10
Paths 320

Size

Total Lines 67

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 67
rs 4.9866
c 0
b 0
f 0
cc 10
nc 320
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Copyright 2014 SURFnet bv
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace Surfnet\StepupMiddleware\ApiBundle\Identity\Repository;
20
21
use Doctrine\Common\Collections\ArrayCollection;
22
use Doctrine\ORM\EntityManager;
23
use Doctrine\ORM\EntityRepository;
24
use Doctrine\ORM\Mapping;
25
use Surfnet\Stepup\Identity\Value\IdentityId;
26
use Surfnet\Stepup\Identity\Value\Institution;
27
use Surfnet\StepupMiddleware\ApiBundle\Authorization\Filter\InstitutionAuthorizationRepositoryFilter;
28
use Surfnet\StepupMiddleware\ApiBundle\Authorization\Value\InstitutionAuthorizationContextInterface;
29
use Surfnet\StepupMiddleware\ApiBundle\Exception\RuntimeException;
30
use Surfnet\StepupMiddleware\ApiBundle\Identity\Entity\RaListing;
31
use Surfnet\StepupMiddleware\ApiBundle\Identity\Query\RaListingQuery;
32
33
/**
34
 * @SuppressWarnings(PHPMD.TooManyPublicMethods)
35
 */
36
class RaListingRepository extends EntityRepository
37
{
38
    /**
39
     * @var InstitutionAuthorizationRepositoryFilter
40
     */
41
    private $authorizationRepositoryFilter;
42
43
    public function __construct(
44
        EntityManager $em,
45
        Mapping\ClassMetadata $class,
46
        InstitutionAuthorizationRepositoryFilter $authorizationRepositoryFilter
47
    ) {
48
        parent::__construct($em, $class);
49
        $this->authorizationRepositoryFilter = $authorizationRepositoryFilter;
50
    }
51
52
    /**
53
     * @param IdentityId $identityId The RA's identity id.
54
     * @return null|RaListing[]
0 ignored issues
show
Documentation introduced by
Should the return type not be array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
55
     */
56
    public function findByIdentityId(IdentityId $identityId)
57
    {
58
        return parent::findBy(['identityId' => (string) $identityId]);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (findBy() instead of findByIdentityId()). Are you sure this is correct? If so, you might want to change this to $this->findBy().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
59
    }
60
61
    /**
62
     * @param IdentityId $identityId The RA's identity id.
63
     * @param Institution $raInstitution
64
     * @return null|RaListing
0 ignored issues
show
Documentation introduced by
Should the return type not be object|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
65
     */
66
    public function findByIdentityIdAndRaInstitution(IdentityId $identityId, Institution $raInstitution)
67
    {
68
        return parent::findOneBy([
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (findOneBy() instead of findByIdentityIdAndRaInstitution()). Are you sure this is correct? If so, you might want to change this to $this->findOneBy().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
69
            'identityId' => (string) $identityId,
70
            'raInstitution' => (string) $raInstitution,
71
        ]);
72
    }
73
74
75
    /**
76
     * @param IdentityId $identityId The RA's identity id.
77
     * @param Institution $raInstitution
78
     * @param InstitutionAuthorizationContextInterface $authorizationContext
79
     * @return null|RaListing
80
     */
81
    public function findByIdentityIdAndRaInstitutionWithContext(
82
        IdentityId $identityId,
83
        Institution $raInstitution,
84
        InstitutionAuthorizationContextInterface $authorizationContext
85
    ) {
86
        $queryBuilder = $this->createQueryBuilder('r')
87
            ->where('r.identityId = :identityId')
88
            ->andWhere('r.raInstitution = :raInstitution')
89
            ->setParameter('identityId', $identityId)
90
            ->setParameter('raInstitution', (string)$raInstitution)
91
            ->orderBy('r.raInstitution');
92
93
        // Modify query to filter on authorization:
94
        // For the RA listing we want identities that are already RA. Because we then need to look at the use_raa's
95
        // we have to look at the RA-institutions because that's the institution the user is RA for and we should use
96
        // those RA's. Hence the 'r.raInstitution'.
97
        $this->authorizationRepositoryFilter->filter(
98
            $queryBuilder,
99
            $authorizationContext,
100
            'r.raInstitution',
101
            'iac'
102
        );
103
104
        return $queryBuilder->getQuery()->getOneOrNullResult();
105
    }
106
107
    /**
108
     * @param IdentityId $identityId The RA's identity id.
109
     * @param Institution $institution
110
     * @return RaListing[]
111
     */
112
    public function findByIdentityIdAndInstitution(IdentityId $identityId, Institution $institution)
113
    {
114
        return parent::findBy([
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (findBy() instead of findByIdentityIdAndInstitution()). Are you sure this is correct? If so, you might want to change this to $this->findBy().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
115
            'identityId' => (string) $identityId,
116
            'institution' => (string) $institution,
117
        ]);
118
    }
119
120
    public function save(RaListing $raListingEntry)
121
    {
122
        $this->getEntityManager()->persist($raListingEntry);
123
        $this->getEntityManager()->flush();
124
    }
125
126
    /**
127
     * @SuppressWarnings(PHPMD.CyclomaticComplexity) The amount of if statements do not necessarily make the method
128
     * @SuppressWarnings(PHPMD.NPathComplexity)      below complex or hard to maintain.
129
     *
130
     * @param RaListingQuery $query
131
     * @return \Doctrine\ORM\Query
132
     */
133
    public function createSearchQuery(RaListingQuery $query)
134
    {
135
        $queryBuilder = $this->createQueryBuilder('r');
136
137
        if ($query->institution) {
138
            $queryBuilder
139
                ->andWhere('r.institution = :institution')
140
                ->setParameter('institution', $query->institution);
141
        }
142
143
        if ($query->identityId) {
144
            $queryBuilder
145
                ->andWhere('r.identityId = :identityId')
146
                ->setParameter('identityId', (string) $query->identityId);
147
        }
148
149
        if ($query->name) {
150
            $queryBuilder
151
                ->andWhere('r.commonName LIKE :name')
152
                ->setParameter('name', sprintf('%%%s%%', $query->name));
153
        }
154
155
        if ($query->email) {
156
            $queryBuilder
157
                ->andWhere('r.email LIKE :email')
158
                ->setParameter('email', sprintf('%%%s%%', $query->email));
159
        }
160
161
        if ($query->role) {
162
            $queryBuilder
163
                ->andWhere('r.role = :role')
164
                ->setParameter('role', (string) $query->role);
165
        }
166
167
        if ($query->raInstitution) {
168
            $queryBuilder
169
                ->andWhere('r.raInstitution = :raInstitution')
170
                ->setParameter('raInstitution', (string) $query->raInstitution);
171
        }
172
173
        // Modify query to filter on authorization:
174
        // For the RA listing we want identities that are already RA. Because we then need to look at the use_raa's
175
        // we have to look at the RA-institutions because that's the institution the user is RA for and we should use
176
        // those RA's. Hence the 'r.raInstitution'.
177
        $this->authorizationRepositoryFilter->filter(
178
            $queryBuilder,
179
            $query->authorizationContext,
180
            'r.raInstitution',
181
            'iac'
182
        );
183
184
        if (!$query->orderBy) {
185
            return $queryBuilder->getQuery();
186
        }
187
188
        $orderDirection = $query->orderDirection === 'asc' ? 'ASC' : 'DESC';
189
190
        switch ($query->orderBy) {
191
            case 'commonName':
192
                $queryBuilder->orderBy('r.commonName', $orderDirection);
193
                break;
194
            default:
195
                throw new RuntimeException(sprintf('Unknown order by column "%s"', $query->orderBy));
196
        }
197
198
        return $queryBuilder->getQuery();
199
    }
200
201
    /**
202
     * @param RaListingQuery $query
203
     * @return \Doctrine\ORM\Query
204
     */
205
    public function createOptionsQuery(RaListingQuery $query)
206
    {
207
        $queryBuilder = $this->createQueryBuilder('r')
208
            ->select('r.institution, r.raInstitution')
209
            ->groupBy('r.institution, r.raInstitution');
210
211
        // Modify query to filter on authorization:
212
        // For the RA listing we want identities that are already RA. Because we then need to look at the use_raa's
213
        // we have to look at the RA-institutions because that's the institution the user is RA for and we should use
214
        // those RA's. Hence the 'r.raInstitution'.
215
        $this->authorizationRepositoryFilter->filter(
216
            $queryBuilder,
217
            $query->authorizationContext,
218
            'r.raInstitution',
219
            'iac'
220
        );
221
222
        return $queryBuilder->getQuery();
223
    }
224
225
    /**
226
     * @param Institution $raInstitution
227
     * @return ArrayCollection
228
     */
229
    public function listRasFor(Institution $raInstitution)
230
    {
231
        $listings = $this->createQueryBuilder('rl')
232
            ->where('rl.raInstitution = :institution')
233
            ->setParameter('institution', $raInstitution)
234
            ->getQuery()
235
            ->getResult();
236
237
        return new ArrayCollection($listings);
238
    }
239
240
    /**
241
     * @param IdentityId $identityId
242
     * @return void
243
     */
244 View Code Duplication
    public function removeByIdentityId(IdentityId $identityId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
245
    {
246
        $this->getEntityManager()->createQueryBuilder()
247
            ->delete($this->_entityName, 'ral')
248
            ->where('ral.identityId = :identityId')
249
            ->andWhere('ral.raInstitution = :institution')
250
            ->setParameter('identityId', $identityId->getIdentityId())
251
            ->getQuery()
252
            ->execute();
253
    }
254
255
    /**
256
     * @param IdentityId $identityId
257
     * @param Institution $raInstitution
258
     * @return void
259
     */
260 View Code Duplication
    public function removeByIdentityIdAndRaInstitution(IdentityId $identityId, Institution $raInstitution)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
261
    {
262
        $this->getEntityManager()->createQueryBuilder()
263
            ->delete($this->_entityName, 'ral')
264
            ->where('ral.identityId = :identityId')
265
            ->andWhere('ral.raInstitution = :institution')
266
            ->setParameter('identityId', $identityId->getIdentityId())
267
            ->setParameter('institution', $raInstitution)
268
            ->getQuery()
269
            ->execute();
270
    }
271
272
    /**
273
     * @param IdentityId $identityId
274
     * @param Institution $institution
275
     * @return void
276
     */
277 View Code Duplication
    public function removeByIdentityIdAndInstitution(IdentityId $identityId, Institution $institution)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
278
    {
279
        $this->getEntityManager()->createQueryBuilder()
280
            ->delete($this->_entityName, 'ral')
281
            ->where('ral.identityId = :identityId')
282
            ->andWhere('ral.institution = :institution')
283
            ->setParameter('identityId', $identityId->getIdentityId())
284
            ->setParameter('institution', $institution)
285
            ->getQuery()
286
            ->execute();
287
    }
288
}
289