subjects ?? '[]', true) ?: []; if (empty($subject_ids)) return []; $disciplines = []; foreach ($subject_ids as $sid) { if (!is_numeric($sid)) continue; $terms = wp_get_post_terms((int) $sid, 'discipline'); if (!is_wp_error($terms) && !empty($terms)) { foreach ($terms as $t) { $order_val = get_field('order', $t); if ($order_val === false || $order_val === null) { $order_val = get_term_meta($t->term_id, 'order', true); } if (!isset($disciplines[$t->term_id])) { $disciplines[$t->term_id] = [ 'term' => $t, 'order' => (int) $order_val ]; } } } } if (empty($disciplines)) return []; uasort($disciplines, function ($a, $b) { return $a['order'] <=> $b['order']; }); $top_disciplines = array_slice($disciplines, 0, 3, true); $questions_to_show = []; foreach ($top_disciplines as $term_id => $data) { $term = $data['term']; $q_posts = get_posts([ 'post_type' => 'interview_question', 'posts_per_page' => -1, 'tax_query' => [ [ 'taxonomy' => 'discipline', 'field' => 'term_id', 'terms' => $term_id ] ], 'fields' => 'ids' ]); if (!empty($q_posts)) { $random_q_id = $q_posts[array_rand($q_posts)]; $gallery = get_field('content', $random_q_id); $images = []; if (is_array($gallery)) { foreach ($gallery as $img) { if (is_string($img)) { $images[] = $img; } elseif (is_array($img) && !empty($img['url'])) { $images[] = $img['url']; } } } if (!empty($images)) { $q_items = []; foreach ($images as $url) { $q_items[] = ['type' => 'image', 'url' => $url]; } $questions_to_show[$term->name] = $q_items; } } } return $questions_to_show; } /* ============================================================ Interview CSS (output once) ============================================================ */ function im_enqueue_interview_styles() { static $done = false; if ($done) return; $done = true; echo ''; echo ''; } /* ============================================================ AJAX: Video Upload Handler ============================================================ */ add_action('wp_ajax_im_interview_upload', 'im_ajax_interview_upload'); add_action('wp_ajax_nopriv_im_interview_upload', 'im_ajax_interview_upload'); function im_ajax_interview_upload() { $token_str = sanitize_text_field($_POST['im_token'] ?? ''); $token_row = $token_str ? IM_Token::validate($token_str) : null; if (!$token_row) { wp_send_json_error(['message' => 'Invalid or expired interview link. Please refresh the page.']); } $candidate = IM_Candidate::get($token_row->candidate_id); if (!$candidate) { wp_send_json_error(['message' => 'Candidate not found.']); } if (!wp_verify_nonce($_POST['im_nonce'] ?? '', 'im_interview_' . $token_row->token)) { wp_send_json_error(['message' => 'Security verification failed. Please refresh and try again.']); } $file = $_FILES['im_video'] ?? null; if (!$file || $file['error'] !== UPLOAD_ERR_OK) { wp_send_json_error(['message' => 'Video upload failed. Please check the file size (max 500MB) and try again.']); } $allowed = [ 'video/mp4', 'video/quicktime', 'video/x-msvideo', 'video/avi', 'video/webm', 'video/x-ms-wmv', 'application/zip', 'application/x-zip-compressed', 'application/x-rar-compressed', 'application/vnd.rar', 'application/x-7z-compressed', 'application/gzip', 'application/x-tar' ]; $finfo = finfo_open(FILEINFO_MIME_TYPE); $mime = finfo_file($finfo, $file['tmp_name']); finfo_close($finfo); if (!in_array($mime, $allowed, true)) { wp_send_json_error(['message' => 'Supported formats: mp4, mov, avi, webm, wmv, zip, rar, 7z.']); } if ($file['size'] > IM_MAX_VIDEO_SIZE) { wp_send_json_error(['message' => 'Video file cannot exceed 500MB. Please compress and try again.']); } $upload_dir = wp_upload_dir(); $save_dir = $upload_dir['basedir'] . '/interviews/' . $candidate->id; wp_mkdir_p($save_dir); file_put_contents($save_dir . '/index.html', ''); $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); $filename = 'interview_' . $token_row->id . '_' . time() . '.' . $ext; $dest = $save_dir . '/' . $filename; if (!move_uploaded_file($file['tmp_name'], $dest)) { wp_send_json_error(['message' => 'File save failed. Please contact the administrator.']); } IM_Token::mark_used($token_row->id, $dest, $filename); IM_Candidate::update_status($candidate->id, 'completed'); $name = esc_html($candidate->preferred_name ?: $candidate->first_name); wp_send_json_success(['message' => 'ok', 'name' => $name]); } /* ============================================================ Shortcode: [im_interview] ============================================================ */ add_shortcode('im_interview', function () { im_enqueue_interview_styles(); ob_start(); $token_str = sanitize_text_field($_GET['im_token'] ?? ''); // No token if (!$token_str): ?>
!

Link Expired

This link has expired. Please fill out the Join Us form again, and we’ll send you a new application link shortly.

is_used): ?>

Already Submitted

You have already submitted your interview video. No further action is needed.

Thank you for your participation!

!

Link Expired

This interview link has expired. Please contact us if you need a new one.

opened_at)) { IM_Token::mark_opened($token_row->id); $token_row = IM_Token::validate($token_str); } $candidate = IM_Candidate::get($token_row->candidate_id); $questions = im_get_questions($candidate); $name = esc_html($candidate->preferred_name ?: $candidate->first_name); $nonce = wp_create_nonce('im_interview_' . $token_row->token); $expires_dt = new DateTimeImmutable($token_row->expires_at, wp_timezone()); $expires_ms = $expires_dt->getTimestamp() * 1000; $q_html = ''; foreach ($questions as $subject => $qs) { $q_html .= '

' . esc_html($subject) . ' Exam question

'; } if (!$q_html) $q_html = '

No questions available. Please contact the recruitment team.

'; ?>

Video Interview

Welcome,

Please review the questions below, record your responses, and upload your video.

Time remaining:

Interview Questions

Please answer all questions in a single video, following the order below. Only one video upload is allowed, so please include all your responses in one recording.

Clearly explain your thinking process as if you are teaching a student.

There is no strict time limit, but most candidates spend around 5 to 10 minutes on each question.

There is no need for perfect answers. We are primarily interested in how you explain your thinking and teaching approach.

Upload Interview Video

Supported formats: mp4, mov, avi, webm, wmv, zip, rar, 7z  |  Max 500MB

Click to select a video or archive file, or drag and drop here