Issues (232)

app/User.php (1 issue)

1
<?php
2
3
namespace App;
4
5
use App\Exceptions\NotOwningAssociationException;
6
use App\Exceptions\NotOwningClubException;
7
use App\Exceptions\NotOwningFederationException;
8
use App\Traits\RoleTrait;
9
use Cviebrock\EloquentSluggable\Sluggable;
10
use Illuminate\Auth\Access\AuthorizationException;
11
use Illuminate\Auth\Authenticatable;
12
use Illuminate\Auth\Passwords\CanResetPassword;
13
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
14
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
15
use Illuminate\Database\Eloquent\Builder;
16
use Illuminate\Database\Eloquent\Model;
17
use Illuminate\Database\Eloquent\SoftDeletes;
18
use Illuminate\Foundation\Auth\Access\Authorizable;
19
use Illuminate\Notifications\Notifiable;
20
use Illuminate\Support\Collection;
21
use Lab404\Impersonate\Models\Impersonate;
22
use Laravel\Passport\HasApiTokens;
23
use OwenIt\Auditing\Contracts\Auditable;
24
use Thomaswelton\LaravelGravatar\Facades\Gravatar;
25
26
/**
27
 * @property  mixed name
28
 * @property  mixed email
29
 * @property  mixed password
30
 * @property bool verified
31
 * @property mixed token
32
 * @property  mixed clearPassword
33
 * @property string firstname
34
 * @property string lastname
35
 * @property Federation federationOwned
36
 * @property Association associationOwned
37
 * @property Club clubOwned
38
 * @property int id
39
 */
40
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, Auditable
41
{
42
    use Authenticatable, Authorizable, CanResetPassword, SoftDeletes, Sluggable, Notifiable, HasApiTokens, Impersonate, RoleTrait, \OwenIt\Auditing\Auditable;
43
44
    /**
45
     * The database table used by the model.
46
     *
47
     * @var string
48
     */
49
    protected $table = 'users';
50
    protected $dates = ['created_at', 'updated_at', 'deleted_at'];
51
    /**
52
     * The attributes that are mass assignable.
53
     *
54
     * @var array
55
     */
56
    protected $guarded = ['id', 'password_confirmation'];
57
    /**
58
     * The attributes excluded from the model's JSON form.
59
     *
60
     * @var array
61
     */
62
    protected $hidden = ['password', 'remember_token'];
63
64
    /**
65
     * Boot the model.
66
     *
67
     * @return void
68
     */
69 52
    public static function boot()
70
    {
71 52
        parent::boot();
72 52
        static::creating(function ($user) {
73 51
            $softDeletedUser = User::onlyTrashed()->where('email', '=', $user->email)->first();
74 51
            if ($softDeletedUser != null) {
75
                $softDeletedUser->restore();
76
                return false;
77
            }
78 51
            $user->token = str_random(30);
79 51
            if ($user->country_id == 0) {
80 50
                $user->addGeoData();
81
            }
82 51
            return true;
83 52
        });
84
85
        // If a User is deleted, you must delete:
86
        // His tournaments, his competitors
87
88 52
        static::deleting(function ($user) {
89 2
            $user->tournaments->each->delete();
90 2
            $user->competitors->each->delete();
91
92 52
        });
93 52
        static::restoring(function ($user) {
94
            $user->competitors()->withTrashed()->get()->each->restore();
95
            $user->tournaments()->withTrashed()->get()->each->restore();
96 52
        });
97 52
    }
98
99
    /**
100
     * Return the sluggable configuration array for this model.
101
     *
102
     * @return array
103
     */
104 51
    public function sluggable()
105
    {
106
        return [
107 51
            'slug' => [
108
                'source' => 'email'
109
            ]
110
        ];
111
    }
112
113
    /**
114
     * @return string
115
     */
116 8
    public function getRouteKeyName()
117
    {
118 8
        return 'slug';
119
    }
120
121
    /**
122
     * Add geoData based on IP
123
     */
124 50
    public function addGeoData()
125
    {
126 50
        $ip = request()->ip();
127 50
        $location = geoip($ip);
128 50
        $country = Country::where('name', '=', $location->country)->first();
0 ignored issues
show
The property country does not seem to exist on Torann\GeoIP\GeoIP.
Loading history...
129 50
        if (is_null($country)) {
130 50
            $this->country_id = config('constants.COUNTRY_ID_DEFAULT');
131 50
            $this->city = "Paris";
132 50
            $this->latitude = 48.858222;
133 50
            $this->longitude = 2.2945;
134 50
            return;
135
        }
136
        $this->country_id = $country->id;
137
        $this->city = $location['city'];
138
        $this->latitude = $location['lat'];
139
        $this->longitude = $location['lon'];
140
    }
141
142
    /**
143
     * Confirm the user.
144
     *
145
     * @return void
146
     */
147 1
    public function confirmEmail()
148
    {
149 1
        $this->verified = true;
150 1
        $this->token = null;
151 1
        $this->save();
152 1
    }
153
154
    /**
155
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
156
     */
157 1
    public function grade()
158
    {
159 1
        return $this->belongsTo('App\Grade');
160
    }
161
162
    /**
163
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
164
     */
165 1
    public function role()
166
    {
167 1
        return $this->belongsTo('App\Role');
168
    }
169
170
    /**
171
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
172
     */
173
    public function settings()
174
    {
175
        return $this->hasOne('App\Settings');
176
    }
177
178
    /**
179
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
180
     */
181 18
    public function invites()
182
    {
183 18
        return $this->hasMany('App\Invite', 'email', 'email');
184
    }
185
186
    /**
187
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
188
     */
189 5
    public function country()
190
    {
191 5
        return $this->belongsTo('Webpatser\Countries\Countries');
192
    }
193
194
    /**
195
     * Get all user's created (owned) tournmanents
196
     *
197
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
198
     */
199 18
    public function tournaments()
200
    {
201 18
        return $this->hasMany('App\Tournament');
202
    }
203
204
    /**
205
     * Get all deleted user's tournmanents
206
     *
207
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
208
     */
209 18
    public function tournamentsDeleted()
210
    {
211 18
        return $this->hasMany('App\Tournament')->onlyTrashed();
212
    }
213
214
    /**
215
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
216
     */
217 3
    public function championships()
218
    {
219 3
        return $this->belongsToMany(Championship::class, 'competitor')
220 3
            ->withTimestamps();
221
    }
222
223
    /**
224
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
225
     */
226
    public function federation()
227
    {
228
        return $this->belongsTo(Federation::class);
229
    }
230
231
    /**
232
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
233
     */
234
    public function association()
235
    {
236
        return $this->belongsTo(Association::class);
237
    }
238
239
    /**
240
     * A president of federation owns a federation
241
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
242
     */
243 4
    public function federationOwned()
244
    {
245 4
        return $this->belongsTo(Federation::class, 'id', 'president_id');
246
    }
247
248
    /**
249
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
250
     */
251 5
    public function associationOwned()
252
    {
253 5
        return $this->belongsTo(Association::class, 'id', 'president_id');
254
    }
255
256
    /**
257
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
258
     */
259 4
    public function clubOwned()
260
    {
261 4
        return $this->belongsTo(Club::class, 'id', 'president_id');
262
    }
263
264
265
    /**
266
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
267
     */
268
    public function club()
269
    {
270
        return $this->belongsTo(Club::class);
271
    }
272
273
    /**
274
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
275
     */
276 2
    public function competitors() // Used to delete competitors when soft deleting
277
    {
278 2
        return $this->hasMany(Competitor::class);
279
    }
280
281
    /**
282
     * Tournament where I have participated as competitor
283
     * @return mixed
284
     */
285 1
    public function myTournaments()
286
    {
287 1
        return Tournament::leftJoin('championship', 'championship.tournament_id', '=', 'tournament.id')
288 1
            ->leftJoin('competitor', 'competitor.championship_id', '=', 'championship.id')
289 1
            ->where('competitor.user_id', '=', $this->id)
290 1
            ->select('tournament.*')
291 1
            ->distinct();
292
    }
293
294
295
    /**
296
     * @return bool
297
     */
298 2
    public function isDeleted()
299
    {
300 2
        return $this->deleted_at != null;
301
    }
302
303
    /**
304
     * @param $firstname
305
     * @param $lastname
306
     */
307 1
    public function updateUserFullName($firstname, $lastname)
308
    {
309 1
        $this->firstname = $firstname;
310 1
        $this->lastname = $lastname;
311 1
        $this->save();
312 1
    }
313
314
    /**
315
     * @return Collection
316
     */
317 2
    public function fillSelect()
318
    {
319 2
        return User::forUser($this)
320 2
            ->pluck('name', 'id')
321 2
            ->prepend('-', 0);
322
    }
323
324
    /**
325
     * Check if a user is registered to a tournament
326
     * @param Tournament $tournament
327
     * @return bool
328
     */
329
    public function isRegisteredTo(Tournament $tournament)
330
    {
331
        $ids = $tournament->championships->pluck('id');
332
        $isRegistered = Competitor::where('user_id', $this->id)
333
            ->whereIn('championship_id', $ids)
334
            ->get();
335
336
        return sizeof($isRegistered) > 0;
337
    }
338
339
    /**
340
     * @return bool
341
     */
342
    public function canImpersonate()
343
    {
344
        return $this->isSuperAdmin();
345
    }
346
347
    /**
348
     * @return bool
349
     */
350
    public function canBeImpersonated()
351
    {
352
        return $this->isSuperAdmin();
353
    }
354
355
356
    /**
357
     * @return string
358
     */
359
    public function getFullName()
360
    {
361
        return $this->firstname ?? '' . " " . $this->lastname ?? '';
362
    }
363
364
    /**
365
     * @param $query
366
     * @param User $user
367
     * @return Builder
368
     * @throws AuthorizationException
369
     * @throws NotOwningAssociationException
370
     * @throws NotOwningClubException
371
     * @throws NotOwningFederationException
372
     */
373 3
    public function scopeForUser($query, User $user)
374
    {
375
        // If user manage a structure, he will be limited to see entity of this structure
376
        // If user has the role but manage no structure --> AuthorizationException
377
        switch (true) {
378 3
            case $user->isSuperAdmin():
379 1
                return $query;
380 2
            case $user->isFederationPresident() && $user->federationOwned != null:
381
                return $query->federationPresident($user);
382 2
            case $user->isAssociationPresident() && $user->associationOwned:
383 1
                return $query->associationPresident($user);
384 1
            case $user->isClubPresident() && $user->clubOwned != null:
385 1
                return $query->clubPresident($user);
386
            case $user->isFederationPresident() && !$user->federationOwned != null:
387
                throw new NotOwningFederationException();
388
            case $user->isAssociationPresident() && !$user->associationOwned:
389
                throw new NotOwningAssociationException();
390
            case $user->isClubPresident() && $user->clubOwned == null:
391
                throw new NotOwningClubException();
392
            default:
393
                throw new AuthorizationException();
394
        }
395
    }
396
397
    public function scopeFederationPresident($query, User $user)
398
    {
399
        return $query->where('federation_id', '=', $user->federationOwned->id);
400
    }
401
402 1
    public function scopeAssociationPresident($query, User $user)
403
    {
404 1
        return $query->where('association_id', '=', $user->associationOwned->id);
405
    }
406
407 1
    public function scopeClubPresident($query, User $user)
408
    {
409 1
        return $query->where('club_id', '=', $user->clubOwned->id);
410
    }
411
412
413 29
    public function getAvatarAttribute($avatar)
414
    {
415
        
416 29
        if (internet_connected() && !isset($avatar) && Gravatar::exists($this->email)) {
417
            return Gravatar::src($this->email);
418
419
        }
420
421 29
        if (!str_contains($avatar, 'http') && isset($avatar)) {
422
            return asset(config('constants.AVATAR_PATH') . $avatar);
423
        }
424 29
        return $avatar;
425
    }
426
}
427