HEX
Server: nginx/1.24.0
System: Linux localhost 5.15.0-46-generic #49-Ubuntu SMP Thu Aug 4 18:03:25 UTC 2022 x86_64
User: www (1000)
PHP: 8.3.27
Disabled: passthru,exec,system,putenv,chroot,chgrp,chown,shell_exec,popen,proc_open,pcntl_exec,ini_alter,ini_restore,dl,openlog,syslog,readlink,symlink,popepassthru,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,imap_open,apache_setenv
Upload Files
File: /www/wwwroot/erp.nhatnamsst.com/domains/Admin/Models/Admin.php
<?php

namespace Domains\Admin\Models;

use Domains\Admin\Observers\AdminObserver;
use Domains\Admin\Supports\Authorization\AccessRoute;
use Domains\Brand\Models\Brand;
use Domains\Core\Enums\AdminRole;
use Domains\Core\Enums\Gender;
use Domains\Core\Traits\ModelTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Attributes\ObservedBy;
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\Attribute;

#[ObservedBy([AdminObserver::class])]
class Admin extends Authenticatable
{
    use HasFactory, Notifiable, AccessRoute, ModelTrait;

    /**
     * The attributes that are mass assignable.
     *
     * @var array<int, string>
     */
    protected $fillable = [
        'code',
        'username',
        'fullname',
        'phone',
        'email',
        'birthday',
        'gender',
        'avatar',
        'status',
        'birthday',
        'is_superadmin',
        'role',
        'password',
        'access_route_names',
        'team_id',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array<int, string>
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * Get the attributes that should be cast.
     *
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'is_superadmin' => 'boolean',
            'email_verified_at' => 'datetime',
            'password' => 'hashed',
            'access_route_names' => AsArrayObject::class,
            'gender' => Gender::class,
            'role' => AdminRole::class
        ];
    }

    protected function fullname(): Attribute
    {
        return Attribute::make(
            get: fn (mixed $value, array $attributes) => $attributes['fullname'] ?: $attributes['username'] ?: $attributes['email']
        );
    }

    protected function avatar(): Attribute
    {
        return Attribute::make(
            get: fn (string|null $value = null) => asset($value ?: config('core.images.avatar'))
        );
    }

    public function getRoleNames()
    {
        if($this->checkIsSuperAdmin())
        {
            return trans('Super Admin');
        }

        if($this->role) {
            return $this->role->description();
        }

        return '';
    }

    public function isSaleOrLeaderSale(): bool
    {
        if (!$this->role) {
            return false;
        }

        return $this->role === AdminRole::SALE || $this->role === AdminRole::LEADER_SALE;
    }

    public function isAdmin(): bool
    {
        if (!$this->role) {
            return false;
        }

        return $this->role === AdminRole::ADMIN || $this->checkIsSuperAdmin();
    }

    public function isInterOrLeaderInter(): bool
    {
        if (!$this->role) {
            return false;
        }

        return $this->role === AdminRole::INTER || $this->role === AdminRole::LEADER_INTER;
    }

    public function isLeaderOrAbove(): bool
    {
        if ($this->checkIsSuperAdmin()) {
            return true;
        }

        if (!$this->role) {
            return false;
        }

        return in_array($this->role, [
            AdminRole::ADMIN,
            AdminRole::LEADER_SALE,
            AdminRole::LEADER_INTER
        ]);
    }

    public function brands(): BelongsToMany
    {
        return $this->belongsToMany(Brand::class, 'brand_admin', 'admin_id', 'brand_id')
            ->withTimestamps();
    }

    /**
     * Get the team this admin belongs to (as a member)
     */
    public function team(): BelongsTo
    {
        return $this->belongsTo(Team::class);
    }

    /**
     * Get the team this admin leads (as a leader)
     */
    public function ledTeam(): HasOne
    {
        return $this->hasOne(Team::class, 'leader_id');
    }

    /**
     * Get team members (if this admin is a leader)
     */
    public function getTeamMembers()
    {
        $team = $this->ledTeam;
        if ($team) {
            return $team->members;
        }
        return collect();
    }

    /**
     * Get all team member IDs (including self if leader)
     */
    public function getTeamMemberIds(): array
    {
        if ($this->role === AdminRole::LEADER_SALE || $this->role === AdminRole::LEADER_INTER) {
            // Load relationship if not already loaded
            if (!$this->relationLoaded('ledTeam')) {
                $this->load('ledTeam.members');
            }
            $team = $this->ledTeam;
            if ($team) {
                return $team->getMemberIds();
            }
        }
        return [$this->id];
    }

    /**
     * Check if admin is a team leader
     */
    public function isTeamLeader(): bool
    {
        return in_array($this->role, [AdminRole::LEADER_SALE, AdminRole::LEADER_INTER]);
    }

    /**
     * Check if admin belongs to a team
     */
    public function belongsToTeam(): bool
    {
        return !is_null($this->team_id);
    }

    public function checkRouteNameAccess(string $route_name): bool
    {
        if(in_array($route_name, config('cms.roles_permissions.whitelist_routes_name', [])))
        {
            return true;
        }

        if(in_array($route_name, $this->getRouteNamesAccess()))
        {
            return true;
        }

        $routeRoleAccess = config('cms.route_role_access', []);
        if (isset($routeRoleAccess[$route_name]) && $this->role) {
            $allowedRoles = $routeRoleAccess[$route_name];
            if (in_array($this->role, $allowedRoles)) {
                return true;
            }
        }

        return false;
    }


    public function getRouteNamesAccess(): array
    {
        $routes = [];
        
        if($this->access_route_names?->count())
        {
            $routes = array_merge($routes, $this->access_route_names->toArray());
        }

        if ($this->role) {
            $routeRoleAccess = config('cms.route_role_access', []);
            foreach ($routeRoleAccess as $routeName => $allowedRoles) {
                if (in_array($this->role, $allowedRoles)) {
                    $routes[] = $routeName;
                }
            }
        }

        return array_unique($routes);
    }
}