Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

With help from experts on this site, I have been able to put together a plugin that allows to choose and submit categories from the front-end. Further, in order to make it a bit more secure I have tried to include nonces and a honey pot in the form.

Although I am pretty sure that my nonce and honeypot are working fine, I am also not sure if I am checking things in the right order. You can see that I have tried to check for the honeypot first and then the main submit and then the nonce. Is it in the right order ? If not, what order should they be in? I believe if I do not check things in right order, I may get unexpected results. Entire plugin code is given below.

add_action('plugins_loaded','wpse_init_crowd_cats_class');
function wpse_init_crowd_cats_class(){
    new WPSECrowdCatsClass();
}


class WPSECrowdCatsClass { 

    function __construct() {

        // APPEND THE FORM AUTOMATICALLY TO EVERY POST
        add_filter( 'the_content', array( $this,'append_form' ) );

        // TEMPLATE ACTION TAG TO BE USED IN THEME
        // Usage: do_action('wpse_crowd_cats_form');
        // Usage: do_action('wpse_crowd_cats_form', $post_id, $taxonomy );
        add_action( 'wpse_crowd_cats_form', array( $this,'wpse_crowd_cats_form' ), 10, 2 );

        // FORM PROCESSING
        add_action( 'template_redirect', array( $this,'process_request' ) );

    }

    function process_request(){ // check submission

    if(!empty($_POST['pot-net']))
    return; //end process if field is not found empty.

    if ( ! isset($_POST['crowd-cat-radio']) || ! is_array($_POST['crowd-cat-radio']) )
    return;

    if (!isset( $_POST['nonce_name'] ) || ! wp_verify_nonce( $_POST['nonce_name'], plugin_basename( __FILE__ ) ) ) {
    print 'Sorry, your nonce did not verify.';
    exit;
   } else {    // continue to process form data



                // sanitize and check the input
        $suggested_terms = array_map( 'absint', $_POST['crowd-cat-radio'] );
        $post_id = absint( $_POST['crowd-cats-pid'] );
        $tax = $_POST['crowd-cats-tax'];
        if ( ! taxonomy_exists($tax) )
            return;

        // Allow only existing terms. Not sure if this is needed.
        $args = array( 'hide_empty' => false );
        $args = apply_filters( 'mcc_allowed_terms_args', $args, $post_id, $tax );
        $args['fields'] = 'ids';
        $allowed_terms = get_terms( $tax, $args );
        foreach ( $suggested_terms as $key => $term_id )
            if ( ! in_array( $term_id, $allowed_terms ) )
                unset( $suggested_terms[$key] );

        // Add terms to taxonomy
        $affected_terms = wp_set_object_terms( $post_id, $suggested_terms, $tax, false );
        update_term_cache($affected_terms);
        return $affected_terms;

    }
    }

    function get_form( $post_id=null, $tax='category' ) {

        if ( is_null($post_id) || ! taxonomy_exists($tax) )
            return false;

        $args = array( 'hide_empty' => false );
        $args = apply_filters( 'mcc_get_terms_args', $args, $post_id, $tax );
        $all_terms = get_terms( $tax, $args );

        if ( ! $all_terms )
            return false;

        $post_terms = wp_get_object_terms( $post_id, $tax, array( 'fields' => 'ids' ) );

        $permalink = get_permalink( $post_id );

        $out = "<form id='crowd-cats' action='$permalink' method='POST' >
            <ul >";

        foreach ( $all_terms as $t ) :

            $checked = in_array( $t->term_id, $post_terms) ? 'checked' : '';
            $out .= "<li>
                        <input type='checkbox' id='crowd-cat-$t->term_id' name='crowd-cat-radio[]' value='$t->term_id' $checked /> 
                        <label for='crowd-cat-$t->term_id' >".esc_attr($t->name)."</label>
                     </li>";

        endforeach;

        $out .= "</ul>
                   <input type='text' name='pot-net' style='visibility:hidden' value=''/>
                   <input type='submit' value='Submit' name='crowd-cats-submit'/>
                   <input type='hidden' value='".esc_attr($tax)."' name='crowd-cats-tax'/>
                   <input type='hidden' value='$post_id' name='crowd-cats-pid'/>";


                   $out .= wp_nonce_field( plugin_basename( __FILE__ ), 'nonce_name',true,false);
        $out .= "</form>";

        return $out;

    }



    function append_form($content){

        global $post;

        if ( 'post' != $post->post_type )
            return $content;

        $form = $this->get_form( $post->ID );

        if ( ! $form )
            return $content;

        return "$content \n $form";
    }


    function wpse_crowd_cats_form( $post_id=null, $taxonomy='category' ) {

        if ( is_null($post_id) ) {
            global $post;
            $post_id = $post->ID;
        }

        echo $this->get_form( $post_id, $taxonomy );
    }


} // end of class               
?>

If you will need me to put this on pastebin and point out the specifically concerned lines of code, please let me know.

share|improve this question
1  
This is a bit outside the scope of WordPress, you can check your "honeypot" by adding a value to it, personally I would check the nonce first. –  Wyck Sep 12 '13 at 4:09
    
I checked for the honeypot and it seems to work. Thanks for the hint. I will reform my question as the order may pose a real problem. –  gurung Sep 12 '13 at 4:15
    
Considering the advice above and after few more tests, I have decided to put the form submit check in this order. Check nonce first, then the honey pot and the main submit. With that I consider my question answered. Please let me know if anyone disagrees. –  gurung Sep 12 '13 at 6:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.