Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm facing the following situation, i've created an event-custom-post-type and display those with a single-event.php template. I've also implemented a signup-form in that template and all worked just fine. However, I've noticed that when the title gets changed of the event (and not the slug), submitting the form will result in a 404 (or in my case a notification that blog-post isn't found). The work-around would be to change the slug accordingly to the title, but i've noticed that that aswell doesn't always work, especially when they put multiple ... in a title for example. It's driving me nuts that i can't seem to figure out where I went wrong :(

How one of you can show me in the right direction to get this solved :D

This is the code of my custom post type

/**
 * Flushes rewrite rules on plugin activation to ensure event posts don't 404
 * http://codex.wordpress.org/Function_Reference/flush_rewrite_rules
 */

function ep_eventposts_activation() {
    ep_eventposts();
    flush_rewrite_rules();
}

register_activation_hook( __FILE__, 'ep_eventposts_activation' );

function ep_eventposts() {

    /**
     * Enable the event custom post type
     * http://codex.wordpress.org/Function_Reference/register_post_type
     */

    $labels = array(
        'name' => __( 'Events', 'eventposttype' ),
        'singular_name' => __( 'Event', 'eventposttype' ),
        'add_new' => __( 'Add New Event', 'eventposttype' ),
        'add_new_item' => __( 'Add New Event', 'eventposttype' ),
        'edit_item' => __( 'Edit Event', 'eventposttype' ),
        'new_item' => __( 'Add New Event', 'eventposttype' ),
        'view_item' => __( 'View Event', 'eventposttype' ),
        'search_items' => __( 'Search Events', 'eventposttype' ),
        'not_found' => __( 'No events found', 'eventposttype' ),
        'not_found_in_trash' => __( 'No events found in trash', 'eventposttype' ),
        'parent' => __( 'kalender' ),
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'supports' => array( 'title', 'editor', 'thumbnail', 'comments' ),
        'capability_type' => 'post',
        'rewrite' => array("slug" => "event"), // Permalinks format
        'menu_position' => 5,
        'menu_icon' => plugin_dir_url( __FILE__ ) . '/images/calendar-icon.gif',  // Icon Path
        'has_archive' => true
    ); 

    register_post_type( 'event', $args );
}

add_action( 'init', 'ep_eventposts' );

/**
 * Adds event post metaboxes for start time and end time
 * http://codex.wordpress.org/Function_Reference/add_meta_box
 *
 * We want two time event metaboxes, one for the start time and one for the end time.
 * Two avoid repeating code, we'll just pass the $identifier in a callback.
 * If you wanted to add this to regular posts instead, just swap 'event' for 'post' in add_meta_box.
 */

function ep_eventposts_metaboxes() {
    add_meta_box( 'ept_event_date_start', 'Start Date and Time', 'ept_event_date', 'event', 'side', 'default', array( 'id' => '_start') );
    add_meta_box( 'ept_event_date_end', 'End Date and Time', 'ept_event_date', 'event', 'side', 'default', array('id'=>'_end') );
    add_meta_box( 'ept_event_location', 'Event Locatie', 'ept_event_location', 'event', 'side', 'default', array('id'=>'_location') );
    add_meta_box( 'ept_event_price', 'Event Prijs', 'ept_event_price', 'event', 'side', 'default', array('id'=>'_price') );
    add_meta_box( 'ept_event_page', 'Event Pagina', 'ept_event_page', 'event', 'side', 'default', array('id'=>'_page') );
    add_meta_box( 'ept_event_full', 'Event Volzet', 'ept_event_full', 'event', 'side', 'default', array('id'=>'_full') );

}
add_action( 'admin_init', 'ep_eventposts_metaboxes' );

// Metabox HTML

function ept_event_date($post, $args) {
    $metabox_id = $args['args']['id'];
    global $post, $wp_locale;

    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'ep_eventposts_nonce' );

    $time_adj = current_time( 'timestamp' );
    $month = get_post_meta( $post->ID, $metabox_id . '_month', true );

    if ( empty( $month ) ) {
        $month = gmdate( 'm', $time_adj );
    }

    $day = get_post_meta( $post->ID, $metabox_id . '_day', true );

    if ( empty( $day ) ) {
        $day = gmdate( 'd', $time_adj );
    }

    $year = get_post_meta( $post->ID, $metabox_id . '_year', true );

    if ( empty( $year ) ) {
        $year = gmdate( 'Y', $time_adj );
    }

    $hour = get_post_meta($post->ID, $metabox_id . '_hour', true);

    if ( empty($hour) ) {
        $hour = gmdate( 'H', $time_adj );
    }

    $min = get_post_meta($post->ID, $metabox_id . '_minute', true);

    if ( empty($min) ) {
        $min = '00';
    }

    $month_s = '<select name="' . $metabox_id . '_month">';
    for ( $i = 1; $i < 13; $i = $i +1 ) {
        $month_s .= "\t\t\t" . '<option value="' . zeroise( $i, 2 ) . '"';
        if ( $i == $month )
            $month_s .= ' selected="selected"';
        $month_s .= '>' . $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) ) . "</option>\n";
    }
    $month_s .= '</select>';

    echo $month_s;
    echo '<input type="text" name="' . $metabox_id . '_day" value="' . $day  . '" size="2" maxlength="2" />';
    echo '<input type="text" name="' . $metabox_id . '_year" value="' . $year . '" size="4" maxlength="4" /> @ ';
    echo '<input type="text" name="' . $metabox_id . '_hour" value="' . $hour . '" size="2" maxlength="2"/>:';
    echo '<input type="text" name="' . $metabox_id . '_minute" value="' . $min . '" size="2" maxlength="2" />';

}

function ept_event_location() {
    global $post;
    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'ep_eventposts_nonce' );
    // The metabox HTML
    $event_location = get_post_meta( $post->ID, '_event_location', true );
    echo '<label for="_event_location">Location:</label>';
    echo '<input type="text" name="_event_location" value="' . $event_location  . '" />';
}

function ept_event_price() {
    global $post;
    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'ep_eventposts_nonce' );
    // The metabox HTML
    $event_price = get_post_meta( $post->ID, '_event_price', true );
    echo '<label for="_event_location">Price:</label>';
    echo '<input type="text" name="_event_price" value="' . $event_price  . '" />';
}

/* Prints the box content */
function ept_event_page( $post, $args ) {
    global $post;
    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'ep_eventposts_nonce');
    // The Metabox HTML
    $event_page = get_post_meta( $post->ID, '_event_page', true );
    $dropdown_args = array(
        'post_type'        => 'page',
        'depth'            => -1,
        'show_option_none' => '-----',
        'name'             => '_event_page',
        'sort_column'      => 'menu_order, post_title',
        'selected'         => $event_page,
        'echo'             => 1,
    );

    //Dropdown of pages
    wp_dropdown_pages( $dropdown_args );
}

function ept_event_full() {
    global $post;
    // Use nonce for verification
    wp_nonce_field( plugin_basename( __FILE__ ), 'ep_eventposts_nonce' );
    // The metabox HTML
    $event_full = get_post_meta( $post->ID, '_event_full', true );
    echo '<label for="_event_full">Volzet: </label>';
    if( $event_full ){ $checked = "checked=\"checked\""; }else{ $checked = "";}
    echo '<input type="checkbox" name="_event_full" ' . $checked . ' />';
}

// Save the Metabox Data

function ep_eventposts_save_meta( $post_id, $post ) {

    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
        return;

    if ( !isset( $_POST['ep_eventposts_nonce'] ) )
        return;

    if ( !wp_verify_nonce( $_POST['ep_eventposts_nonce'], plugin_basename( __FILE__ ) ) )
        return;

    // Is the user allowed to edit the post or page?
    if ( !current_user_can( 'edit_post', $post->ID ) )
        return;

    // OK, we're authenticated: we need to find and save the data
    // We'll put it into an array to make it easier to loop though

    $metabox_ids = array( '_start', '_end' );

    foreach ($metabox_ids as $key ) {

        $aa = $_POST[$key . '_year'];
        $mm = $_POST[$key . '_month'];
        $jj = $_POST[$key . '_day'];
        $hh = $_POST[$key . '_hour'];
        $mn = $_POST[$key . '_minute'];

        $aa = ($aa <= 0 ) ? date('Y') : $aa;
        $mm = ($mm <= 0 ) ? date('n') : $mm;
        $jj = sprintf('%02d',$jj);
        $jj = ($jj > 31 ) ? 31 : $jj;
        $jj = ($jj <= 0 ) ? date('j') : $jj;
        $hh = sprintf('%02d',$hh);
        $hh = ($hh > 23 ) ? 23 : $hh;
        $mn = sprintf('%02d',$mn);
        $mn = ($mn > 59 ) ? 59 : $mn;

        $events_meta[$key . '_year'] = $aa;
        $events_meta[$key . '_month'] = $mm;
        $events_meta[$key . '_day'] = $jj;
        $events_meta[$key . '_hour'] = $hh;
        $events_meta[$key . '_minute'] = $mn;
        $events_meta[$key . '_eventtimestamp'] = $aa . $mm . $jj . $hh . $mn;

    }

        // Save Locations Meta

         $events_meta['_event_location'] = $_POST['_event_location'];   

        // Save Price Meta

         $events_meta['_event_price'] = $_POST['_event_price'];

        // Save Page Meta

         $events_meta['_event_page'] = $_POST['_event_page'];

         // Save Full Meta

         $events_meta['_event_full'] = $_POST['_event_full'];


    // Add values of $events_meta as custom fields

    foreach ( $events_meta as $key => $value ) { // Cycle through the $events_meta array!
        if ( $post->post_type == 'revision' ) return; // Don't store custom data twice
        $value = implode( ',', (array)$value ); // If $value is an array, make it a CSV (unlikely)
        if ( get_post_meta( $post->ID, $key, FALSE ) ) { // If the custom field already has a value
            update_post_meta( $post->ID, $key, $value );
        } else { // If the custom field doesn't have a value
            add_post_meta( $post->ID, $key, $value );
        }
        if ( !$value ) delete_post_meta( $post->ID, $key ); // Delete if blank
    }

}

add_action( 'save_post', 'ep_eventposts_save_meta', 1, 2 );

/**
 * Helpers to display the date on the front end
 */

// Get the Month Abbreviation

function eventposttype_get_the_month_abbr($month) {
    global $wp_locale;
    for ( $i = 1; $i < 13; $i = $i +1 ) {
                if ( $i == $month )
                    $monthabbr = $wp_locale->get_month_abbrev( $wp_locale->get_month( $i ) );
                }
    return $monthabbr;
}

// Display the date

function eventposttype_get_the_event_date() {
    global $post;
    $eventdate = '';
    $month = get_post_meta($post->ID, '_month', true);
    $eventdate = eventposttype_get_the_month_abbr($month);
    $eventdate .= ' ' . get_post_meta($post->ID, '_day', true) . ',';
    $eventdate .= ' ' . get_post_meta($post->ID, '_year', true);
    $eventdate .= ' at ' . get_post_meta($post->ID, '_hour', true);
    $eventdate .= ':' . get_post_meta($post->ID, '_minute', true);
    echo $eventdate;
}

// Add custom CSS to style the metabox
add_action('admin_print_styles-post.php', 'ep_eventposts_css');
add_action('admin_print_styles-post-new.php', 'ep_eventposts_css');

function ep_eventposts_css() {
    wp_enqueue_style('your-meta-box', plugin_dir_url( __FILE__ ) . '/event-post-metabox.css');
}

/**
 * Customize Event Query using Post Meta
 * 
 * @link http://www.billerickson.net/customize-the-wordpress-query/
 * @param object $query data
 *
 */
function ep_event_query( $query ) {

    // http://codex.wordpress.org/Function_Reference/current_time
    $current_time = current_time('mysql'); 
    list( $today_year, $today_month, $today_day, $hour, $minute, $second ) = split( '([^0-9])', $current_time );
    $current_timestamp = $today_year . $today_month . $today_day . $hour . $minute;

    global $wp_the_query;

    if ( $wp_the_query === $query && !is_admin() && is_post_type_archive( 'event' ) ) {
        $meta_query = array(
            array(
                'key' => '_start_eventtimestamp',
                'value' => $current_timestamp,
                'compare' => '>'
            )
        );
        $query->set( 'meta_query', $meta_query );
        $query->set( 'orderby', 'meta_value_num' );
        $query->set( 'meta_key', '_start_eventtimestamp' );
        $query->set( 'order', 'ASC' );
        $query->set( 'posts_per_page', '2' );
    }

}

add_action( 'pre_get_posts', 'ep_event_query' );

?>

And this is the code that displays the event and generates the form:

<?php

  //response generation function
  $response = "";

  //function to generate response
  function my_signup_form_generate_response($type, $message){

    global $response;

    if($type == "success") $response = "<div class='success'>{$message}</div>";
    else $response = "<div class='error'>{$message}</div>";

  }

  //response messages
$not_human       = "Foutieve verificatie";
$missing_content = "Gelieve alles in te vullen.";
$email_invalid   = "Email is foutief.";
$message_unsent  = "Inschrijving niet doorgestuurd. Probeer opnieuw";
$message_sent    = "Bedankt! Uw inschrijving is doorgestuurd.";

//user posted variables
$firstname = $_POST['message_firstname'];
$lastname = $_POST['message_lastname'];
$persons = $_POST['message_persons'];
$email = $_POST['message_email'];
$phone = $_POST['message_phone'];
$human = $_POST['message_human'];
$price = $_POST['price'];
$event = $_POST['event'];
$date  = $_POST['date'];

$message = "Beste " . $firstname ."\r\n\r\n";
$message .= "We hebben uw inschrijving goed ontvangen en danken u voor het vertrouwen in onze diensten.\r\n";
$message .= "U ontvangt kort vóór de activiteit nog een herinneringsbericht en meer praktische informatie.\r\n\r\n";
$message .= "Vitale groeten,\r\n";
$message .= "Barbele\r\n\r\n";
$message .= "Details van uw inschrijving:\r\n";
$message .= "Naam: " . $firstname . " " . $lastname . "\r\n";
$message .= "Telefoon: " . $phone . "\r\n";
$message .= "Aantal personen: " . $persons . "\r\n\r\n";
$message .= "Activiteit: " . $event . "\r\n";
$message .= "Datum: " . $date . "\r\n";
$message .= "Inschrijvingsgeld: " . $price . "\r\n";

//php mailer variables
$to = get_option('admin_email');
$subject = "Inschrijving voor \"". $event . "\" (" . $date . ")";
$conf_subject = "Bevestiging inschrijving \"". $event . "\" (" . $date . ")";
$headers [] = "From: " . $firstname . " " . $lastname . " <" . $email . ">";
$headers [] = "Reply-To: " . $email;
$conf_headers[] = 'From: Mens Sana Health <info@menssanahealth.be>';
$conf_headers[] = 'Reply-To: info@menssanahealth.be';

if(!$human == 0){
  if($human != 2) my_signup_form_generate_response("error", $not_human); //not human!
  else {
     //validate email
    if(!filter_var($email, FILTER_VALIDATE_EMAIL))
      my_signup_form_generate_response("error", $email_invalid);
    else //email is valid
    {
      //validate presence of name and message
      if(empty($name) || empty($phone)){
        my_signup_form_generate_response("error", $missing_content);
      }
      else //ready to go!
      {
        $sent = wp_mail($to, $subject, strip_tags($message), $headers);
        if($sent){
          $sent_conf = wp_mail($email, $conf_subject, strip_tags($message),$conf_headers);
          my_signup_form_generate_response("success", $message_sent); //message sent!
        }
        else my_signup_form_generate_response("error", $message_unsent);
      }
    }
  }
}
else if ($_POST['submitted']) my_signup_form_generate_response("error", $missing_content);



?>
<?php get_header(); ?>
<!-- kalender single template -->
<div id="banner-wrap">
    <div id="banner" class="container_24">

    </div>
</div>
<div id="main">
    <div id="main-wrap" class="container_24">
        <div id="main-sidebar" class="grid_7 prefix_1">
            <h1>Kalender</h1>
        </div>
        <div id="main-content" class="grid_15 prefix_1">

            <?php if ( have_posts() ) : while ( have_posts() ) :
          the_post(); ?>
                  <article class="dotted_bottom_border">
                  <?php 
        // Gets the event start month from the meta field
        $month = get_post_meta( $post->ID, '_start_month', true );
        // Gets the event start day
        $day = get_post_meta( $post->ID, '_start_day', true );
        // Gets the event start year
        $year = get_post_meta( $post->ID, '_start_year', true );

        $start_hour = get_post_meta($post->ID, '_start_hour', true);
        $start_minute = get_post_meta($post->ID, '_start_minute', true);
        $end_hour = get_post_meta($post->ID, '_end_hour', true);;
        $end_minute = get_post_meta($post->ID, '_end_minute', true);;

        $location = get_post_meta($post->ID, '_event_location', true);
        $price = get_post_meta($post->ID, '_event_price', true);
        $event_full = get_post_meta( $post->ID, '_event_full', true );

        $event_page = get_post_meta( $post->ID, '_event_page', true );



        ?>
        <h6><img src="<?php echo get_template_directory_uri(); ?>/images/date-arrow.png"/><?php echo $day . '.' . $month . '.' . $year; ?></h6>
                  <h5><?php the_title(); ?><?php if($event_full) : ?> (volzet)<?php endif; ?></h5>
                  <?php the_content(); ?>
                  <?php if($event_page != "") : ?>
                  <b><a href="<?php echo get_permalink( $event_page ); ?>">Meer informatie</a></b><br /><br />
                  <?php endif; ?>
                  <?php if($location != "") : ?>
                  <b>Waar:</b> <?php echo $location; ?><br/>
                  <?php endif; ?>
                  <b>Wanneer:</b> <?php echo $start_hour . ':' . $start_minute . ' - ' . $end_hour . ':' .$end_minute; ?><br />
                  <?php if($price != "") : ?>
                  <b>Prijs:</b> &euro; <?php echo $price; ?><br />
                  <?php endif; ?>
                  <?php if(!$event_full) : ?>
                  <p>
                  <b class="orange">Inschrijven</b>
                  <div id="signup">
                    <?php echo $response; ?>
                    <form action="<?php the_permalink(); ?>" method="post">
                      <p><label for="message_firstname">Voornaam: <span>*</span> <br><input type="text" name="message_firstname" value="<?php echo esc_attr($_POST['message_firstname']); ?>"></label><br />
                        <label for="message_lastname">Familienaam: <span>*</span> <br><input type="text" name="message_lastname" value="<?php echo esc_attr($_POST['message_lastname']); ?>"></label><br />
                     <label for="message_persons">Aantal personen: <span>*</span> <br><input type="text" name="message_persons" value="<?php echo esc_attr($_POST['message_persons']); ?>"></label><br />
                      <label for="message_phone">Telefoon: <span>*</span> <br><input type="text" name="message_phone" value="<?php echo esc_attr($_POST['message_phone']); ?>"></label><br />
                      <label for="message_email">Email: <span>*</span> <br><input type="text" name="message_email" value="<?php echo esc_attr($_POST['message_email']); ?>"></label><br />
                      <label for="message_human">Verificatie: <span>*</span> <br><input type="text" style="width: 60px;" name="message_human"> + 3 = 5</label></p>
                      <input type="hidden" name="submitted" value="1">
                      <input type="hidden" name="event" value="<?php the_title(); ?>">
                      <input type="hidden" name="price" value="<?php echo $price; ?>">
                      <input type="hidden" name="date" value="<?php echo $day . '/' . $month . '/' . $year; ?>">
                      <p><input type="submit"></p>
                    </form>
                  </div>
                  </p>
                  <?php endif; ?>
                  <?php if (get_adjacent_post(true, '', true) || get_adjacent_post(true, '', false)) : // if there are older posts ?>
                  <p class="topref"><?php previous_post_link('<span style="float:left;">%link</span>', '< %title', TRUE); ?> <?php next_post_link('%link', '%title >', TRUE); ?></p>
                  <?php endif; ?>
                  <?php $quote = get_post_meta(get_the_ID(), 'quote', true); ?>
          </article>
                  <?php endwhile; else: ?>
          <article id="main" class="roundedCorners">
            <?php _e('Nog niets aanwezig.'); ?>
          </article>
          <?php endif; ?>
        </div>      
    </div>
</div>
<?php get_footer(); ?>

Also, the permalink structure in the settings is /%category%/%postname%/ don't really think this is the issues as I get the same result when I set this to default.

An example can be found on http://www.menssanahealth.be/kalender/ whitch lists all events And this is one of the posts where the title has been changed: http://www.menssanahealth.be/events/workshop-relaxatie-thuis-en-in-de-klas/

Thanks in advanced for any help!

share|improve this question
add comment

1 Answer

up vote 0 down vote accepted

When you register a post type, WordPress creates a query var for that post type which it uses in the process of parsing incoming requests and converting them into queries. In your case the query var is event:

register_post_type( 'event', $args );

Your form then uses a POST var of the same name:

$event = $_POST['event'];

So when you submit this form, WordPress sees the event post var and thinks you are trying to query an event post with slug that matches that value, which is resulting in a 404.

The answer is to always prefix form vars with a unique string so they don't clash with built-in or other plugin vars.

share|improve this answer
    
Ah sweet, totally overlooked that! Thanks for the help! –  Yoeri Rousseaux Aug 31 '13 at 14:51
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.