My code was checked and seems OK so maybe the problem lies in the htaccess file whose content on my online server is:

SetEnv PHP_VER 5_4
Options -Indexes
ErrorDocument 404 /index.php
RewriteEngine on 
RewriteCond %{HTTP_HOST} !^www.example.fr$
RewriteRule ^(.*)   http://www.example.fr/$1  [QSA,L,R=301] 

Any reason why this htaccess would prevent forms from submitting correctly on my site?

Just in case here’s my code:

<form id='contact_form_mmt' action='<?php echo bloginfo("wpurl"); ?>/contact' method='post'>
  <input type="text" name="contact_nom" placeholder="Votre nom *" data-validation='length' data-validation-length="min3" data-validation-error-msg='<?php echo $text_too_short_or_empty; ?>'>  
  <input type="text" name="contact_prenom" placeholder="Votre prénom *" data-validation='length' data-validation-length="min3" data-validation-error-msg='<?php echo $text_too_short_or_empty; ?>'>
  <input type="text" name="contact_mail" placeholder="Votre mail *" data-validation='email' data-validation-length="min3" data-validation-error-msg='<?php echo $email_valid; ?>'>
  <select name="contact_destinataire">
    <option value="contact@example.com|Information générales">Information générales</option>
    <option value="webmaster@example.fr|Problèmes liés au site">Problèmes liés au site</option>
  </select>
  <textarea name="contact_message" placeholder="Message *"data-validation='length' data-validation-length="min3" data-validation-error-msg='<?php echo $text_too_short_or_empty; ?>'></textarea>  
  <input type="hidden" name="sub" value="1">  
  <input type="submit" value="envoyer">
</form>

PHP (I know the syntax is ugly, I’ll improve that):

if ( isset($_POST['sub']) ) $sub = $_POST['sub']; else $sub = ''; 
if ( isset($_POST['contact_nom']) ) $contact_nom = $_POST['contact_nom']; else $contact_nom = ''; 
if ( isset($_POST['contact_prenom']) ) $contact_prenom = $_POST['contact_prenom' ]; else $contact_prenom = ''; 
if ( isset($_POST['contact_mail']) ) $contact_mail = $_POST['contact_mail']; else $contact_mail=""; 
if ( isset($_POST['contact_sujet']) ) $contact_sujet = $_POST['contact_sujet']; else $contact_sujet=""; 
if ( isset($_POST['contact_destinataire']) ) $contact_destinataire = $_POST['contact_destinataire']; else $contact_destinataire=""; 
if ( isset($_POST['contact_message']) ) $contact_message = $_POST['contact_message']; else $contact_message=""; 

3 Answers
3

The best way to deal with Form Posts in WordPress is to use a special endpoint, /wp-admin/admin-post.php.

POST data can be messed up, both by the WP Query call, and by any redirects that happen.

So you set up your form with this action:

<form action="<?= admin_url('admin-post.php') ?>" method="post">
<input type="hidden" name="action" value="special_action">
<?php wp_nonce_field('special_action_nonce', 'special_action_nonce'); ?>

Then you can handle the form by adding an action to your theme or plugin:

add_action('admin_post_nopriv_special_action', ['My\Plugins\FormController', 'specialAction']);
add_action('admin_post_special_action', ['My\Plugins\FormController', 'specialAction']);

Note that WordPress constructs a special action, based on the action value in the form, admin_post_no_priv_special_action (if you’re logged out) and admin_post_special_action (if you’re logged in). You can point these in different locations.

These action endpoints will always have access to POST, and will never trigger a redirect (which is often what WordPress does for pretty routes… it often routes: site.com/about to site.com/?pageName=about).

Once you’ve handled the form as you want, you can do a wp_redirect() to get to where you need it to be. This is also helpful because an accidental page refresh will not re-send the form.

Much lengthier doco can be found here:
https://www.sitepoint.com/handling-post-requests-the-wordpress-way/

Leave a Reply

Your email address will not be published. Required fields are marked *