Skip to content

Instantly share code, notes, and snippets.

@iuriemalai
Created December 19, 2015 08:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iuriemalai/5bad5e05c92b1cec10db to your computer and use it in GitHub Desktop.
Save iuriemalai/5bad5e05c92b1cec10db to your computer and use it in GitHub Desktop.
This is code creates a form so that posts can be created or edited from the front end
<?php
/*
* Plugin Name: Front Post
* Plugin URI:
* Description: This is a forked code of TheDeadMedic that creates a form so that posts can be created or edited from the front end. See here the original: http://wordpress.stackexchange.com/a/210662/25187
* Version: 0.1
* Author:
* Author URI:
* Text Domain: front-post
*/
class WPSE_Submit_From_Front {
const NONCE_VALUE = 'frontend_add_edit_post';
const NONCE_FIELD = 'faep_nonce';
protected $pluginPath;
protected $pluginUrl;
protected $errors = array();
protected $data = array();
protected $postID;
function __construct() {
$this->pluginPath = plugin_dir_path( __file__ );
$this->pluginUrl = plugins_url( '', __file__ );
if( 'POST' == $_SERVER['REQUEST_METHOD'] && isset( $_POST['postid'] ) ) {
$this->postID = $_POST['postid']; //echo 'Post ID is ' . $this->postID . '<br>';
}
add_action( 'wp_enqueue_scripts', array( $this, 'addStyles' ) );
add_shortcode( 'post_from_front', array( $this, 'post_shortcode' ) );
// Listen for the form submit & process before headers output
add_action( 'template_redirect', array( $this, 'handleForm' ) );
}
function addStyles() {
wp_enqueue_style( 'submitform-style', "$this->pluginUrl/submit-from-front.css" );
}
/**
* Shortcodes should return data, NOT echo it.
*
* @return string
*/
function post_shortcode() {
if ( ! current_user_can( 'publish_posts' ) )
return sprintf( '<p>To add or edit a post you must be <a href="%s">logged in</a>.</p>', esc_url( wp_login_url( get_permalink() ) ) );
elseif ( $this->isFormSuccess() )
return '<p class="alert-box success"><span>Excellent: </span> The post was saved successfully!</p>';
else
return $this->getForm();
}
/**
* Process the form and redirect if sucessful.
*/
function handleForm() {
if ( ! $this->isFormSubmitted() )
return false;
// http://php.net/manual/en/function.filter-input-array.php
$data = filter_input_array( INPUT_POST, array(
'foo_id' => FILTER_DEFAULT,
'foo_date' => FILTER_DEFAULT,
'item_name' => FILTER_DEFAULT,
'item_description' => FILTER_DEFAULT,
'item_category' => FILTER_DEFAULT,
'item_location' => FILTER_DEFAULT,
'item_location2' => FILTER_DEFAULT,
'contact_person' => FILTER_DEFAULT,
'contact_phone' => FILTER_DEFAULT,
));
$data = wp_unslash( $data );
$data = array_map( 'trim', $data );
// You might also want to more aggressively sanitize these fields
// By default WordPress will handle it pretty well, based on the current user's "unfiltered_html" capability
$data['item_name'] = sanitize_text_field( $data['item_name'] );
$data['item_description'] = wp_check_invalid_utf8( $data['item_description'] );
$data['item_category'] = sanitize_text_field( $data['item_category'] );
$data['item_location'] = sanitize_text_field( $data['item_location'] );
$data['item_location2'] = sanitize_text_field( $data['item_location2'] );
$data['contact_person'] = sanitize_text_field( $data['contact_person'] );
$data['contact_phone'] = sanitize_text_field( $data['contact_phone'] );
$this->data = $data;
if ( ! $this->isNonceValid() )
$this->errors[] = 'Security check failed, please try again!';
if ( ! $data['item_name'] )
$this->errors[] = 'Please add a title!';
if ( ! $data['item_description'] )
$this->errors[] = 'Please add a description!';
if ( ! $data['item_category'] )
$this->errors[] = 'Please select a category!';
if ( ! $data['item_location'] )
$this->errors[] = 'Please select a location!';
//if( $data['contact_phone'] ) {
if( ! is_numeric( $data['contact_phone'] ) || $data['contact_phone'] <= 0 || strlen( $data['contact_phone'] ) > 9 ){
$this->errors[] = 'Add a valid phone number!';
}
//}
if ( ! $this->errors ) {
$post_id = wp_insert_post( array(
//'ID' => $this->postID, // here and only here the $this->postID is empty and I can't use it, so below
'ID' => $data['foo_id'], // I used a form hidden input field to get the post ID
'post_date' => $data['foo_date'], // the same for for the post date
'post_title' => $data['item_name'],
'post_content' => $data['item_description'],
'post_category' => array( $data['item_category'] ),
'tax_input' => array('location' => array( $data['item_location'] )),
'post_status' => 'publish',
));
if ( $post_id ) {
update_post_meta($post_id, 'item_location2', $data['item_location2']);
update_post_meta($post_id, 'contact_person', $data['contact_person']);
update_post_meta($post_id, 'contact_phone', $data['contact_phone']);
// Redirect to avoid duplicate form submissions
wp_redirect( add_query_arg( 'success', 'true' ) );
exit;
} else {
$this->errors[] = 'Sorry! Try again!';
}
}
}
/**
* Use output buffering to *return* the form HTML, not echo it.
*
* @return string
*/
function getForm() {
//if( 'POST' == $_SERVER['REQUEST_METHOD'] && isset( $_POST['postid'] ) ) {
if( 'POST' == $_SERVER['REQUEST_METHOD'] && !empty( $this->postID ) ) {
//echo 'Post ID is ' . $this->postID . '<br>'; // here the $this->postID is not empty yet
$post_to_edit = array();
$post_to_edit = get_post( $this->postID );
$this->data['foo_id'] = $post_to_edit->ID;
$this->data['foo_date'] = $post_to_edit->post_date;
$this->data['item_name'] = $post_to_edit->post_title;
$this->data['item_description'] = $post_to_edit->post_content;
$category = get_the_category( $post_to_edit->ID );
$this->data['item_category'] = $category[0]->term_id;
$location = get_the_terms( $post_to_edit->ID, 'location' );
$this->data['item_location'] = $location[0]->term_id;
$this->data['item_location2'] = get_post_meta( $post_to_edit->ID, 'item_location2', true );
$this->data['contact_person'] = get_post_meta( $post_to_edit->ID, 'contact_person', true );
$this->data['contact_phone'] = get_post_meta( $post_to_edit->ID, 'contact_phone', true );
}
ob_start();
?>
<?php foreach ( $this->errors as $error ) : ?>
<p class="error alert-box"><span>Error: </span><?php echo $error ?></p>
<?php endforeach ?>
<form id="frontpostform" method="post"> <!-- autocomplete="off"> -->
<fieldset>
<!-- Item name -->
<label for="item_name">Title<span class="required">*</span></label>
<input type="text" name="item_name" id="item_name" title="Add a title!" value="<?php
// "Sticky" field, will keep value from last POST if there were errors
if ( isset( $this->data['item_name'] ) )
echo esc_attr( $this->data['item_name'] );
?>" />
<!-- Item description -->
<label for="item_description">Description<span class="required">*</span></label>
<textarea name="item_description" id="item_description" rows="10" cols="35" title="Add a description!"><?php
if ( isset( $this->data['item_description'] ) )
echo esc_textarea( $this->data['item_description'] );
?></textarea>
<!-- Category -->
<label for="item_category">Category<span class="required">*</span></label>
<select name="item_category" title="Select a category!">
<option value=""><?php echo esc_attr(__('Select ...')); ?></option>
<?php
$categories = get_categories( 'hide_empty=0' );
foreach ($categories as $category) {
// keep post category value from last POST if there were errors
if ( isset( $this->data['item_category'] ) && $this->data['item_category'] == $category->cat_ID ) {
$option = '<option value="' . $category->cat_ID . '" selected="selected">';
} else {
$option = '<option value="' . $category->cat_ID . '">';
}
$option .= $category->cat_name;
//$option .= ' (' . $category->category_count . ')';
$option .= '</option>';
echo $option;
}
?>
</select>
<!-- Location -->
<label for="item_location">Location<span class="required">*</span></label>
<select name="item_location" title="Select a location!">
<option value=""><?php echo esc_attr(__('Select ...')); ?></option>
<?php
$locations = get_categories( 'hide_empty=0&taxonomy=location' );
foreach ($locations as $location) {
if ( isset( $this->data['item_location'] ) && $this->data['item_location'] == $location->cat_ID ) {
$option = '<option value="' . $location->cat_ID . '" selected="selected">';
} else {
$option = '<option value="' . $location->cat_ID . '">';
}
$option .= $location->cat_name;
//$option .= ' (' . $location->category_count . ')';
$option .= '</option>';
echo $option;
}
?>
</select>
<!-- Second Location -->
<div>
<label for="item_location2">Location 2</label>
<input type="text" name="item_location2" id="item_location2" title="Location 2 (optional)" value="<?php
// "Sticky" field, will keep value from last POST if there were errors
if ( isset( $this->data['item_location2'] ) )
echo esc_attr( $this->data['item_location2'] );
?>" />
</div>
<!-- Contact Person -->
<div>
<label for="contact_person">Contact person</label>
<input type="text" name="contact_person" id="contact_person" title="Contact person" value="<?php
// "Sticky" field, will keep value from last POST if there were errors
if ( isset( $this->data['contact_person'] ) )
echo esc_attr( $this->data['contact_person'] );
?>" />
</div>
<!-- Contact Phone -->
<div>
<label for="contact_phone">Contact phone<span class="required">*</span></label>
<input type="tel" name="contact_phone" id="contact_phone" maxlength="9" title="Contact phone" value="<?php
// "Sticky" field, will keep value from last POST if there were errors
if ( isset( $this->data['contact_phone'] ) )
echo esc_attr( $this->data['contact_phone'] );
?>" />
</div>
<!-- Submit button -->
<label for="submitForm"></label>
<div class="submitForm-wrapper">
// below are two hidden fields that will retain the post ID and date
<input type="hidden" name="foo_id" id="foo_id" value="<?php
// "Sticky" field, will keep value from last POST if there were errors
if ( isset( $this->data['foo_id'] ) )
echo esc_attr( $this->data['foo_id'] );
?>" />
<input type="hidden" name="foo_date" id="foo_date" value="<?php
// "Sticky" field, will keep value from last POST if there were errors
if ( isset( $this->data['foo_date'] ) )
echo esc_attr( $this->data['foo_date'] );
?>" />
<button type="submit" name="submitForm" id="submitForm" title="Save">Save</button>
</div>
</fieldset>
<?php wp_nonce_field( self::NONCE_VALUE , self::NONCE_FIELD ) ?>
</form>
<?php
return ob_get_clean();
}
/**
* Has the form been submitted?
*
* @return bool
*/
function isFormSubmitted() {
return isset( $_POST['submitForm'] );
}
/**
* Has the form been successfully processed?
*
* @return bool
*/
function isFormSuccess() {
return filter_input( INPUT_GET, 'success' ) === 'true';
}
/**
* Is the nonce field valid?
*
* @return bool
*/
function isNonceValid() {
return isset( $_POST[ self::NONCE_FIELD ] ) && wp_verify_nonce( $_POST[ self::NONCE_FIELD ], self::NONCE_VALUE );
}
}
new WPSE_Submit_From_Front;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment