Files
2026-08-11 03:27:54 +08:00

122 lines
3.1 KiB
PHP

<?php
namespace App\Support;
use App\Models\Channel;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
final class AgentScope
{
/**
* Parse admin 「代理用户」filter.
* null = 全部; 0 = 官方渠道 (channels.user_id = 0); >0 = that agent.
*/
public static function parseAgentUserIdFilter(mixed $raw): ?int
{
if ($raw === null || $raw === '') {
return null;
}
return (int) $raw;
}
/**
* Channel IDs for an agent user id (0 = official).
*
* @return list<string>
*/
public static function channelIdsForUserId(int $userId): array
{
return Channel::query()
->where('user_id', $userId)
->pluck('channel_id')
->all();
}
/**
* Channel IDs owned by the agent (empty list means no access).
*
* @return list<string>
*/
public static function channelIdsFor(?User $agent): array
{
if ($agent === null) {
return [];
}
return self::channelIdsForUserId((int) $agent->id);
}
/**
* Restrict a devices query (or anything with devices.channel_id) to an agent.
* Admin passes null agent → no restriction.
*/
public static function applyDeviceChannelScope(Builder $query, ?User $agent, string $channelColumn = 'devices.channel_id'): Builder
{
if ($agent === null) {
return $query;
}
$ids = self::channelIdsFor($agent);
if ($ids === []) {
return $query->whereRaw('1 = 0');
}
return $query->whereIn($channelColumn, $ids);
}
/**
* Admin agent filter on queries that join/select devices.channel_id.
* null = no filter; 0 = official; >0 = agent id.
*/
public static function applyAgentUserFilter(Builder $devicesQuery, ?int $agentUserId): Builder
{
if ($agentUserId === null) {
return $devicesQuery;
}
$ids = self::channelIdsForUserId($agentUserId);
if ($ids === []) {
return $devicesQuery->whereRaw('1 = 0');
}
return $devicesQuery->whereIn('devices.channel_id', $ids);
}
/**
* Restrict a query that has a bare channel_id column (e.g. page_visits).
*/
public static function applyChannelIdScope(Builder $query, ?User $agent, string $column = 'channel_id'): Builder
{
if ($agent === null) {
return $query;
}
$ids = self::channelIdsFor($agent);
if ($ids === []) {
return $query->whereRaw('1 = 0');
}
return $query->whereIn($column, $ids);
}
/**
* Admin agent filter on bare channel_id column.
* null = no filter; 0 = official; >0 = agent id.
*/
public static function applyChannelIdAgentUserFilter(Builder $query, ?int $agentUserId, string $column = 'channel_id'): Builder
{
if ($agentUserId === null) {
return $query;
}
$ids = self::channelIdsForUserId($agentUserId);
if ($ids === []) {
return $query->whereRaw('1 = 0');
}
return $query->whereIn($column, $ids);
}
}