Files
Recruitment-HC/includes/candidate-test.php
T

33 lines
5.1 KiB
PHP

<?php
require __DIR__.'/candidate.php'; $p=candidate();
if((int)$p['level']!==$phase-1) cgo('home.php');
$info=CPHASES[$phase];
cdb()->begin_transaction();
try {
$current=cq('SELECT level FROM in_daper WHERE id=? FOR UPDATE','i',[(int)$p['id']])->get_result()->fetch_assoc();
if((int)$current['level']!==$phase-1) { cdb()->rollback(); cgo('home.php'); }
$attempt=exam_find((int)$p['id'],$phase);
if(!$attempt) {
$questions=[];
foreach($info[4] as $kat=>$limit) {
$found=cq('SELECT id,kat,soal,soal1,opa,opb,opc,opd,ope FROM in_soal WHERE kat=? ORDER BY RAND() LIMIT '.$limit,'i',[$kat])->get_result()->fetch_all(MYSQLI_ASSOC);
if(count($found)<$limit) throw new RuntimeException('Soal fase ini belum lengkap. Hubungi tim Human Capital.');
$questions=array_merge($questions,$found);
}
cq('INSERT INTO rec_exam_attempt(participant_id,phase,questions_json,answers_json,deadline,active_token) VALUES(?,?,?,\'{}\',?,?)','iisis',[(int)$p['id'],$phase,json_encode($questions,JSON_UNESCAPED_UNICODE),time()+$info[3],bin2hex(random_bytes(32))]);
$attempt=exam_find((int)$p['id'],$phase);
}
if($attempt['status']!=='active') { cdb()->rollback(); cgo('home.php'); }
if(time()>=(int)$attempt['deadline']) {
exam_finalize($attempt,json_decode($attempt['answers_json'],true),true); cdb()->commit();
$_SESSION['success']='Waktu fase '.$phase.' habis. Draft terakhir yang diterima server telah disimpan.'; cgo('home.php');
}
$attemptToken=bin2hex(random_bytes(32));
cq('UPDATE rec_exam_attempt SET active_token=? WHERE id=?','si',[$attemptToken,(int)$attempt['id']]);
cdb()->commit();
} catch(Throwable $error) { cdb()->rollback(); error_log($error->getMessage()); $_SESSION['error']='Tes belum dapat dibuka. Periksa koneksi atau hubungi Human Capital.'; cgo('home.php'); }
$exam=['questions'=>json_decode($attempt['questions_json'],true),'deadline'=>(int)$attempt['deadline']];
$draft=json_decode($attempt['answers_json'],true);
cstart('Fase '.$phase.' · '.$info[0],$p);
?><a class="text-link back" href="home.php">← Beranda peserta</a><div class="exam-heading"><div><span class="eyebrow">FASE 0<?=$phase?> / 04</span><h1><?=ce($info[0])?></h1><p class="muted intro"><?=ce($info[1])?> · <?=$phase===4?'Pilih satu pernyataan yang paling sesuai dengan diri Anda.':'Jawab dengan teliti dan periksa sebelum mengirim.'?></p></div><div class="timer" role="timer" data-remaining="<?=max(0,$exam['deadline']-time())?>"><small>SISA WAKTU</small><strong id="exam-time">--:--</strong></div></div><div class="exam-progress"><span id="answered-count">0</span> / <?=count($exam['questions'])?> jawaban terisi <progress id="answer-progress" value="0" max="<?=count($exam['questions'])?>" aria-label="Jawaban terisi"></progress></div><div class="notice integrity-notice" role="status">Waktu tes dipantau server dan tetap berjalan saat Anda keluar atau pindah tab. Jawaban disimpan otomatis. Aktivitas meninggalkan halaman serta copy/paste dapat dicatat untuk ditinjau tim Human Capital; catatan ini bukan keputusan kelulusan.</div><div id="exam-status" class="draft-status" role="status">Memulai sinkronisasi…</div><noscript><div class="notice error">JavaScript diperlukan untuk autosave dan tampilan waktu. Batas waktu server tetap berlaku.</div></noscript><form id="exam-form" method="post" action="test1_add.php"><?php ctoken(); ?><input type="hidden" name="attempt_token" value="<?=ce($attemptToken)?>"><input type="hidden" name="phase" value="<?=$phase?>"><?php foreach($exam['questions'] as $i=>$s): ?><section class="card question-card" data-question><div class="question-meta"><span class="phase-number"><?=str_pad($i+1,2,'0',STR_PAD_LEFT)?></span><span class="eyebrow"><?=ce([1=>'MATEMATIKA',2=>'SINONIM',3=>'ANTONIM',4=>'PADANAN KATA',5=>'KEPRIBADIAN'][$s['kat']])?></span></div><?php if($phase===4): ?><div class="choice-grid"><?php foreach(['L'=>$s['soal'],'R'=>$s['soal1']] as $value=>$text): ?><label class="choice"><input type="radio" name="answers[<?=(int)$s['id']?>]" value="<?=$value?>" <?=($draft[$s['id']]??'')===$value?'checked':''?>><span><b><?=$value?></b><?=nl2br(ce($text))?></span></label><?php endforeach; ?></div><?php else: ?><h2 class="question-prompt"><?=nl2br(ce($s['soal']))?> <?=nl2br(ce($s['soal1']))?></h2><?php if($phase===3): ?><div class="choice-grid"><?php foreach(['opa','opb','opc','opd','ope'] as $option): if(trim($s[$option])==='') continue; ?><label class="choice"><input type="radio" name="answers[<?=(int)$s['id']?>]" value="<?=ce($s[$option])?>" <?=($draft[$s['id']]??'')===$s[$option]?'checked':''?>><span><?=ce($s[$option])?></span></label><?php endforeach; ?></div><?php else: ?><label>Jawaban Anda<input type="text" name="answers[<?=(int)$s['id']?>]" value="<?=ce($draft[$s['id']]??'')?>" autocomplete="off" placeholder="Tulis jawaban di sini…" maxlength="2000"></label><?php endif; ?><?php endif; ?></section><?php endforeach; ?><div class="save-bar"><div><strong>Sudah yakin dengan jawaban Anda?</strong><small>Draft disimpan otomatis. Pengiriman akhir tidak dapat diulang.</small></div><button class="button" type="submit"><?=$phase===4?'Selesaikan psikotest':'Kirim jawaban & lanjut'?> →</button></div></form><?php cend(); ?>