Files

37 lines
4.6 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
require __DIR__.'/bootstrap.php'; require_admin();
$id=(int)($_GET['id']??0); $copy=(int)($_GET['copy']??0);
$fields=['kat','soal','soal1','opa','opb','opc','opd','ope','kunci'];
$s=array_fill_keys($fields,''); $s['kat']=1; $error=''; $used=0;
if($id || $copy) {
$s=one('SELECT * FROM in_soal WHERE id=?','i',[$id?:$copy]);
if(!$s) { http_response_code(404); page_start('Soal tidak ditemukan','questions'); echo '<p>Soal tidak ditemukan.</p>'; page_end(); exit; }
if($id) $used=(int)one('SELECT COUNT(*) n FROM in_jawab WHERE isoal=?','i',[$id])['n'];
}
if($_SERVER['REQUEST_METHOD']==='POST') {
verify_csrf();
foreach($fields as $field) $s[$field]=trim($_POST[$field]??'');
$category=(int)$s['kat']; $deleting=($_POST['action']??'')==='delete';
if($deleting && !$id) $error='Soal belum tersimpan.';
elseif(!isset(CATEGORIES[$category]) || $s['soal']==='' || ($category===5 && $s['soal1']==='') || ($category!==5 && $s['kunci']==='')) $error='Lengkapi kategori, soal, dan kunci jawaban (atau pilihan R untuk kepribadian).';
else {
foreach(['opa','opb','opc','opd','ope'] as $field) if(strlen($s[$field])>100) $error='Pilihan jawaban maksimal 100 karakter.';
if(strlen($s['kunci'])>200) $error='Kunci jawaban maksimal 200 karakter.';
if(!$error) {
db()->begin_transaction();
try {
if($id) {
one('SELECT id FROM in_soal WHERE id=? FOR UPDATE','i',[$id]);
if(one('SELECT id FROM in_jawab WHERE isoal=? LIMIT 1','i',[$id])) throw new InvalidArgumentException('Soal sudah digunakan peserta. Duplikat soal untuk membuat versi baru; riwayat hasil harus dipertahankan.');
}
if($deleting) query('DELETE FROM in_soal WHERE id=?','i',[$id]);
elseif($id) query('UPDATE in_soal SET kat=?,soal=?,soal1=?,opa=?,opb=?,opc=?,opd=?,ope=?,kunci=? WHERE id=?','issssssssi',[$category,$s['soal'],$s['soal1'],$s['opa'],$s['opb'],$s['opc'],$s['opd'],$s['ope'],$s['kunci'],$id]);
else query('INSERT INTO in_soal(kat,soal,soal1,opa,opb,opc,opd,ope,kunci) VALUES(?,?,?,?,?,?,?,?,?)','issssssss',[$category,$s['soal'],$s['soal1'],$s['opa'],$s['opb'],$s['opc'],$s['opd'],$s['ope'],$s['kunci']]);
db()->commit(); $_SESSION['flash']=$deleting?'Soal dihapus.':'Soal berhasil disimpan.'; redirect('isoal.php');
} catch(InvalidArgumentException $ex) { db()->rollback(); $error=$ex->getMessage(); } catch(Throwable $ex) { db()->rollback(); throw $ex; }
}
}
}
page_start($id?'Detail soal #'.$id:($copy?'Duplikat soal':'Tambah soal'),'questions');
?><a class="text-link back" href="isoal.php">← Bank soal</a><section class="card form-card"><h2><?=$id?'Detail bank soal':'Soal baru'?></h2><p class="muted">Soal kepribadian memiliki dua pernyataan (L / R), tanpa skor benar atau salah.</p><?php if($used): ?><div class="notice">Soal ini sudah memiliki <?=$used?> jawaban. Isi dikunci untuk menjaga riwayat penilaian. Duplikat akan menjadi soal tambahan yang juga masuk dalam pengacakan tes.</div><a class="button secondary" href="question-edit.php?copy=<?=$id?>">Duplikat sebagai soal baru →</a><?php endif; ?><?php if($error): ?><div class="notice error"><?=e($error)?></div><?php endif; ?><form method="post"><?php csrf_field(); ?><fieldset <?=$used?'disabled':''?>><label>Kategori<select name="kat" required><?php foreach(CATEGORIES as $k=>$v): ?><option value="<?=$k?>" <?=(int)$s['kat']===$k?'selected':''?>><?=e($v)?></option><?php endforeach; ?></select></label><div class="form-grid"><label>Soal / Pernyataan L<textarea name="soal" rows="5" required><?=e($s['soal'])?></textarea></label><label>Pernyataan R (khusus kepribadian)<textarea name="soal1" rows="5"><?=e($s['soal1'])?></textarea></label></div><label>Kunci jawaban (kategori 1–4)<textarea name="kunci" rows="2" maxlength="200"><?=e($s['kunci'])?></textarea></label><details><summary>Pilihan jawaban A–E (jika digunakan)</summary><p class="muted">Alur tes saat ini memakai jawaban teks untuk kategori 1–4. Pilihan ini disimpan sebagai bagian bank soal.</p><div class="form-grid"><?php foreach(['opa'=>'A','opb'=>'B','opc'=>'C','opd'=>'D','ope'=>'E'] as $key=>$label): ?><label>Pilihan <?=$label?><input name="<?=$key?>" maxlength="100" value="<?=e($s[$key])?>"></label><?php endforeach; ?></div></details><div class="form-actions"><?php if($id): ?><button class="button danger" name="action" value="delete" data-confirm="Hapus soal ini? Tindakan ini tidak dapat dibatalkan.">Hapus soal</button><?php endif; ?><button class="button" name="action" value="save">Simpan soal</button></div></fieldset></form></section><?php page_end(); ?>