0

I've fallen in the (unknown to me) abyss of the custom forms and custom form handlers in wordpress. I just need a working contact form without the need of installing any plugin. I would normally do this with the $_SESSION superglobal (to pass error and success messages) and a post-redirect-get pattern (avoiding double sends with page reloads). The code would look like this

<form class="di-contact" method="post" action="<?php echo get_template_directory_uri() ?>/contact.php" style="width: 50%; margin: 0 auto">
<h3 id="titulo-single"><?php the_title() ?></h3>
<label for="di-name"><?php _e('Name', 'di-news-blog'); ?>:</label>
<input class="uk-input" type="text" id="di-name"  name="di-name"><br>
<label for="di-email"><?php _e('E-mail', 'di-news-blog'); ?>:</label>
<input class="uk-input" type="email" id="di-email"  name="di-email"><br>
<label for="di-message"><?php _e('Message', 'di-news-blog'); ?>:</label>
<textarea class="uk-textarea" id="di-message"  name="di-message"></textarea><br>
<input type="submit" name="di-submit" value="<?php _e('Submit', 'di-news-blog'); ?>">
</form>

Then i would code something like this in contact.php:

<?php
////////////////////   MAIL PROPERTIES      ///////////////////

$to = get_option('admin_email');
$from = htmlentities($_POST['di-email']);   
$subject = __('Message from ','di-news-blog'). get_bloginfo('blogname');

////////////////////////   HEADERS   ////////////////////////

$headers = "From:" . $from . "\r\n";
$headers .= "Reply-To:" . $from . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n";

////////////////////////   MESSAGE  ////////////////////////

$message = '<p>You got a message from <strong>'  . 
htmlentities($_POST['di-name']) . '</strong><p/>';
$message .= '<p><strong>Email:</strong> ' . $from . '</p>';
$message .= '<strong>Message:</strong><br/>' . 
htmlentities($_POST['di-message']);

//////////////////////////////////////////////////////////////
if ( isset( $_POST['di-submit'] ) ) {
if (  ! empty( $_POST['di-email'] ) || ! empty( $_POST['di-email'] ) ||  ! empty( $_POST['di-message'] ) ) {
    mail($to, $subject, $message, $headers); 
    $_SESSION['success'] = '<p class="success">' . __('Message sent succesfully', 'di-news-blog') . '</p>';

    wp_redirect(get_template_directory_uri() . '/contact'); exit;
} else {
    $_SESSION['error'] = '<p class="failed">' . __('Please enter all the requested data and try again', 'di-news-blog') . '</p>';

   wp_redirect(get_template_directory_uri() . '/contact'); exit;
  }
}

But nooby me, i just found out wordpress functions like get_option() or __('','') won't work in a page like contact.php, and also the $_SESSION superglobal, i was told i could make it work with something like that in the functions.php file:

// SESSIONS //////
function register_my_session(){
    if( ! session_id() ) {
        session_start();
    }
}

add_action('init', 'register_my_session', 1);

function cyb_session_start() {
    if( ! session_id() ) {
        session_start();
    }
}

function cyb_session_end() {
    session_destroy();
}

add_action( 'init', 'cyb_session_start', 1 );
add_action( 'wp_logout', 'cyb_session_end' );
add_action( 'wp_login', 'cyb_session_end' );

which didn't work.
Sorry my ignorance, but i couldn't find documentation (that i understand, not a nijna php dev) on how this could be achieved.

Marcos Di Paolo
  • 527
  • 1
  • 5
  • 22

1 Answers1

1

I would send the form POST back to /contact (the contact form page) and handle the form send from there.

To keep the template clean I'd normally create a function in functions.php which you can then call from the template, and I'd create a specific contact page template in the theme called page-contact.php (which will automatically be used for the page with the slug contact). This would be the only template that needs to call the contact form handler function.

You can actually include Wordpress within your own custom (non-template) files so that you can use wordpress functions, but I don't think it's necessary for what you're trying to do.

A very minimal example:

page-contact.php

<?php get_header(); ?>

<?php if(have_posts()) : ?>
<?php while(have_posts()) : the_post(); ?>

<h1><?php the_title(); ?></h1>
<?php the_content(); ?>
<?php contact_form_handler(); ?>

<?php endwhile; ?>

<?php else : ?>
<?php include_once 'templates/no-posts-found.php'; ?>
<?php endif; ?>

<?php get_footer(); ?>

functions.php

function contact_form_handler() {

  /* If this is a postback, handle the contact form */
  if(isset($_POST['message'])) {

    //Try to send the message and set $successful to true or false

    echo ($successful ? "Message sent!" : "An error occurred");

  } 

  /* Otherwise display the form itself */
  else {
    include_once 'templates/contact-form.php';
  }
}

templates/contact-form.php

<form method="POST" action="/contact">
  <textarea name="message"></textarea>
  <input type="submit" value="Submit" />
</form>
Andrew Chart
  • 623
  • 6
  • 10
  • thanks a lot, i'll try it in a minute and log back. Just for the curiosity, how can you include Wordpress within your own custom (non-template) files so that you can use wordpress functions?? – Marcos Di Paolo Apr 02 '18 at 23:32
  • Looks like the simplest way is including wp-load.php from the wordpress core directory. See: https://stackoverflow.com/questions/15304926/how-to-include-wordpress-functions-in-custom-php-file I can't say I know what security or performance implications that may have though. – Andrew Chart Apr 02 '18 at 23:36