web-dev-qa-db-fra.com

Formulaire de contact simple avec validation sur le terrain

Je cherche à créer un contact très simple pour que je puisse sortir avec un shortcode. J'ai le code suivant, mais il ne semble pas valider correctement et vous permet même de soumettre le formulaire sans entrer de détails. Toute chance que quelqu'un puisse expliquer comment valider le formulaire, s'il vous plaît. Je voudrais aussi ajouter un piège à pot de miel, car ils sont meilleurs que les captures imo, mais je suis assez nouveau en PHP. Toute aide serait super merci.

    function html_form_code() {
    echo '<form action="' . esc_url( $_SERVER['REQUEST_URI'] ) . '" method="post">';
    echo '<p>';
    echo 'Your Name (required) <br />';
    echo '<input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="' . ( isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : '' ) . '" size="40" />';
    echo '</p>';
    echo '<p>';
    echo 'Your Email (required) <br />';
    echo '<input type="email" name="cf-email" value="' . ( isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : '' ) . '" size="40" />';
    echo '</p>';
    echo '<p>';
    echo 'Your Message (required) <br />';
    echo '<textarea rows="10" cols="35" name="cf-message">' . ( isset( $_POST["cf-message"] ) ? esc_attr( $_POST["cf-message"] ) : '' ) . '</textarea>';
    echo '</p>';
    echo '<input type="text" name="content" id="content" value="" class="hpot" />';
    echo '<p><input type="submit" name="cf-submitted" value="Send"/></p>';
    echo '</form>';
}

function deliver_mail() {

  $errors = new WP_Error();
if ( isset( $_POST[ 'content' ] ) && $_POST[ 'content' ] !== '' ) {
  $errors->add( 'cheater', 'Sorry, this field should not be filled. Are you trying to cheat?' );
}
if ( isset( $_POST[ 'cf-name' ] ) && $_POST[ 'cf-name' ] == '' ) {
  $errors->add('error', 'Please fill in a valid name.' );
}

if ( isset( $_POST[ 'cf-email' ] ) && $_POST[ 'cf-email' ] == '' ) {
  $errors->add('error', 'Please fill in a valid email.' );
}

if ( isset( $_POST[ 'cf-message' ] ) && $_POST[ 'cf-message' ] == '' ) {
  $errors->add('error', 'Please fill in a valid message.' );
}

if ( empty( $errors->errors ) ){
  deliver_mail();
}
else {
  echo 'Please fill the required fields';
}


    // if the submit button is clicked, send the email
    if ( isset( $_POST['cf-submitted'] ) ) {

        // sanitize form values
        $name    = sanitize_text_field( $_POST["cf-name"] );
        $email   = sanitize_email( $_POST["cf-email"] );
        $message = esc_textarea( $_POST["cf-message"] );

        // get the administrator's email address
        $to = get_option( 'admin_email' );

        $headers = "From: $name <$email>" . "\r\n";

        // If email has been process for sending, display a success message
        if ( wp_mail( $to, $message, $headers ) ) {
            echo '<div class=cf-success>';
            echo '<p>Thank you for contacting us '. $name .', a member of our team will be in touch with you shortly.</p>';
            echo '</div>';
        } else {
            echo '<div class=cf-error>';
            echo '<p>An unexpected error occurred</p>';
            echo '</div>';
        }
    }
}

function cf_contact_form() {
    ob_start();
    deliver_mail();
    html_form_code();

    return ob_get_clean();
}

add_shortcode( 'contact_form', 'cf_contact_form' );

Alors serait-ce comme ci-dessus? Merci

Je reçois également cette erreur lorsque j'essaie d'exécuter les contrôles sur le terrain.

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes) in /Applications/MAMP/htdocs/centenary-framework/wp-content/themes/cent_framework/assets/inc/core/contact-form.php on line 147

Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 262144 bytes) in /Applications/MAMP/htdocs/centenary-framework/wp-includes/load.php on line 671

Je ne suis pas sûr de ce que cela signifie. = (

MODIFIER

Ces problèmes ont maintenant été corrigés. Je colle le code de travail ci-dessous dans l'espoir que cela aidera quelqu'un à l'avenir. Un grand merci à tous ceux qui ont aidé !!

// Form markup
 function html_form_code()
 {
     ?>

 <form action="<?php esc_url($_SERVER['REQUEST_URI']);
     ?>" method="post">
   <p>Your Name (required)<br />
     <input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="<?php isset($_POST['cf-name']) ? esc_attr($_POST['cf-name']) : '';
     ?>" size="40" />
   </p>
   <p>Your Email (required)<br />
     <input type="email" name="cf-email" value="<?php isset($_POST['cf-email']) ? esc_attr($_POST['cf-email']) : '';
     ?>" size="40" />
   </p>
   <p>Your Message (required)<br />
     <textarea rows="10" cols="35" name="cf-message"><?php isset($_POST['cf-message']) ? esc_attr($_POST['cf-message']) : '';
     ?></textarea>
   </p>
   <p><input type="submit" name="cf-submitted" value="Send"/></p>
 </form>

 <?php

 }

// Form validation
 function my_validate_form()
 {
     $errors = new WP_Error();

     if (isset($_POST[ 'content' ]) && $_POST[ 'content' ] !== '') {
         $errors->add('cheater', 'Sorry, this field should not be filled. Are you trying to cheat?');
     }

     if (isset($_POST[ 'cf-name' ]) && $_POST[ 'cf-name' ] == '') {
         $errors->add('name_error', 'Please fill in a valid name.');
     }

     if (isset($_POST[ 'cf-email' ]) && $_POST[ 'cf-email' ] == '') {
         $errors->add('email_error', 'Please fill in a valid email.');
     }

     if (isset($_POST[ 'cf-message' ]) && $_POST[ 'cf-message' ] == '') {
         $errors->add('message_error', 'Please fill in a valid message.');
     }

     return $errors;
 }

// Form delivery
 function deliver_mail($args = array())
 {

  // This $default array is a way to initialize some default values that will be overwritten by our $args array.
  // We could add more keys as we see fit and it's a Nice way to see what parameter we are using in our function.
  // It will only be overwritten with the values of our $args array if the keys are present in $args.
  // This uses WP wp_parse_args() function.
  $defaults = array(
    'name' => '',
    'email' => '',
    'message' => '',
    'to' => get_option('admin_email'), // get the administrator's email address
  );

     $args = wp_parse_args($args, $defaults);

     $headers = "From: {$args['name']}  <{$args['email']}>"."\r\n";

  // Send email returns true on success, false otherwise
  if (wp_mail($args['to'], $args['message'], $headers)) {
      return;
  } else {
      return false;
  }
 }

// Form sanitize
function my_sanitize_field($input)
{
    return trim(stripslashes(sanitize_text_field($input)));
}

// Form succsess message
function my_form_message()
{
    global $errors;
    if (is_wp_error($errors) && empty($errors->errors)) {
        echo '<div class="cf-success">';
        echo '<p>Thank you for contacting us '.$_POST['cf-name'].', a member of our team will be in touch with you shortly.</p>';
        echo '</div>';

    //Empty $_POST because we already sent email
    $_POST = '';
    } else {
        if (is_wp_error($errors) && !empty($errors->errors)) {
            $error_messages = $errors->get_error_messages();
            foreach ($error_messages as $k => $message) {
                echo '<div class="cf-error '.$k.'">';
                echo '<p>'.$message.'</p>';
                echo '</div>';
            }
        }
    }
}

// Form shortcode
add_shortcode('contact_form', 'cf_contact_form');
function cf_contact_form()
{
    ob_start();

    my_form_message();
    html_form_code();

    return ob_get_clean();
}

// Error validation
add_action('init', 'my_cf_form');
function my_cf_form()
{
    if (isset($_POST['cf-submitted'])) {
        global $errors;
        $errors = my_validate_form();
        if (empty($errors->errors)) {
            $args = array(
         'name' => my_sanitize_field($_POST['cf-name']),
         'email' => my_sanitize_field($_POST['cf-email']),
         'message' => my_sanitize_field($_POST['cf-message']),
       );
            deliver_mail($args);
        } else {
            return $errors;
        }
    }
}
2
user53340

Vous n'avez aucun mécanisme de validation.

Votre logique devrait être un peu dans cette direction

  • Soumettre le formulaire
  • Vérifier les champs soumis ($ _POST) par rapport aux valeurs attendues
  • Si tout semble bien envoyer
  • Si quelque chose ne se passe pas comme prévu, enregistrez une erreur (vous pouvez utiliser WP_Error ()) et reconstruire le formulaire en affichant le message d'erreur (et éventuellement en remplissant à nouveau les champs avec les valeurs "correctes" précédentes).

Tout ce que je vois ici, c’est que vous désinfectez les entrées, mais vous ne validez pas si vos entrées ont les valeurs que vous attendez (e-mail, téléphone, longueur du nom, etc.).

Vous envoyez votre email, que vos champs aient les valeurs attendues ou non. Votre else générera une erreur UNIQUEMENT si wp_mail() échoue, et non si vos champs réels ont des valeurs validées ou non.

Pour ajouter un pot de miel, vous devez simplement ajouter un champ caché dans votre formulaire que vous vous attendez à être vide.

Par exemple, dans votre code HTML

<input type="text" name="content" id="content" value="" class="hpot" />

Ensuite, lorsque vous validez votre entrée de formulaire, vous vous attendez à ce que ce champ soit vide.

en utilisant WP_Error class, vous pouvez ajouter des erreurs à l’objet afin de les utiliser ultérieurement pour informer l’utilisateur ou quoi que ce soit d'autre.

$errors = new WP_Error();
if ( isset( $_POST[ 'content' ] ) && $_POST[ 'content' ] !== '' ) {
  $errors->add( 'cheater', 'Sorry, this field should not be filled. Are you trying to cheat?' );
}

Ainsi, la vérification PHP ci-dessus est une méthode que vous pouvez utiliser pour valider votre formulaire. Vous ajoutez simplement des instructions if avec les valeurs attendues de votre formulaire (bien entendu, cela peut être étendu pour valider votre entrée). Ensuite, si vous utilisez la classe WP_Error, en ajoutant à l’objet si des erreurs sont détectées, il vous suffit de faire une dernière vérification avant de l’envoyer.

if ( empty( $errors->errors ) ){
  deliver_mail();
}
else {
  // Here you can use your $_POST variable to repopulate the form with accepted 
  // form value (you would have to update your html_form_code() to accept an argument) 
  // or just reload the contact page displaying an error message.
}

MODIFIER

Ok, voici un exemple plus complet

CSS

ajoutez ceci à votre css pour que le champ ne soit pas affiché dans le navigateur

.hpot {
  display: none;
}

PHP

Voici une autre façon d'écrire votre fonction html, c'est juste plus facile à lire

function html_form_code() { ?>

<form action="<?php esc_url( $_SERVER['REQUEST_URI'] ); ?>" method="post">
  <p>Your Name (required)<br />
    <input type="text" name="cf-name" pattern="[a-zA-Z0-9 ]+" value="<?php isset( $_POST["cf-name"] ) ? esc_attr( $_POST["cf-name"] ) : ''; ?>" size="40" />
  </p>
  <p>Your Email (required)<br />
    <input type="email" name="cf-email" value="<?php isset( $_POST["cf-email"] ) ? esc_attr( $_POST["cf-email"] ) : ''; ?>" size="40" />
  </p>
  <p>Your Message (required)<br />
    <textarea rows="10" cols="35" name="cf-message"><?php isset( $_POST["cf-message"] ) ? esc_attr( $_POST["cf-message"] ) : ''; ?></textarea>
  </p>
  <p><input type="submit" name="cf-submitted" value="Send"/></p>
</form>

<?php } 

Votre fonction deliver_mail ne doit pas écouter $_POST ni désinfecter. De plus, l’utilisation du courrier électronique de l’utilisateur des formulaires comme en-tête from peut poser problème avec certains fournisseurs d’accès Internet, car le courrier électronique est envoyé à partir de votre domaine. avec un domaine ne correspondant pas à l'adresse de (peut être considéré comme du spam). Utilisez une adresse de votre domaine ici (par exemple, [email protected]) et définissez l'adresse électronique de l'utilisateur dans le corps de l'e-mail (dans le message). Vous pouvez également le définir comme un champ reply-to pour plus de commodité.

function deliver_mail( $args = array() ) {

  // This $default array is a way to initialize some default values that will be overwritten by our $args array.
  // We could add more keys as we see fit and it's a Nice way to see what parameter we are using in our function.
  // It will only be overwritten with the values of our $args array if the keys are present in $args.
  // This uses WP wp_parse_args() function.
  $defaults = array(
    'name'    => '',
    'email'   => '',
    'message' => '',
    'to'      => get_option( 'admin_email' ), // get the administrator's email address
  );

  $args = wp_parse_args( $args, $defaults );

  $headers = "From: {$args['name']} <{$args['email']}>" . "\r\n";

  // Send email returns true on success, false otherwise
  if( wp_mail( $args['to'], $args['message'], $headers ) ) {
    return;
  }
  else {
    return false;
  }
}

Votre fonction de validation

function my_validate_form() {

  $errors = new WP_Error();

  if ( isset( $_POST[ 'content' ] ) && $_POST[ 'content' ] !== '' ) {
    $errors->add( 'cheater', 'Sorry, this field should not be filled. Are you trying to cheat?' );
  }

  if ( isset( $_POST[ 'cf-name' ] ) && $_POST[ 'cf-name' ] == '' ) {
    $errors->add('name_error', 'Please fill in a valid name.' );
  }

  if ( isset( $_POST[ 'cf-email' ] ) && $_POST[ 'cf-email' ] == '' ) {
    $errors->add('email_error', 'Please fill in a valid email.' );
  }

  if ( isset( $_POST[ 'cf-message' ] ) && $_POST[ 'cf-message' ] == '' ) {
    $errors->add('message_error', 'Please fill in a valid message.' );
  }

  return $errors;
}

Votre fonction de désinfection. Voici une fonction de désinfection générale qui supprime les espaces et échappe au code HTML, mais cette opération peut s'avérer plus complexe en fonction des champs de saisie que vous avez. Mais je pense que pour toi c'est assez

function my_sanitize_field( $input ){

  return trim( stripslashes( sanitize_text_field ( $input ) ) );

}

En affichant votre message de réussite/d'erreur, vous pouvez l'utiliser pour récupérer l'objet WP_Error

function my_form_message(){

  global $errors;
  if( is_wp_errors( $errors ) && empty( $errors->errors ) ){

    echo '<div class="cf-success">';
    echo '<p>Thank you for contacting us '. $_POST['cf-name'] .', a member of our team will be in touch with you shortly.</p>';
    echo '</div>';

    //Empty $_POST because we already sent email
    $_POST = '';

  }
  else {

  if( is_wp_errors( $errors ) && ! empty( $errors->errors ) ){

    $error_messages = $errors->get_error_messages(); 
    foreach( $error_messages as $k => $message ){
        echo '<div class="cf-error ' . $k . '">';
        echo '<p>' . $message . '</p>';
        echo '</div>';

    }

  }

}

Enfin votre fonction shortcode

add_shortcode( 'contact_form', 'cf_contact_form' );
function cf_contact_form() {

  ob_start();

  my_form_message();
  html_form_code();

  return ob_get_clean();
}

Et raccordez à init pour écouter $_POST avant de rendre notre formulaire et de générer le $errors si nous en trouvons ou si nous l'envoyons si tout va bien.

add_action( 'init', 'my_cf_form');
function my_cf_form(){

  if( isset( $_POST['cf-submitted'] ) ) {

    global $errors;
    $errors = my_validate_form(); 
    if( empty( $errors->errors ) ){

       $args = array(
         'name'    => my_sanitize_field( $_POST['cf-name'] ),
         'email'   => my_sanitize_field( $_POST['cf-email'] ),
         'message' => my_sanitize_field( $_POST['cf-message'] ),
       );
       deliver_mail( $args );
    }
    else {
      return $errors;
    } 
  }
}

N'oubliez pas de toujours préfixer vos fonctions afin d'éviter tout conflit avec les noms de fonction des autres plugins.

2
bynicolas

Puisque vous êtes un peu nouveau sur PHP, voici un bel exemple d’un pot de miel simple côté serveur .

Vous allez configurer un champ de texte masqué dans votre formulaire et vérifier si ce n'est pas vide pour attraper le spam.

Formulaire HTML

<label for="honeypot" class="bot">Leave blank if you are human</label>
<input type="text" id="honeypot" name="honeypot" class="bot" />

CSS

.bot { display:none }

PHP (simplifié)

 if ( $_POST() ) {
    $name = strip_tags(urldecode(trim($_POST['name'])));
    // OR
    $name = test_input($_POST['name']; 
    $honeypot = $_POST('honeypot');
    // Only checks IF something is in it.
    if ($honeypot){
      $msg = "You are a bot";
    } else {
      $msg = "Success";
      // Additional processing
      if ($name){
          mail(...)
      }
    }
    echo $msg;
 }

Après une brève recherche, j'ai également trouvé cette fonction que vous pourriez utiliser.

function test_input($data) {
  $data = trim($data);
  $data = stripslashes($data);
  $data = htmlspecialchars($data);
  return $data;
}
0
Greg McMullen