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 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.
Supported formats: mp4, mov, avi, webm, wmv, zip, rar, 7z | Max 500MB