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): ?>
This link has expired. Please fill out the Join Us form again, and we’ll send you a new application link shortly.
You have already submitted your interview video. No further action is needed.
Thank you for your participation!
This interview link has expired. Please contact us if you need a new one.
No questions available. Please contact the recruitment team.
'; ?>Welcome, = $name ?>
Please review the questions below, record your responses, and upload your video.
Please answer all questions in one video, in order. Only one upload is allowed.
Please record your responses in English.
Walk us through your thinking as if you’re teaching a student — we’d love to see how you explain and communicate your ideas. Most candidates spend around 5–10 minutes per question, but there’s no strict time limit. Don’t worry about having perfect answers — we’re much more interested in how you think and how you teach.
Supported formats: mp4, mov, avi, webm, wmv, zip, rar, 7z | Max 500MB