0

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.

3
  • 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
    Commented Sep 12, 2013 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
    Commented Sep 12, 2013 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
    Commented Sep 12, 2013 at 6:35

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.