Created
October 7, 2015 15:45
-
-
Save notomato/6f719276a0ec137f8e19 to your computer and use it in GitHub Desktop.
CMB2 front end forms - shortcode takes id of any metabox registered and outputs the appropriate frontend form.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
// @todo post editing | |
/** | |
* Gets the cmb instance | |
* | |
* @param string $metabox_id The id of the metabox as it is registered with `new_cmb2_box` e.g. `architect` | |
* @return CMB2 object | |
*/ | |
function th_get_frontend_form($metabox_id) { | |
$object_id = 'fake-oject-id'; | |
return cmb2_get_metabox($metabox_id, $object_id); | |
} | |
/** | |
* This function will output a front-end CMB2 form on any page. The shortcode should be entered as below: | |
* | |
* [frontend-form id="architect"] | |
* | |
* where `id` is the id of the metabox is it is registered with the `new_cmb2_box` function. | |
* | |
* @param array $atts Array of shortcode attributes | |
* @return string Form html | |
*/ | |
function th_frontend_form_shortcode( $atts = array() ) { | |
// Check we have the id attribute and it's a valid | |
if (!$atts['id'] && $cmb = th_get_frontend_form($atts['id'])) { | |
return false; | |
} | |
// Get CMB2 metabox object | |
$cmb = th_get_frontend_form($atts['id']); | |
// Get $cmb object_types | |
$post_types = $cmb->prop( 'object_types' ); | |
// Current user | |
$user_id = get_current_user_id(); | |
// Parse attributes | |
$atts = shortcode_atts( array( | |
'post_author' => $user_id ? $user_id : 1, // Current user, or admin | |
'post_status' => 'pending', | |
'metabox_id' => $atts['id'], | |
'post_type' => reset( $post_types ), // Only use first object_type in array | |
), $atts, 'frontend-form' ); | |
/* | |
* Let's add these attributes as hidden fields to our cmb form | |
* so that they will be passed through to our form submission | |
*/ | |
foreach ( $atts as $key => $value ) { | |
$cmb->add_hidden_field( array( | |
'field_args' => array( | |
'id' => "atts[$key]", | |
'type' => 'hidden', | |
'default' => $value, | |
), | |
) ); | |
} | |
// Initiate our output variable | |
$output = ''; | |
// Get any submission errors | |
if ( ( $error = $cmb->prop( 'submission_error' ) ) && is_wp_error( $error ) ) { | |
// If there was an error with the submission, add it to our ouput. | |
$output .= '<h3>' . sprintf( __( 'There was an error in the submission: %s', 'wds-post-submit' ), '<strong>'. $error->get_error_message() .'</strong>' ) . '</h3>'; | |
} | |
// If the post was submitted successfully, notify the user. | |
if ( isset( $_GET['post_submitted'] ) && ( $post = get_post( absint( $_GET['post_submitted'] ) ) ) ) { | |
// Get submitter's name | |
$name = get_post_meta( $post->ID, 'submitted_author_name', 1 ); | |
$name = $name ? ' '. $name : ''; | |
// Add notice of submission to our output | |
$output .= '<h3>' . sprintf( __( 'Thank you%s, your new post has been submitted and is pending review by a site administrator.', 'wds-post-submit' ), esc_html( $name ) ) . '</h3>'; | |
} | |
// Get our form | |
$output .= cmb2_get_metabox_form( $cmb, 'fake-oject-id', array( 'save_button' => __( 'Submit', 'wds-post-submit' ) ) ); | |
return $output; | |
} | |
add_shortcode('frontend-form', 'th_frontend_form_shortcode'); | |
/** | |
* Handles form submission on save. Redirects if save is successful, otherwise sets an error message as a cmb property | |
* | |
* @return void | |
*/ | |
function th_handle_frontend_submission() { | |
// var_dump($_POST); die; | |
// If no form submission, bail | |
if ( empty( $_POST ) || ! isset( $_POST['submit-cmb'], $_POST['object_id'] ) ) { | |
return false; | |
} | |
// Get CMB2 metabox object | |
$cmb = th_get_frontend_form($_POST['atts']['metabox_id']); | |
$post_data = array(); | |
// Get our shortcode attributes and set them as our initial post_data args | |
if ( isset( $_POST['atts'] ) ) { | |
foreach ( (array) $_POST['atts'] as $key => $value ) { | |
$post_data[ $key ] = sanitize_text_field( $value ); | |
} | |
unset( $_POST['atts'] ); | |
} | |
// Check security nonce | |
if ( ! isset( $_POST[ $cmb->nonce() ] ) || ! wp_verify_nonce( $_POST[ $cmb->nonce() ], $cmb->nonce() ) ) { | |
return $cmb->prop( 'submission_error', new WP_Error( 'security_fail', __( 'Security check failed.' ) ) ); | |
} | |
// Check title submitted | |
if ( empty( $_POST['title'] ) ) { | |
return $cmb->prop( 'submission_error', new WP_Error( 'post_data_missing', __( 'New post requires a title.' ) ) ); | |
} | |
// And that the title is not the default title | |
if ( $cmb->get_field( 'title' )->default() == $_POST['title'] ) { | |
return $cmb->prop( 'submission_error', new WP_Error( 'post_data_missing', __( 'Please enter a new title.' ) ) ); | |
} | |
/** | |
* Fetch sanitized values | |
*/ | |
$sanitized_values = $cmb->get_sanitized_values( $_POST ); | |
// Set our post data arguments | |
$post_data['post_title'] = $sanitized_values['title']; | |
unset( $sanitized_values['title'] ); | |
$post_data['post_content'] = $sanitized_values['submitted_post_content']; | |
unset( $sanitized_values['submitted_post_content'] ); | |
// Create the new post | |
$new_submission_id = wp_insert_post( $post_data, true ); | |
// If we hit a snag, update the user | |
if ( is_wp_error( $new_submission_id ) ) { | |
return $cmb->prop( 'submission_error', $new_submission_id ); | |
} | |
/** | |
* Other than post_type and post_status, we want | |
* our uploaded attachment post to have the same post-data | |
*/ | |
unset( $post_data['post_type'] ); | |
unset( $post_data['post_status'] ); | |
// Try to upload the featured image | |
$img_id = th_frontend_form_photo_upload( $new_submission_id, $post_data ); | |
// If our photo upload was successful, set the featured image | |
if ( $img_id && ! is_wp_error( $img_id ) ) { | |
set_post_thumbnail( $new_submission_id, $img_id ); | |
} | |
// Loop through remaining (sanitized) data, and save to post-meta | |
foreach ( $sanitized_values as $key => $value ) { | |
if ( is_array( $value ) ) { | |
$value = array_filter( $value ); | |
if( ! empty( $value ) ) { | |
update_post_meta( $new_submission_id, $key, $value ); | |
} | |
} else { | |
update_post_meta( $new_submission_id, $key, $value ); | |
} | |
} | |
/* | |
* Redirect back to the form page with a query variable with the new post ID. | |
* This will help double-submissions with browser refreshes | |
*/ | |
wp_redirect( esc_url_raw( add_query_arg( 'post_submitted', $new_submission_id ) ) ); | |
exit; | |
} | |
add_action( 'cmb2_after_init', 'th_handle_frontend_submission' ); | |
/** | |
* Handles uploading a file to a WordPress post | |
* | |
* @param int $post_id Post ID to upload the photo to | |
* @param array $attachment_post_data Attachement post-data array | |
*/ | |
function th_frontend_form_photo_upload( $post_id, $attachment_post_data = array() ) { | |
// Make sure the right files were submitted | |
if ( | |
empty( $_FILES ) | |
|| ! isset( $_FILES['submitted_post_thumbnail'] ) | |
|| isset( $_FILES['submitted_post_thumbnail']['error'] ) && 0 !== $_FILES['submitted_post_thumbnail']['error'] | |
) { | |
return; | |
} | |
// Filter out empty array values | |
$files = array_filter( $_FILES['submitted_post_thumbnail'] ); | |
// Make sure files were submitted at all | |
if ( empty( $files ) ) { | |
return; | |
} | |
// Make sure to include the WordPress media uploader API if it's not (front-end) | |
if ( ! function_exists( 'media_handle_upload' ) ) { | |
require_once( ABSPATH . 'wp-admin/includes/image.php' ); | |
require_once( ABSPATH . 'wp-admin/includes/file.php' ); | |
require_once( ABSPATH . 'wp-admin/includes/media.php' ); | |
} | |
// Upload the file and send back the attachment post ID | |
return media_handle_upload( 'submitted_post_thumbnail', $post_id, $attachment_post_data ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment