UserFilter.php 6.09 KB
<?php

namespace App\ModelFilters;

use App\Enums\UserScopeEnum;
use App\Support\ModelFilter;
use Arr;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as Query;
use Str;

class UserFilter extends ModelFilter
{
    /**
     * @param string $search
     * @return void
     */
    public function search(string $search): void
    {
        $this->where(function (Builder $builder) use ($search) {
            $builder->whereLike($this->qualifyColumn('nick_name'), $search)
                ->whereLike($this->qualifyColumn('real_name'), $search, 'or');
        });
    }

    /**
     * @param string $nickName
     * @return void
     */
    public function nickName(string $nickName): void
    {
        $this->whereLike('nick_name', $nickName);
    }

    /**
     * @param string $realName
     * @return void
     */
    public function realName(string $realName): void
    {
        $this->whereLike('real_name', $realName);
    }

    /**
     * @param string $email
     * @return void
     */
    public function emailLike(string $email): void
    {
        $this->whereLike('email', $email);
    }

    /**
     * @param string $name
     * @return void
     */
    public function businessName(string $name): void
    {
        $this->whereExists(function (\Illuminate\Database\Query\Builder $query) use ($name) {
            $query->selectRaw('1')->from('users', 'business')
                ->whereColumn('users.business_id', 'business.id')
                ->where('business.nick_name', 'like', "%$name%");
        });
    }

    /**
     * @param string $name
     * @return void
     */
    public function company(string $name): void
    {
        $this->whereLike('company', $name);
    }

    /**
     * @param string $email
     * @return void
     */
    public function email(string $email): void
    {
        $this->where('email', $email);
    }

    /**
     * @param string $phone
     * @return void
     */
    public function phone(string $phone): void
    {
        $this->where('phone', $phone);
    }

    /**
     * @param string $phone
     * @return void
     */
    public function phoneLike(string $phone): void
    {
        $this->whereLike('phone', $phone);
    }

    /**
     * @param string|array $sex
     * @return void
     */
    public function sex(string|array $sex): void
    {
        is_array($sex) ? $this->whereIn('sex', $sex) : $this->where('sex', $sex);
    }

    /**
     * @param string|array $role
     * @return void
     */
    public function role(string|array $role): void
    {
        is_array($role) ? $this->whereIn('role', $role) : $this->where('role', $role);
    }

    /**
     * @param string|array $scope
     * @return void
     */
    public function scope(string|array $scope): void
    {
        $this->whereIn('scope', Arr::wrap($scope));
    }

    /**
     * @param string|array $status
     * @return void
     */
    public function status(array|string $status): void
    {
        $this->whereIn('status', Arr::wrap($status));
    }

    /**
     * @param array|int $status
     * @return void
     */
    public function identity(array|int $status): void
    {
        $this->whereIn('identity', Arr::wrap($status));
    }

    /**
     * @param array|int $tagIds
     * @return void
     */
    public function authIds(array|int $tagIds): void
    {
        $this->whereHas('authTags', fn($query) => $query->whereIn('tag_id', Arr::wrap($tagIds)));
    }

    /**
     * @param array|string $status
     * @return void
     */
    public function officialStatus(array|string $status): void
    {
        $this->whereIn('official_status', Arr::wrap($status));
    }

    /**
     * @param array|int $activityIds
     * @return void
     */
    public function excludeManageActivity(array|int $activityIds): void
    {
        $this->whereNotExists(fn(Query $query) => $query->from('user_manage_activities')->whereColumn('users.id', 'user_manage_activities.user_id')->whereIn('user_manage_activities.activity_id', Arr::wrap($activityIds)));
    }

    /**
     * @param array|int $projectIds
     * @return void
     */
    public function excludeManageProject(array|int $projectIds): void
    {
        $this->whereNotExists(fn(Query $query) => $query->from('user_has_projects')->whereColumn('users.id', 'user_has_projects.user_id')->whereIn('user_has_projects.project_id', Arr::wrap($projectIds)));
    }

    /**
     * @param string|array $identity
     * @return void
     */
    public function identityRole(string|array $identity): void
    {
        $identity       = Arr::wrap($identity);
        $musicianTagIds = Arr::whereNotNull(Arr::map($identity, static fn($value) => Str::startsWith($value, 'musician_tag_') ? Str::after($value, 'musician_tag_') : NULL));


        $this->where(fn(Builder $builder) => $builder
            ->when(in_array('visitor', $identity, true), fn(Builder $query) => $query->orWhere('identity', 0))
            ->when(in_array('system', $identity, true), fn(Builder $query) => $query->orWhere('scope', UserScopeEnum::SYSTEM))
            ->when(in_array('musician', $identity, true), fn(Builder $query) => $query->orWhereIn('identity', [1, 3]))
            ->when(in_array('project', $identity, true), fn(Builder $query) => $query->orWhere(function (Builder $query) use ($identity) {
                $query->where('scope', UserScopeEnum::PROJECT)->when(in_array('manager', $identity, true), function (Builder $query) {
                    $query->WhereExists(fn(Query $query) => $query->from('projects')->whereColumn('projects.master_id', 'users.id'));
                });
            }))
            ->when(in_array('captain', $identity, true), fn(Builder $query) => $query->orWhere(function (Builder $query) use ($identity) {
                $query->when(in_array('broker', $identity, true), fn($query) => $query->whereIn('identity', [2, 3]))
                    ->whereExists(fn($query) => $query->from('users', 'u')->whereColumn('u.business_id', 'users.id')->whereNull('u.deleted_at'));
            }))
            ->when($musicianTagIds, fn(Builder $query) => $query->orWhereHas('authTags', fn(Builder $builder) => $builder->whereIn('system_tags.id', $musicianTagIds))));
    }
}