Job Application Form With CV Upload
Adds a [wpide_job_application] shortcode where candidates send their details and a CV (PDF or Word, size-limited); the CV is attached to the email you receive and then deleted from the server.
Opens WPIDE on
Code
$wpide_jobs = array(
'to' => '', // Recipient; empty = admin email.
'max_mb' => 5, // Maximum CV size.
'types' => array( 'pdf' => 'application/pdf', 'doc' => 'application/msword', 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ),
);
add_action( 'template_redirect', function () use ( $wpide_jobs ) {
if ( empty( $_POST['wpide_job_nonce'] ) ) {
return;
}
$back = remove_query_arg( 'wpide_job', wp_get_referer() ? wp_get_referer() : home_url( '/' ) );
$done = function ( $status ) use ( $back ) {
wp_safe_redirect( add_query_arg( 'wpide_job', $status, $back ) . '#wpide-job' );
exit;
};
if ( ! wp_verify_nonce( sanitize_key( wp_unslash( $_POST['wpide_job_nonce'] ) ), 'wpide_job' ) ) {
$done( 'expired' );
}
if ( ! empty( $_POST['wpide_job_hp'] ) ) {
$done( 'sent' );
}
$name = str_replace( array( '<', '>', '"' ), '', sanitize_text_field( wp_unslash( isset( $_POST['wpide_job_name'] ) ? $_POST['wpide_job_name'] : '' ) ) );
$email = sanitize_email( wp_unslash( isset( $_POST['wpide_job_email'] ) ? $_POST['wpide_job_email'] : '' ) );
$position = sanitize_text_field( wp_unslash( isset( $_POST['wpide_job_position'] ) ? $_POST['wpide_job_position'] : '' ) );
$letter = sanitize_textarea_field( wp_unslash( isset( $_POST['wpide_job_letter'] ) ? $_POST['wpide_job_letter'] : '' ) );
$file = isset( $_FILES['wpide_job_cv'] ) ? $_FILES['wpide_job_cv'] : null; // phpcs:ignore
if ( '' === $name || ! is_email( $email ) || ! $file || UPLOAD_ERR_OK !== $file['error'] ) {
$done( 'invalid' );
}
if ( $file['size'] > $wpide_jobs['max_mb'] * MB_IN_BYTES ) {
$done( 'size' );
}
require_once ABSPATH . 'wp-admin/includes/file.php';
$upload = wp_handle_upload( $file, array( 'test_form' => false, 'mimes' => $wpide_jobs['types'] ) );
if ( empty( $upload['file'] ) ) {
$done( 'type' );
}
$to = is_email( $wpide_jobs['to'] ) ? $wpide_jobs['to'] : get_option( 'admin_email' );
$sent = wp_mail( $to, sprintf( 'Application: %s – %s', $position ? $position : 'Open application', $name ), "Name: $name\nEmail: $email\nPosition: $position\n\n$letter", array( 'Reply-To: ' . $name . ' <' . $email . '>' ), array( $upload['file'] ) );
wp_delete_file( $upload['file'] );
$done( $sent ? 'sent' : 'error' );
} );
add_shortcode( 'wpide_job_application', function ( $atts ) use ( $wpide_jobs ) {
$atts = shortcode_atts( array( 'position' => '' ), $atts, 'wpide_job_application' );
$messages = array(
'sent' => 'Thank you for applying! We will review your application and be in touch.',
'invalid' => 'Please fill in your name and email and attach your CV.',
'size' => sprintf( 'Your CV is too large. The maximum size is %d MB.', $wpide_jobs['max_mb'] ),
'type' => 'Please upload your CV as a PDF or Word document.',
'expired' => 'The form expired. Please try again.',
'error' => 'Sorry, your application could not be sent. Please email us directly.',
);
$status = isset( $_GET['wpide_job'] ) ? sanitize_key( $_GET['wpide_job'] ) : '';
$html = '<div id="wpide-job" class="wpide-form wpide-job-form">';
$html .= isset( $messages[ $status ] ) ? '<p class="wpide-form-notice" role="status">' . esc_html( $messages[ $status ] ) . '</p>' : '';
$html .= '<form method="post" action="" enctype="multipart/form-data">';
$html .= '<p><label for="wpide-job-name">Full name</label><br><input id="wpide-job-name" name="wpide_job_name" required autocomplete="name"></p>';
$html .= '<p><label for="wpide-job-email">Email</label><br><input type="email" id="wpide-job-email" name="wpide_job_email" required autocomplete="email"></p>';
$html .= '<p><label for="wpide-job-cv">CV (PDF or Word, max ' . (int) $wpide_jobs['max_mb'] . ' MB)</label><br><input type="file" id="wpide-job-cv" name="wpide_job_cv" required accept=".pdf,.doc,.docx"></p>';
$html .= '<p><label for="wpide-job-letter">Why are you a great fit?</label><br><textarea id="wpide-job-letter" name="wpide_job_letter" rows="6"></textarea></p>';
$html .= '<input type="hidden" name="wpide_job_position" value="' . esc_attr( $atts['position'] ) . '">';
$html .= '<p style="position:absolute;left:-9999px;" aria-hidden="true"><input name="wpide_job_hp" tabindex="-1" autocomplete="off"></p>';
$html .= wp_nonce_field( 'wpide_job', 'wpide_job_nonce', false, false );
$html .= '<p><button type="submit">Send application</button></p></form></div>';
return $html;
} );
Notes
Use [wpide_job_application position="Senior Designer"] to name the role and change the size limit and recipient at the top; CVs are never kept on the server.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.