QuickQuiz/app/Services/LearningAccessService.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');
}
}