Passed
Push — master ( 2daeaa...eba4a8 )
by Marcel
16:01
created

StudentRepository::remove()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 3
rs 10
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace App\Repository;
4
5
use App\Entity\Grade;
6
use App\Entity\Section;
7
use App\Entity\Student;
8
use App\Entity\StudyGroup;
9
use App\Entity\User;
10
use App\Entity\UserType;
11
use DateTime;
12
use Doctrine\ORM\QueryBuilder;
13 4
use Doctrine\ORM\Tools\Pagination\Paginator;
14 4
15 2
class StudentRepository extends AbstractTransactionalRepository implements StudentRepositoryInterface {
16 2
17 2
    private function getDefaultQueryBuilder(bool $simple = false): QueryBuilder {
18 2
        if($simple === true) {
19
            return $this->em->createQueryBuilder()
20
                ->select(['s', 'gm', 'sec'])
21 2
                ->from(Student::class, 's')
22 2
                ->leftJoin('s.gradeMemberships', 'gm')
23 2
                ->leftJoin('s.sections', 'sec');
24 2
        }
25 2
26 2
        return $this->em->createQueryBuilder()
27 2
            ->select(['s', 'gm', 'sgm', 'sg', 'sgg', 'sec'])
28
            ->from(Student::class, 's')
29
            ->leftJoin('s.gradeMemberships', 'gm')
30
            ->leftJoin('s.studyGroupMemberships', 'sgm')
31
            ->leftJoin('sgm.studyGroup', 'sg')
32
            ->leftJoin('sg.grades', 'sgg')
33
            ->leftJoin('s.sections', 'sec');
34
    }
35
36
    public function findOneById(int $id): ?Student {
37
        return $this->getDefaultQueryBuilder()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDefault...)->getOneOrNullResult() could return the type integer which is incompatible with the type-hinted return App\Entity\Student|null. Consider adding an additional type-check to rule them out.
Loading history...
38
            ->andWhere('s.id = :id')
39
            ->setParameter('id', $id)
40
            ->getQuery()
41
            ->getOneOrNullResult();
42
    }
43
44
    /**
45
     * @inheritDoc
46
     */
47
    public function findOneByUuid(string $uuid): ?Student {
48
        return $this->getDefaultQueryBuilder()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDefault...)->getOneOrNullResult() could return the type integer which is incompatible with the type-hinted return App\Entity\Student|null. Consider adding an additional type-check to rule them out.
Loading history...
49
            ->andWhere('s.uuid = :uuid')
50
            ->setParameter('uuid', $uuid)
51
            ->getQuery()
52
            ->getOneOrNullResult();
53
    }
54
55
    public function findOneByExternalId(string $externalId): ?Student {
56
        return $this->getDefaultQueryBuilder()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDefault...)->getOneOrNullResult() could return the type integer which is incompatible with the type-hinted return App\Entity\Student|null. Consider adding an additional type-check to rule them out.
Loading history...
57
            ->andWhere('s.externalId = :externalId')
58
            ->setParameter('externalId', $externalId)
59
            ->getQuery()
60
            ->getOneOrNullResult();
61
    }
62
63
    public function findOneByEmailAddress(string $email): ?Student {
64
        return $this->getDefaultQueryBuilder()
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDefault...)->getOneOrNullResult() could return the type integer which is incompatible with the type-hinted return App\Entity\Student|null. Consider adding an additional type-check to rule them out.
Loading history...
65
            ->andWhere('s.email = :email')
66
            ->setParameter('email', $email)
67
            ->getQuery()
68
            ->getOneOrNullResult();
69
    }
70
71
    /**
72
     * @inheritDoc
73
     */
74
    public function findAllByGrade(Grade $grade, Section $section): array {
75
        return $this->getQueryBuilderFindAllByGrade($grade, $section)
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getQueryBu...getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
76
            ->getQuery()
77
            ->getResult();
78
    }
79
80
    private function getQueryBuilderFindAllByGrade(Grade $grade, Section $section): QueryBuilder {
81
        return $this->getDefaultQueryBuilder(true)
82
            ->andWhere('gm.grade = :grade')
83
            ->andWhere('gm.section = :section')
84
            ->orderBy('s.lastname')
85
            ->addOrderBy('s.firstname')
86
            ->setParameter('grade', $grade->getId())
87
            ->setParameter('section', $section->getId());
88
    }
89
90
    /**
91
     * @inheritDoc
92
     */
93
    public function findAllByQuery(string $query): array {
94
        $qb = $this->getDefaultQueryBuilder(true);
95
96
        $qbInner = $this->em->createQueryBuilder()
97
            ->select('sInner.id')
98
            ->from(Student::class, 'sInner')
99
            ->where(
100
                $qb->expr()->orX(
101
                    $qb->expr()->like('sInner.firstname', ':query'),
102
                    $qb->expr()->like('sInner.lastname', ':query')
103 2
                )
104 2
            );
105 2
106 2
        $qb
107
            ->andWhere($qb->expr()->in('s.id', $qbInner->getDQL()))
108
            ->setParameter('query', '%' . $query . '%');
109
110
        return $qb->getQuery()->getResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb->getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
111
    }
112 1
113 1
    /**
114 1
     * @return Student[]
115 1
     */
116
    public function findAll() {
117
        return $this->getDefaultQueryBuilder(true)
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDefault...getQuery()->getResult() also could return the type integer which is incompatible with the documented return type App\Entity\Student[].
Loading history...
118
            ->getQuery()
119
            ->getResult();
120
    }
121
122
    /**
123
     * @inheritDoc
124
     */
125
    public function findAllBySection(Section $section): array {
126
        return $this->getDefaultQueryBuilder(true)
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDefault...getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
127
            ->andWhere('sec.id = :section')
128 2
            ->setParameter('section', $section->getId())
129 2
            ->getQuery()
130
            ->getResult();
131 2
    }
132 2
133 2
    public function persist(Student $student): void {
134 2
        $this->em->persist($student);
135 2
        $this->flushIfNotInTransaction();
136
    }
137
138 2
    public function remove(Student $student): void {
139 2
        $this->em->remove($student);
140
        $this->flushIfNotInTransaction();
141 2
    }
142
143
    /**
144
     * @inheritDoc
145
     */
146
    public function findAllByExternalId(array $externalIds): array {
147
        $qb = $this->getDefaultQueryBuilder();
148
149
        $qbInner = $this->em->createQueryBuilder()
150
            ->select('sInner.id')
151
            ->from(Student::class, 'sInner')
152
            ->where($qb->expr()->in('sInner.externalId', ':externalIds'));
153
154
        $qb
155
            ->andWhere($qb->expr()->in('s.id', $qbInner->getDQL()))
156
            ->setParameter('externalIds', $externalIds);
157
158
        return $qb->getQuery()->getResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb->getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
159
    }
160
161
    public function findAllByEmailAddresses(array $emailAddresses): array {
162
        $qb = $this->getDefaultQueryBuilder()
163
            ->andWhere('s.email IN (:emails)')
164
            ->setParameter('emails', $emailAddresses);
165
166
        return $qb->getQuery()->getResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $qb->getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
167
    }
168
169
    /**
170
     * @inheritDoc
171
     */
172
    public function findAllByStudyGroups(array $studyGroups): array {
173
        return $this->getQueryBuilderFindAllByStudyGroups($studyGroups)->getQuery()->getResult();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getQueryBu...getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
174
    }
175
176
    public function findAllByBirthday(DateTime $date): array {
177
        return $this->getDefaultQueryBuilder(true)
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDefault...getQuery()->getResult() could return the type integer which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
178
            ->where('s.birthday LIKE :date')
179
            ->setParameter('date', $date->format('%s-m-d'))
180
            ->getQuery()
181
            ->getResult();
182
    }
183
184
    /**
185
     * @inheritDoc
186
     */
187
    public function getQueryBuilderFindAllByStudyGroups(array $studyGroups): QueryBuilder {
188
        $studyGroupIds = array_map(fn(StudyGroup $studyGroup) => $studyGroup->getId(), $studyGroups);
189
190
        $qb = $this->getDefaultQueryBuilder();
191
192
        $qbInner = $this->em->createQueryBuilder()
193
            ->select('sInner.id')
194
            ->from(Student::class, 'sInner')
195
            ->leftJoin('sInner.studyGroupMemberships', 'sgmInner')
196
            ->where($qb->expr()->in('sgmInner.studyGroup', ':studyGroupIds'));
197
198
        $qb
199
            ->andWhere($qb->expr()->in('s.id', $qbInner->getDQL()))
200
            ->setParameter('studyGroupIds', $studyGroupIds);
201
202
        return $qb;
203
    }
204
205
206
    /**
207
     * @inheritDoc
208
     */
209
    public function removeOrphaned(): int {
210
        $qbOrphaned = $this->em->createQueryBuilder()
211
            ->select('s.id')
212
            ->from(Student::class, 's')
213
            ->leftJoin('s.sections', 'sec')
214
            ->leftJoin('s.gradeMemberships', 'gm')
215
            ->where('sec.id IS NULL')
216
            ->orWhere('gm.id IS NULL');
217
218
        $qb = $this->em->createQueryBuilder();
219
220
        return (int)$qb->delete(Student::class, 'student')
221
            ->where(
222
                $qb->expr()->in('student.id', $qbOrphaned->getDQL())
223
            )
224
            ->getQuery()
225
            ->execute();
226
    }
227
228
    public function getStudentsByGradePaginator(int $itemsPerPage, int &$page, Grade $grade, Section $section): Paginator {
229
        if($page < 1) {
230
            $page = 1;
231
        }
232
233
        $offset = ($page - 1) * $itemsPerPage;
234
235
        $paginator = new Paginator($this->getQueryBuilderFindAllByGrade($grade, $section));
236
        $paginator->getQuery()
237
            ->setMaxResults($itemsPerPage)
238
            ->setFirstResult($offset);
239
240
        return $paginator;
241
    }
242
243
    public function getStudentsByStudyGroupsPaginator(int $itemsPerPage, int &$page, array $studyGroups): Paginator {
244
        if($page < 1) {
245
            $page = 1;
246
        }
247
248
        $offset = ($page - 1) * $itemsPerPage;
249
250
        $paginator = new Paginator($this->getQueryBuilderFindAllByStudyGroups($studyGroups)->orderBy('s.lastname')->addOrderBy('s.firstname'));
251
        $paginator->getQuery()
252
            ->setMaxResults($itemsPerPage)
253
            ->setFirstResult($offset);
254
255
        return $paginator;
256
    }
257
}