69 lines
2.4 KiB
PHP
69 lines
2.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Paper;
|
|
use App\Models\QuestionBank;
|
|
use App\Models\SchoolClass;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Collection;
|
|
|
|
final class LearningAccessService
|
|
{
|
|
public function visibleBanksQuery(User $user): Builder
|
|
{
|
|
$classIds = $this->classIds($user);
|
|
|
|
return QuestionBank::query()
|
|
->where('is_active', true)
|
|
->where(function (Builder $query) use ($user, $classIds): void {
|
|
$query->where('visibility', 'public')
|
|
->orWhere('owner_id', $user->id)
|
|
->orWhereExists(function ($sub) use ($user): void {
|
|
$sub->selectRaw('1')
|
|
->from('bank_shares')
|
|
->whereColumn('bank_shares.question_bank_id', 'question_banks.id')
|
|
->where('target_type', 'user')
|
|
->where('target_id', $user->id);
|
|
})
|
|
->orWhereExists(function ($sub) use ($classIds): void {
|
|
$sub->selectRaw('1')
|
|
->from('bank_shares')
|
|
->whereColumn('bank_shares.question_bank_id', 'question_banks.id')
|
|
->where('target_type', 'class')
|
|
->whereIn('target_id', $classIds);
|
|
});
|
|
});
|
|
}
|
|
|
|
public function visiblePapersQuery(User $user): Builder
|
|
{
|
|
return Paper::query()
|
|
->where('is_active', true)
|
|
->where(function (Builder $query) use ($user): void {
|
|
$query->where('owner_id', $user->id)
|
|
->orWhereIn('question_bank_id', $this->visibleBanksQuery($user)->select('id'));
|
|
});
|
|
}
|
|
|
|
public function canAccessBank(User $user, QuestionBank $bank): bool
|
|
{
|
|
return $this->visibleBanksQuery($user)->whereKey($bank->id)->exists();
|
|
}
|
|
|
|
public function canAccessPaper(User $user, Paper $paper): bool
|
|
{
|
|
return $this->visiblePapersQuery($user)->whereKey($paper->id)->exists();
|
|
}
|
|
|
|
private function classIds(User $user): Collection
|
|
{
|
|
return SchoolClass::query()
|
|
->whereHas('members', fn (Builder $query) => $query->where('users.id', $user->id))
|
|
->pluck('id');
|
|
}
|
|
}
|