Passed
Pull Request — develop (#11)
by
unknown
07:48 queued 03:43
created

Student::leave()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Judite\Models;
4
5
use Illuminate\Database\Eloquent\Model;
6
use App\Exceptions\EnrollmentCannotBeDeleted;
7
use App\Exceptions\UserHasAlreadyGroupInCourseException;
8
use App\Exceptions\StudentIsNotEnrolledInCourseException;
9
use App\Exceptions\UserIsAlreadyEnrolledInCourseException;
10
11
class Student extends Model
12
{
13
    /**
14
     * The relations to eager load on every query.
15
     *
16
     * @var array
17
     */
18
    protected $with = ['user'];
19
20
    /**
21
     * The attributes that are mass assignable.
22
     *
23
     * @var array
24
     */
25
    protected $fillable = ['student_number'];
26
27
    /**
28
     * Get user who owns this student.
29
     *
30
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
31
     */
32
    public function user()
33
    {
34
        return $this->belongsTo(User::class);
35
    }
36
37
    /**
38
     * Get exchanges requested by this student.
39
     *
40
     * @return \Illuminate\Database\Eloquent\Builder
41
     */
42
    public function requestedExchanges()
43
    {
44
        $enrollmentsRelationship = $this->enrollments();
45
        $enrollmentsKeyName = $enrollmentsRelationship->getRelated()->getKeyName();
46
        $enrollmentsIdsQuery = $enrollmentsRelationship
47
            ->select($enrollmentsKeyName)
48
            ->getBaseQuery();
49
50
        return Exchange::whereFromEnrollmentIn($enrollmentsIdsQuery);
51
    }
52
53
    /**
54
     * Get exchanges proposed to this student.
55
     *
56
     * @return \Illuminate\Database\Eloquent\Builder
57
     */
58
    public function proposedExchanges()
59
    {
60
        $enrollmentsRelationship = $this->enrollments();
61
        $enrollmentsKeyName = $enrollmentsRelationship->getRelated()->getKeyName();
62
        $enrollmentsIdsQuery = $enrollmentsRelationship
63
            ->select($enrollmentsKeyName)
64
            ->getBaseQuery();
65
66
        return Exchange::whereToEnrollmentIn($enrollmentsIdsQuery);
67
    }
68
69
    /**
70
     * Get enrollments of this student.
71
     *
72
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
73
     */
74
    public function enrollments()
75
    {
76
        return $this->hasMany(Enrollment::class);
77
    }
78
79
    /**
80
     * Get enrollment of this student in a given course.
81
     *
82
     * @param \App\Judite\Models\Course $course
83
     *
84
     * @return \App\Judite\Models\Enrollment|null
85
     */
86
    public function getEnrollmentInCourse(Course $course)
87
    {
88
        return $this->enrollments()
89
            ->where('course_id', $course->id)
90
            ->first();
91
    }
92
93
    /**
94
     * Enroll this student with a given course.
95
     *
96
     * @param \App\Judite\Models\Course $course
97
     *
98
     * @throws \App\Exceptions\UserIsAlreadyEnrolledInCourseException
99
     *
100
     * @return \App\Judite\Models\Enrollment
101
     */
102
    public function enroll(Course $course): Enrollment
103
    {
104
        if ($this->isEnrolledInCourse($course)) {
105
            throw new UserIsAlreadyEnrolledInCourseException($course);
106
        }
107
108
        $enrollment = $this->enrollments()->make();
109
        $enrollment->course()->associate($course);
110
        $enrollment->save();
111
112
        return $enrollment;
113
    }
114
115
    /**
116
     * Check if this student is enrolled in a course.
117
     *
118
     * @param \App\Judite\Models\Course $course
119
     *
120
     * @return bool
121
     */
122
    public function isEnrolledInCourse(Course $course): bool
123
    {
124
        return $this->enrollments()->where('course_id', $course->id)->exists();
125
    }
126
127
    /**
128
     * Remove enrollment in the given course.
129
     *
130
     * @param \App\Judite\Models\Course $course
131
     *
132
     * @throws \App\Exceptions\StudentIsNotEnrolledInCourseException|\App\Exceptions\EnrollmentCannotBeDeleted
133
     *
134
     * @return bool
135
     */
136
    public function unenroll(Course $course): bool
137
    {
138
        $enrollment = $this->getEnrollmentInCourse($course);
139
140
        if (is_null($enrollment)) {
141
            throw new StudentIsNotEnrolledInCourseException($course);
142
        }
143
144
        if (! ($enrollment->isDeletable())) {
145
            throw new EnrollmentCannotBeDeleted($enrollment);
146
        }
147
148
        return $enrollment->delete();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $enrollment->delete() could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
149
    }
150
151
    /**
152
     * Scope a query to only include users with the given student number.
153
     *
154
     * @param \Illuminate\Database\Eloquent\Builder $query
155
     * @param string                                $studentNumber
156
     *
157
     * @return \Illuminate\Database\Eloquent\Builder
158
     */
159
    public function scopeWhereNumber($query, $studentNumber)
160
    {
161
        return $query->where('student_number', $studentNumber);
162
    }
163
164
    /**
165
     * Get memberships of this student.
166
     *
167
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
168
     */
169
    public function memberships()
170
    {
171
        return $this->hasMany(Membership::class);
172
    }
173
174
    /**
175
     * Make this student member of a given group.
176
     *
177
     * @param \App\Judite\Models\Group $group
178
     *
179
     * @throws \App\Exceptions\UserHasAlreadyGroupInCourseException
180
     *
181
     * @return \App\Judite\Models\Group
182
     */
183
    public function join(Group $group): Membership
184
    {
185
        if ($this->isMemberOfGroupInCourse($group->course_id)) {
186
            throw new UserHasAlreadyGroupInCourseException();
187
        }
188
189
        $membership = $this->memberships()->make();
190
        $membership->group()->associate($group);
191
        $membership->course_id = $group->course_id;
192
        $membership->save();
193
194
        return $membership;
195
    }
196
197
    /**
198
     * Check if this student is member of a group in a course.
199
     *
200
     * @param $course_id
201
     *
202
     * @return bool
203
     */
204
    public function isMemberOfGroupInCourse($courseId): bool
205
    {
206
        return $this->memberships()->where('course_id', $courseId)->exists();
207
    }
208
209
    /**
210
     * Remove membership in the given group.
211
     *
212
     * @param \App\Judite\Models\Group $group
213
     *
214
     * @return bool
215
     */
216
    public function leave(Group $group): bool
217
    {
218
        return $this->getMembershipInGroup($group)->delete();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getMembers...Group($group)->delete() could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
219
    }
220
221
    /**
222
     * Get membership of this student in a given course.
223
     *
224
     * @param \App\Judite\Models\Group $group
225
     *
226
     * @return \App\Judite\Models\Membership|null
227
     */
228
    public function getMembershipInGroup(Group $group)
229
    {
230
        return $this->memberships()
231
            ->where('group_id', $group->id)
232
            ->first();
233
    }
234
235
    /**
236
     * Get invitations of this student.
237
     *
238
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
239
     */
240
    public function invitations()
241
    {
242
        return $this->hasMany(Invitation::class);
243
    }
244
}
245