SOA/laravel/app/Models/User.php
2025-06-18 23:49:55 +02:00

199 lines
5.2 KiB
PHP

<?php
namespace App\Models;
use database\GalleryMember;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'username',
'email',
'alias',
'password_hash',
'first_name',
'last_name',
'bio',
'profile_picture_url'
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password_hash',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'created_at' => 'datetime',
'updated_at' => 'datetime',
];
/**
* Get the password for the user (Laravel Auth compatibility).
*/
public function getAuthPassword()
{
return $this->password_hash;
}
/**
* Set the password hash when setting password.
*/
public function setPasswordAttribute($password)
{
$this->attributes['password_hash'] = bcrypt($password);
}
/**
* Get the user's full name.
*/
public function getFullNameAttribute(): string
{
return trim($this->first_name . ' ' . $this->last_name);
}
/**
* Scope pour rechercher par nom d'utilisateur ou email.
*/
public function scopeSearch($query, $search)
{
return $query->where('username', 'like', "%{$search}%")
->orWhere('email', 'like', "%{$search}%")
->orWhere('first_name', 'like', "%{$search}%")
->orWhere('last_name', 'like', "%{$search}%");
}
// ===== RELATIONS =====
/**
* Galeries possédées par cet utilisateur.
*/
public function ownedGalleries()
{
return $this->hasMany(Gallery::class, 'owner_id');
}
/**
* Œuvres créées par cet utilisateur.
*/
public function artworks()
{
return $this->hasMany(Artwork::class, 'creator_id');
}
/**
* Galeries auxquelles cet utilisateur a accès (invitations).
*/
public function galleryMemberships()
{
return $this->hasMany(GalleryMember::class, 'user_id');
}
/**
* Galeries auxquelles l'utilisateur a accès avec statut accepté.
*/
public function accessibleGalleries()
{
return $this->belongsToMany(Gallery::class, 'gallery_members', 'user_id', 'gallery_id')
->wherePivot('status', 'accepted')
->withPivot(['role', 'status', 'invited_at', 'updated_at']);
}
/**
* Invitations en attente pour cet utilisateur.
*/
public function pendingInvitations()
{
return $this->belongsToMany(Gallery::class, 'gallery_members', 'user_id', 'gallery_id')
->wherePivot('status', 'pending')
->withPivot(['role', 'status', 'invited_at', 'updated_at']);
}
/**
* Vérifier si l'utilisateur peut accéder à une galerie.
*/
public function canAccessGallery($galleryId): bool
{
// Propriétaire de la galerie
if ($this->ownedGalleries()->where('id', $galleryId)->exists()) {
return true;
}
// Membre avec accès accepté
return $this->galleryMemberships()
->where('gallery_id', $galleryId)
->where('status', 'accepted')
->exists();
}
/**
* Vérifier si l'utilisateur peut éditer une galerie.
*/
public function canEditGallery($galleryId): bool
{
// Propriétaire
if ($this->ownedGalleries()->where('id', $galleryId)->exists()) {
return true;
}
// Membre avec rôle editor
return $this->galleryMemberships()
->where('gallery_id', $galleryId)
->where('status', 'accepted')
->where('role', 'editor')
->exists();
}
/**
* Obtenir le rôle de l'utilisateur dans une galerie.
*/
public function getRoleInGallery($galleryId): ?string
{
// Propriétaire
if ($this->ownedGalleries()->where('id', $galleryId)->exists()) {
return 'owner';
}
// Membre
$membership = $this->galleryMemberships()
->where('gallery_id', $galleryId)
->where('status', 'accepted')
->first();
return $membership ? $membership->role : null;
}
/**
* Statistiques de l'utilisateur.
*/
public function getStatsAttribute(): array
{
return [
'galleries_count' => $this->ownedGalleries()->count(),
'artworks_count' => $this->artworks()->count(),
'public_galleries_count' => $this->ownedGalleries()->where('is_public', true)->count(),
'artworks_for_sale_count' => $this->artworks()->where('is_for_sale', true)->count(),
];
}
}