*/ protected $fillable = [ 'name', 'email', 'notification_email', 'phone', 'password', 'role', 'role_id', 'color', 'token_fcm', ]; /** * The attributes that should be hidden for serialization. * * @var list */ protected $hidden = [ 'password', 'remember_token', ]; /** * Get the attributes that should be cast. * * @return array */ protected function casts(): array { return [ 'email_verified_at' => 'datetime', 'password' => 'hashed', ]; } /** * Route notifications for the FCM channel. * * @return string */ public function routeNotificationForFcm(): string { return (string)$this->token_fcm; } public function getAppInstalledAttribute(): string { return $this->token_fcm ? 'Да' : 'Нет'; } public function userNotifications(): HasMany { return $this->hasMany(UserNotification::class); } public function unreadUserNotifications(): HasMany { return $this->userNotifications()->whereNull('read_at'); } public function roleModel(): BelongsTo { return $this->belongsTo(Role::class, 'role_id'); } public function permissions(): BelongsToMany { return $this->belongsToMany(Permission::class, 'user_permissions') ->withPivot(['effect', 'reason', 'expires_at']) ->withTimestamps(); } public function scopeWithPermission(Builder $query, string $permission): Builder { return $query->where(function (Builder $query) use ($permission): void { $query ->whereHas('roleModel.permissions', function (Builder $query) use ($permission): void { $query ->where('slug', $permission) ->where('role_permissions.effect', 'allow'); }) ->orWhereExists(function ($query) use ($permission): void { $query ->selectRaw('1') ->from('roles') ->join('role_permissions', 'role_permissions.role_id', '=', 'roles.id') ->join('permissions', 'permissions.id', '=', 'role_permissions.permission_id') ->whereColumn('roles.slug', 'users.role') ->where('permissions.slug', $permission) ->where('role_permissions.effect', 'allow'); }) ->orWhereHas('permissions', function (Builder $query) use ($permission): void { $query ->where('slug', $permission) ->where('user_permissions.effect', 'allow') ->where(function (Builder $query): void { $query ->whereNull('user_permissions.expires_at') ->orWhere('user_permissions.expires_at', '>', now()); }); }); }); } public function scopeWithAnyPermission(Builder $query, array|string $permissions): Builder { $permissions = is_array($permissions) ? $permissions : explode(',', $permissions); $permissions = array_filter(array_map('trim', $permissions)); return $query->where(function (Builder $query) use ($permissions): void { foreach ($permissions as $permission) { $query->orWhere(fn (Builder $query): Builder => $query->withPermission($permission)); } }); } public function hasRole(string|array $roles): bool { $roles = is_array($roles) ? $roles : explode(',', $roles); $roles = array_map('trim', $roles); $role = $this->resolvedRoleSlug(); if (!$role) { return false; } return count(array_intersect($roles, Role::effectiveRoles($role))) > 0; } public function hasPermission(string $permission): bool { return app(\App\Services\Access\AccessService::class)->can($this, $permission); } public function hasAnyPermission(array|string $permissions): bool { $permissions = is_array($permissions) ? $permissions : explode(',', $permissions); return app(\App\Services\Access\AccessService::class)->canAny($this, $permissions); } public function visibilityScope(string $module): ?string { return app(\App\Services\Access\AccessService::class)->visibilityScope($this, $module); } public function hasVisibilityScope(string $module, string $scope): bool { return app(\App\Services\Access\AccessService::class)->hasVisibilityScope($this, $module, $scope); } public function canViewField(string $module, string $field, ?string $entity = null): bool { return app(\App\Services\Access\AccessService::class)->canViewField($this, $module, $field, $entity); } public function canUpdateField(string $module, string $field, ?string $entity = null): bool { return app(\App\Services\Access\AccessService::class)->canUpdateField($this, $module, $field, $entity); } public function getEffectivePermissions(): \Illuminate\Support\Collection { return app(\App\Services\Access\AccessService::class)->getEffectivePermissions($this); } public function resolvedRoleSlug(): ?string { if ($this->getAttribute('role_id')) { $role = $this->relationLoaded('roleModel') ? $this->roleModel : $this->roleModel()->first(); if ($role) { return $role->slug; } } return $this->role; } public static function assignUniqueFcmToken(int $userId, string $token): void { DB::transaction(function () use ($userId, $token) { self::query() ->where('id', '!=', $userId) ->where('token_fcm', $token) ->update(['token_fcm' => null]); self::query() ->where('id', $userId) ->update(['token_fcm' => $token]); }); } public static function clearFcmToken(int $userId): void { self::query() ->where('id', $userId) ->update(['token_fcm' => null]); } }