DevinVinson / WordPress-Plugin-Boilerplate

[WordPress] A foundation for WordPress Plugin Development that aims to provide a clear and consistent guide for building your plugins.
http://wppb.io
7.65k stars 2.25k forks source link

Processing Forms In Public/Partials/ #381

Open TheBigK opened 8 years ago

TheBigK commented 8 years ago

I'm new to both PHP and WPBP and this could be a really dumb question. I'll however really appreciate your help.

I've my HTML Form inside public/partials/crzy-resume-builder-public-display-resume-form.php , which renders fine using a shortcode.

<form method="post" action="../class-crzy-resume-builder-public.php" id="crzy-resume-form" >

    <div class="input-group">
        <input type="text" name="resumeTitle" class="form-control">
   <span class="input-group-btn">
        <button class="btn btn-default" type="submit">Go!</button>
   </span>
    </div>

</form>

My file class-crzy-resume-builder-public.php has this -

class Crzy_Resume_Builder_Public {
......
........
/**
     * Process the resume input form and save the title
     */
    public function crzy_process_resume_form () {

        $resume_title = $_POST['resumeTitle'];
        $postarr = array('post_title' => $resume_title, 'post_type' => 'crzy_resume');
        $result = wp_insert_post($postarr);
        $stop = 'stop'; //For the sake of adding a break point for debugger. 

    }

}

if($_SERVER['REQUEST_METHOD'] == 'POST') {
    $processResume = new Crzy_Resume_Builder_Public();
    $processResume->crzy_process_resume_form();
}

I'm however not able to figure out why is WordPress directly getting inside the the function when I refresh the form page?

What is the right way to process my form after I press 'Go' button?

Rocks360 commented 8 years ago

Hello TheBigK, output with your shordcode a Form like the following:

`

<input placeholder="enter a Value" type="text" id="somevalue" name="someValue"></input>
<input type="submit" value="Process Form"></input>

`

Go to the main class of your Plugin (the class-plugin-name.php) and register in the define_public_hooks() function something like this:

$this->loader->add_action( 'admin_post_process_form', $plugin_public, 'plugin_name_process_form' );

This line of code adds a custom handler function for the action "process_form" in your Plugin_Name_Public class. see here for more information https://codex.wordpress.org/Plugin_API/Action_Reference/admin_post_(action) Now add the function "plugin_name_process_form" as a public function to your Plugin_Name_Public class.

`

public function plugin_name_process_form() {

    // proof if the user has the requested capabilities
    // https://developer.wordpress.org/plugins/security/checking-user-capabilities/
    if ( ! current_user_can( 'beschlussdatenbank_save_request' ) )
    return; // if not return

    // securing the input. NEVER TRUST USER INPUT! 
    //https://developer.wordpress.org/plugins/security/securing-input/
    $someFormValue = sanitize_text_field($_POST['someValue']);

    // do some sing with the form input data like save it in a database
    global $wpdb; // https://codex.wordpress.org/Class_Reference/wpdb

    // after processing redirect back to the side
    //https://codex.wordpress.org/Function_Reference/wp_redirect
    // here hardcoded  just for showing purposes only 
    // redirects to a side and add a Get value "message" that contains that the form is processed successful 
    wp_redirect( "http://www.development.mywebside.com/aformside/?page=Antragerstellen&message='".urlencode('Form successful processed!')."'" );

}

`

Now when the submit button is clicked wordpress will load again and in the admin-post.php there is a function that shows if a post value with the name "action" exist. Because I added a hidden input field in the form above with the name 'action' so it exist. So wordpress is calling the function "plugin_name_process_form" in the public Class of your Plugin and execute it and redirects to your side when everything is finished.

I didn't run the code. It's just an example of how you can handle it.

Hope it will help you a little bit. Is my first answer post :D

good luck

TheBigK commented 8 years ago

First of all, super thank you! I literally spent about 6 hours trying to figure out a solution. Was able to achieve what I wanted. I had no clue that admin-post.php would hold the 'answer' I was looking for.

I'm now even more curious to know if this is the way to handle all public forms - I mean, by referring to the do_action("adminpost{$action}" ); or there are other ways to process forms?

Also, would really appreciate if you could give me pointers on how to redirect to the newly created post type, after the form submission is successful. All I'm doing is inserting the title through my front-end form to the custom post type. I'd like to redirect to the newly create CPT after submission is successful.

Rocks360 commented 8 years ago

Instead of use "adminpost{$action}" you should use the "admin_postnopriv{$action}" hook. ( http://adambrown.info/p/wp_hooks/hook/admin_post_nopriv_%7B$action%7D ) Because there is no authentication. Or you use the "wpajax{$action}" and "wp_ajaxnonpriv{$action}" ( https://codex.wordpress.org/AJAX_in_Plugins ) I didn't now if this is the best practice but I still not find something better to do the job in my plugin. But if someone have/ find a better approach it wood be great if he could share it here :)

TheBigK commented 8 years ago

@Rocks360 - Thanks! Any pointers on redirecting the user to the new post created?

Rocks360 commented 8 years ago

Oh yeah. So maybe you can take a look to the settings Permalinks in the admin backend of wordpress. There are the syntax of your urls. Then you can do something to encode the url for your needs. Also take a look to this link: https://developer.wordpress.org/reference/functions/get_permalink/ Maybe that can help you too. Good luck

Rocks360 commented 8 years ago

Oh and check out also the closed issues here. There are also some helpful information about how to do stuff.

TonyKnibb-MakaraHealth commented 2 years ago

I'm not getting any $_POST data in my function. Anyone have an ideas?

Hooks (class-m-contact-form.php):

private function define_public_hooks() {

    $plugin_public = new M_Contact_Form_Public( $this->get_plugin_name(), $this->get_version() );

        //Hooks for contact form
        $this->loader->add_action( 'admin_post_nopriv_reg_event', $plugin_public, 'mcf_reg_event' );
        $this->loader->add_action( 'admin_post_reg_event', $plugin_public, 'mcf_reg_event' );
}

Form (contact.php):

<form method="post" enctype="text/plain" name="m_contact_reg_event" action="<?php echo esc_url( admin_url('admin-post.php') ); ?>?action=reg_event">
                <input type="hidden" name="action" value="reg_event">
                <input type="hidden" name="_nonce" value="<?php echo $_nonce; ?>" />

                <input type="text" id="mcf-name" name="mcf-name" value=""/>
                <input type="text" id="mcf-email" name="mcf-email" value=""/>

                <input type="submit" value="Submit"/>
</form>

Method (class-m-contact-form-public.php):

function mcf_reg_event() {
        /**
         * At this point, $_GET/$_POST variable are available
         *
         * We can do our normal processing here
         */

        // Sanitize the POST field
        // Generate email content
        // Send to appropriate email

        var_dump($_POST);
}