Passed
Push — main ( ad8384...b61e7a )
by
unknown
22:06 queued 16:15
created

RaListingRepository::save()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
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
 */
0 ignored issues
show
Coding Style introduced by
Missing @link tag in file comment
Loading history...
18
19
namespace Surfnet\StepupMiddleware\ApiBundle\Identity\Repository;
20
21
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
22
use Doctrine\Common\Collections\ArrayCollection;
23
use Doctrine\ORM\Query;
24
use Doctrine\Persistence\ManagerRegistry;
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
 * @extends ServiceEntityRepository<RaListing>
0 ignored issues
show
Coding Style introduced by
Tag value for @extends tag indented incorrectly; expected 38 spaces but found 1
Loading history...
36
 */
0 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
37
class RaListingRepository extends ServiceEntityRepository
38
{
39
    public function __construct(
40
        ManagerRegistry $registry,
41
        private readonly InstitutionAuthorizationRepositoryFilter $authorizationRepositoryFilter,
42
    ) {
43
        parent::__construct($registry, RaListing::class);
44
    }
45
46
    public function findByIdentityId(IdentityId $identityId): ?array
47
    {
48
        return parent::findBy(['identityId' => (string)$identityId]);
49
    }
50
51
    public function findByIdentityIdAndRaInstitution(IdentityId $identityId, Institution $raInstitution): ?RaListing
52
    {
53
        return parent::findOneBy([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
54
            'identityId' => (string)$identityId,
55
            'raInstitution' => (string)$raInstitution,
56
        ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
57
    }
58
59
    public function findByIdentityIdAndRaInstitutionWithContext(
60
        IdentityId $identityId,
61
        Institution $raInstitution,
62
        InstitutionAuthorizationContextInterface $authorizationContext,
63
    ): ?RaListing {
64
        $queryBuilder = $this->createQueryBuilder('r')
65
            ->where('r.identityId = :identityId')
66
            ->andWhere('r.raInstitution = :raInstitution')
67
            ->setParameter('identityId', $identityId)
68
            ->setParameter('raInstitution', (string)$raInstitution)
69
            ->orderBy('r.raInstitution');
70
71
        // Modify query to filter on authorization:
72
        // For the RA listing we want identities that are already RA. Because we then need to look at the use_raa's
73
        // we have to look at the RA-institutions because that's the institution the user is RA for and we should use
74
        // those RA's. Hence the 'r.raInstitution'.
75
        $this->authorizationRepositoryFilter->filter(
76
            $queryBuilder,
77
            $authorizationContext,
78
            'r.raInstitution',
79
            'iac',
80
        );
81
82
        return $queryBuilder->getQuery()->getOneOrNullResult();
83
    }
84
85
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $institution should have a doc-comment as per coding-style.
Loading history...
Coding Style introduced by
Parameter $identityId should have a doc-comment as per coding-style.
Loading history...
86
     * @return RaListing[]
87
     */
88
    public function findByIdentityIdAndInstitution(IdentityId $identityId, Institution $institution): array
89
    {
90
        return parent::findBy([
0 ignored issues
show
Coding Style introduced by
The opening parenthesis of a multi-line function call should be the last content on the line.
Loading history...
91
            'identityId' => (string)$identityId,
92
            'institution' => (string)$institution,
93
        ]);
0 ignored issues
show
Coding Style introduced by
For multi-line function calls, the closing parenthesis should be on a new line.

If a function call spawns multiple lines, the coding standard suggests to move the closing parenthesis to a new line:

someFunctionCall(
    $firstArgument,
    $secondArgument,
    $thirdArgument
); // Closing parenthesis on a new line.
Loading history...
94
    }
95
96
    public function save(RaListing $raListingEntry): void
97
    {
98
        $this->getEntityManager()->persist($raListingEntry);
99
        $this->getEntityManager()->flush();
100
    }
101
102
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $query should have a doc-comment as per coding-style.
Loading history...
103
     * @SuppressWarnings(PHPMD.CyclomaticComplexity) The amount of if statements do not necessarily make the method
104
     * @SuppressWarnings(PHPMD.NPathComplexity)      below complex or hard to maintain.
105
     */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
106
    public function createSearchQuery(RaListingQuery $query): Query
107
    {
108
        $queryBuilder = $this->createQueryBuilder('r');
109
110
        if ($query->institution) {
111
            $queryBuilder
112
                ->andWhere('r.institution = :institution')
113
                ->setParameter('institution', $query->institution);
114
        }
115
116
        if ($query->identityId instanceof IdentityId) {
117
            $queryBuilder
118
                ->andWhere('r.identityId = :identityId')
119
                ->setParameter('identityId', (string)$query->identityId);
120
        }
121
122
        if ($query->name) {
123
            $queryBuilder
124
                ->andWhere('r.commonName LIKE :name')
125
                ->setParameter('name', sprintf('%%%s%%', $query->name));
126
        }
127
128
        if ($query->email) {
129
            $queryBuilder
130
                ->andWhere('r.email LIKE :email')
131
                ->setParameter('email', sprintf('%%%s%%', $query->email));
132
        }
133
134
        if ($query->role) {
135
            $queryBuilder
136
                ->andWhere('r.role = :role')
137
                ->setParameter('role', (string)$query->role);
138
        }
139
140
        if ($query->raInstitution) {
141
            $queryBuilder
142
                ->andWhere('r.raInstitution = :raInstitution')
143
                ->setParameter('raInstitution', (string)$query->raInstitution);
144
        }
145
146
        // Modify query to filter on authorization:
147
        // For the RA listing we want identities that are already RA. Because we then need to look at the use_raa's
148
        // we have to look at the RA-institutions because that's the institution the user is RA for and we should use
149
        // those RA's. Hence the 'r.raInstitution'.
150
        $this->authorizationRepositoryFilter->filter(
151
            $queryBuilder,
152
            $query->authorizationContext,
153
            'r.raInstitution',
154
            'iac',
155
        );
156
157
        if ($query->orderBy === '' || $query->orderBy === '0') {
158
            return $queryBuilder->getQuery();
159
        }
160
161
        $orderDirection = $query->orderDirection === 'asc' ? 'ASC' : 'DESC';
162
163
        match ($query->orderBy) {
164
            'commonName' => $queryBuilder->orderBy('r.commonName', $orderDirection),
165
            default => throw new RuntimeException(sprintf('Unknown order by column "%s"', $query->orderBy)),
166
        };
167
168
        return $queryBuilder->getQuery();
169
    }
170
171
    public function createOptionsQuery(RaListingQuery $query): Query
172
    {
173
        $queryBuilder = $this->createQueryBuilder('r')
174
            ->select('r.institution, r.raInstitution')
175
            ->groupBy('r.institution, r.raInstitution');
176
177
        // Modify query to filter on authorization:
178
        // For the RA listing we want identities that are already RA. Because we then need to look at the use_raa's
179
        // we have to look at the RA-institutions because that's the institution the user is RA for and we should use
180
        // those RA's. Hence the 'r.raInstitution'.
181
        $this->authorizationRepositoryFilter->filter(
182
            $queryBuilder,
183
            $query->authorizationContext,
184
            'r.raInstitution',
185
            'iac',
186
        );
187
188
        return $queryBuilder->getQuery();
189
    }
190
191
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $raInstitution should have a doc-comment as per coding-style.
Loading history...
192
     * @return ArrayCollection<RaListing>
193
     */
194
    public function listRasFor(Institution $raInstitution): ArrayCollection
195
    {
196
        $listings = $this->createQueryBuilder('rl')
197
            ->where('rl.raInstitution = :institution')
198
            ->setParameter('institution', $raInstitution)
199
            ->getQuery()
200
            ->getResult();
201
202
        return new ArrayCollection($listings);
203
    }
204
205
    public function removeByIdentityId(IdentityId $identityId, Institution $institution): void
206
    {
207
        $this->getEntityManager()->createQueryBuilder()
208
            ->delete($this->getEntityName(), 'ral')
209
            ->where('ral.identityId = :identityId')
210
            ->andWhere('ral.raInstitution = :institution')
211
            ->setParameter('identityId', $identityId->getIdentityId())
212
            ->setParameter('institution', $institution->getInstitution())
213
            ->getQuery()
214
            ->execute();
215
    }
216
217
    public function removeByIdentityIdAndRaInstitution(IdentityId $identityId, Institution $raInstitution): void
218
    {
219
        $this->getEntityManager()->createQueryBuilder()
220
            ->delete($this->getEntityName(), 'ral')
221
            ->where('ral.identityId = :identityId')
222
            ->andWhere('ral.raInstitution = :institution')
223
            ->setParameter('identityId', $identityId->getIdentityId())
224
            ->setParameter('institution', $raInstitution)
225
            ->getQuery()
226
            ->execute();
227
    }
228
229
    public function removeByIdentityIdAndInstitution(IdentityId $identityId, Institution $institution): void
230
    {
231
        $this->getEntityManager()->createQueryBuilder()
232
            ->delete($this->getEntityName(), 'ral')
233
            ->where('ral.identityId = :identityId')
234
            ->andWhere('ral.institution = :institution')
235
            ->setParameter('identityId', $identityId->getIdentityId())
236
            ->setParameter('institution', $institution)
237
            ->getQuery()
238
            ->execute();
239
    }
240
241
    public function contains(IdentityId $identityId): bool
242
    {
243
        return count(parent::findBy(['identityId' => (string)$identityId])) > 0;
244
    }
245
}
246