37 lines
4.6 KiB
PHP
37 lines
4.6 KiB
PHP
<?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(); ?>
|