281 lines
8.9 KiB
PHP
281 lines
8.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Guru;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\Ujian;
|
|
use App\Models\Kelas;
|
|
use App\Models\Guru;
|
|
use App\Models\Mapel;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use App\Models\HasilUjian;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class UjianController extends Controller
|
|
{
|
|
protected function getGuruId()
|
|
{
|
|
$guru = Guru::where('user_id', auth()->id())->firstOrFail();
|
|
return $guru->id;
|
|
}
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$guruId = $this->getGuruId(); // Mendapatkan ID guru yang login
|
|
$kelasId = $request->get('kelas_id'); // ID kelas yang difilter (jika ada)
|
|
|
|
// Ambil semua mapel yang diajar guru, bisa difilter juga berdasarkan kelas
|
|
$mapelIds = \App\Models\GuruMapel::where('guru_id', $guruId)
|
|
->when($kelasId, fn($q) => $q->where('kelas_id', $kelasId))
|
|
->pluck('mapel_id');
|
|
|
|
// Ambil ujian-ujian yang mapelnya diajar oleh guru
|
|
$ujians = \App\Models\Ujian::with('kelas', 'mapel')
|
|
->whereIn('mapel_id', $mapelIds)
|
|
->when($kelasId, function ($query) use ($kelasId) {
|
|
$query->whereHas('kelas', fn($q) => $q->where('kelas.id', $kelasId));
|
|
})
|
|
->get();
|
|
|
|
// Ambil daftar kelas untuk dropdown filter (kelas yang benar-benar diajar guru)
|
|
$daftarKelas = \App\Models\Kelas::whereIn('id', \App\Models\GuruMapel::where('guru_id', $guruId)->pluck('kelas_id'))
|
|
->get();
|
|
|
|
return view('guru.ujian.index', compact('ujians', 'daftarKelas', 'kelasId'));
|
|
}
|
|
|
|
public function show(Ujian $ujian)
|
|
{
|
|
return redirect()->route('guru.ujian.preview', $ujian->id);
|
|
}
|
|
|
|
public function detail(Ujian $ujian)
|
|
{
|
|
$ujian->load([
|
|
'soalPilgan',
|
|
'soalEssay',
|
|
'kelas' => function ($query) {
|
|
$query->withPivot('deadline', 'terbit');
|
|
}
|
|
]);
|
|
|
|
return view('guru.ujian.detail', compact('ujian'));
|
|
}
|
|
|
|
public function create()
|
|
{
|
|
$guru = auth()->user()->guru;
|
|
|
|
if (!$guru) {
|
|
return redirect()->route('guru.dashboard')->with('error', 'Data guru tidak ditemukan.');
|
|
}
|
|
|
|
$mapels = $guru->mapel;
|
|
$kelas = Kelas::all();
|
|
|
|
return view('guru.ujian.create', compact('mapels', 'kelas'));
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$guru = auth()->user()->guru;
|
|
|
|
$request->validate([
|
|
'mapel_id' => [
|
|
'required',
|
|
'exists:mapels,id',
|
|
// Validasi custom supaya mapel yang dipilih adalah mapel yang diampu guru
|
|
function ($attribute, $value, $fail) use ($guru) {
|
|
if (!$guru->mapel->pluck('id')->contains($value)) {
|
|
$fail('Mapel yang dipilih tidak valid.');
|
|
}
|
|
},
|
|
],
|
|
'judul' => 'required',
|
|
'waktu' => 'required|numeric',
|
|
'deskripsi' => 'nullable|string',
|
|
'soal' => 'nullable|string',
|
|
'bobot_pg' => 'nullable|integer',
|
|
'bobot_essay' => 'nullable|integer',
|
|
'kelas' => 'required|array',
|
|
'kelas.*.deadline' => 'nullable|date',
|
|
'kelas.*.terbit' => 'nullable|boolean',
|
|
]);
|
|
|
|
$ujian = Ujian::create([
|
|
'mapel_id' => $request->mapel_id,
|
|
'judul' => $request->judul,
|
|
'deskripsi' => $request->deskripsi,
|
|
'tanggal_post' => now(),
|
|
'waktu' => $request->waktu,
|
|
'soal' => $request->soal ?? '',
|
|
'terbit' => false,
|
|
'bobot_pg' => $request->bobot_pg ?? 0,
|
|
'bobot_essay' => $request->bobot_essay ?? 0,
|
|
]);
|
|
|
|
$attachData = [];
|
|
foreach ($request->kelas as $kelas_id => $kelasData) {
|
|
$attachData[$kelas_id] = [
|
|
'deadline' => $kelasData['deadline'] ?? null,
|
|
'terbit' => $kelasData['terbit'] ?? false,
|
|
];
|
|
}
|
|
$ujian->kelas()->attach($attachData);
|
|
|
|
return redirect()->route('guru.ujian.index')->with('success', 'Ujian berhasil dibuat.');
|
|
}
|
|
|
|
public function edit(Ujian $ujian)
|
|
{
|
|
$ujian->load(['soalPilgan', 'soalEssay', 'kelas']);
|
|
$kelas = Kelas::all();
|
|
|
|
$kelasDeadline = $ujian->kelas->keyBy('id')->map(function ($kelas) {
|
|
return $kelas->pivot->deadline;
|
|
});
|
|
|
|
$kelasTerbit = $ujian->kelas->keyBy('id')->map(function ($kelas) {
|
|
return $kelas->pivot->terbit;
|
|
});
|
|
|
|
return view('guru.ujian.edit', compact('ujian', 'kelas', 'kelasDeadline', 'kelasTerbit'));
|
|
}
|
|
|
|
public function update(Request $request, Ujian $ujian)
|
|
{
|
|
$request->validate([
|
|
'judul' => 'required',
|
|
'waktu' => 'required|numeric',
|
|
'deskripsi' => 'nullable|string',
|
|
'soal' => 'nullable|string',
|
|
'bobot_pg' => 'nullable|integer',
|
|
'bobot_essay' => 'nullable|integer',
|
|
'kelas' => 'required|array',
|
|
'kelas.*.deadline' => 'nullable|date',
|
|
'kelas.*.terbit' => 'nullable|boolean',
|
|
]);
|
|
|
|
$ujian->update([
|
|
'judul' => $request->judul,
|
|
'deskripsi' => $request->deskripsi,
|
|
'waktu' => $request->waktu,
|
|
'soal' => $request->soal ?? '',
|
|
'bobot_pg' => $request->bobot_pg ?? 0,
|
|
'bobot_essay' => $request->bobot_essay ?? 0,
|
|
]);
|
|
|
|
$syncData = [];
|
|
foreach ($request->kelas as $kelas_id => $kelasData) {
|
|
$syncData[$kelas_id] = [
|
|
'deadline' => $kelasData['deadline'] ?? null,
|
|
'terbit' => $kelasData['terbit'] ?? false,
|
|
];
|
|
}
|
|
$ujian->kelas()->sync($syncData);
|
|
|
|
return redirect()->route('guru.ujian.index')->with('success', 'Ujian berhasil diperbarui.');
|
|
}
|
|
|
|
public function updateStatus(Ujian $ujian)
|
|
{
|
|
$ujian->terbit = !$ujian->terbit;
|
|
$ujian->save();
|
|
|
|
return redirect()->route('guru.ujian.index')->with('success', 'Status ujian berhasil diperbarui.');
|
|
}
|
|
|
|
public function destroy(Ujian $ujian)
|
|
{
|
|
$ujian->kelas()->detach();
|
|
$ujian->delete();
|
|
return back()->with('success', 'Ujian berhasil dihapus.');
|
|
}
|
|
|
|
public function preview($id)
|
|
{
|
|
$ujian = Ujian::with('kelas')->findOrFail($id);
|
|
return view('guru.ujian.preview', compact('ujian'));
|
|
}
|
|
|
|
public function daftarHasil(Request $request)
|
|
{
|
|
$guruId = $this->getGuruId(); // Ambil ID guru login
|
|
$kelasId = $request->get('kelas_id');
|
|
|
|
// Ambil mapel yang diajar guru
|
|
$mapelIds = \App\Models\GuruMapel::where('guru_id', $guruId)
|
|
->when($kelasId, fn($q) => $q->where('kelas_id', $kelasId))
|
|
->pluck('mapel_id');
|
|
|
|
// Ambil semua ujian yang punya hasil, dibuat oleh guru login
|
|
$ujians = \App\Models\Ujian::withCount('hasilUjian')
|
|
->whereIn('mapel_id', $mapelIds)
|
|
->whereHas('hasilUjian')
|
|
->when($kelasId, function ($query) use ($kelasId) {
|
|
$query->whereHas('kelas', fn($q) => $q->where('kelas.id', $kelasId));
|
|
})
|
|
->get();
|
|
|
|
// Ambil daftar kelas untuk dropdown
|
|
$daftarKelas = \App\Models\Kelas::whereIn('id', \App\Models\GuruMapel::where('guru_id', $guruId)->pluck('kelas_id'))->get();
|
|
|
|
return view('guru.ujian.daftar-hasil', compact('ujians', 'daftarKelas', 'kelasId'));
|
|
}
|
|
|
|
public function hasil(Request $request, $ujian_id)
|
|
{
|
|
$guruId = $this->getGuruId();
|
|
$kelasId = $request->get('kelas_id');
|
|
|
|
// Ambil mapel yang diajar oleh guru
|
|
$mapelIds = \App\Models\GuruMapel::where('guru_id', $guruId)->pluck('mapel_id');
|
|
|
|
// Validasi bahwa ujian benar-benar milik guru login
|
|
$ujian = \App\Models\Ujian::with(['hasilUjian.siswa', 'kelas'])
|
|
->where('id', $ujian_id)
|
|
->whereIn('mapel_id', $mapelIds)
|
|
->firstOrFail();
|
|
|
|
// Filter hasilUjian berdasarkan kelas jika diminta
|
|
if ($kelasId) {
|
|
$ujian->setRelation('hasilUjian', $ujian->hasilUjian->filter(function ($hasil) use ($kelasId) {
|
|
return $hasil->siswa->kelas_id == $kelasId;
|
|
}));
|
|
}
|
|
|
|
// Ambil daftar kelas dari relasi ujian
|
|
$daftarKelas = $ujian->kelas;
|
|
|
|
return view('guru.ujian.hasil', compact('ujian', 'daftarKelas', 'kelasId'));
|
|
}
|
|
|
|
|
|
|
|
public function grafik(Request $request)
|
|
{
|
|
$kelasId = $request->kelas_id;
|
|
|
|
if (!$kelasId) {
|
|
return redirect()->route('guru.ujian.hasil.index')->with('error', 'Silakan pilih kelas terlebih dahulu.');
|
|
}
|
|
|
|
$kelas = Kelas::find($kelasId); // ambil data kelas
|
|
|
|
$data = HasilUjian::select('ujian_id', DB::raw('AVG(nilai_total) as rata_rata'))
|
|
->whereNotNull('nilai_total')
|
|
->whereHas('siswa', fn($q) => $q->where('kelas_id', $kelasId))
|
|
->groupBy('ujian_id')
|
|
->with('ujian:id,judul')
|
|
->get();
|
|
|
|
$labels = $data->map(fn($item) => $item->ujian->judul);
|
|
$values = $data->map(fn($item) => round($item->rata_rata, 2));
|
|
|
|
return view('guru.ujian.grafik', compact('labels', 'values', 'kelasId', 'kelas'));
|
|
}
|
|
|
|
|
|
}
|