Front End Event Posting

There will be an extension available soon that allows you to accept and moderate front-end submissions of events. This article is for those who wish to implement something a bit more bespoke themselves.


One of the features for Event Organiser that has been requested a few times is that of ‘front-end’ event posting. People want their users to be able create events on the front-end. While this won’t make it into the core of the plug-in (since everyone will want it to work slightly differently) – it’s very easy to implement this yourself, as Event Organiser provides some very simple functions for creating and manipulating the events. In this post, I’m going to give a basic example of how you could implement front-end posting: feel free to edit it to your needs…

Front-end event (like post) creation is essentially a two step process:

  1. Create form to collect data
  2. Collect that data and use it create an event

You might want to implement a ‘success page’ that you redirect to afterwards, or return users to the form which errors highlighted, but at its core you just have two steps.

(Those who just want the entire source code, see this Gist).

Step 1: The form

In this post I’m going to create a shortcode to produce the form – this can then be used on an page or post (or event!).

Creating a shortcode is very easy, the following will create a shortcode [my_event_form] that will output a form only if the user is logged in (once its finished!). I strongly recommend not allowing logged-out users to create events.

add_shortcode('my_event_form','my_event_form_shortcode_handler');

function my_event_form_shortcode_handler( ){

    if( !is_user_logged_in() ){
        return '<p> Only logged in users can post events </p>'; 
    }

     //Return form HTML mark-up
     return $html;
}

Now we just need to produce the HTML form mark-up. The rest of this step shows how to generate the HTML, and goes just above the comment //Return form HTML mark-up.

The following creates a nonce for the form and a hidden field which will use so we know what to do with the data sent.

$html = '<form method="POST">';

//Create hidden 'action' field and corresponding nonce
$html .= '<input type="hidden"  name="my-action" value="post-event" >';
$html .=wp_nonce_field( 'post-event', '_mynonce',false,false);

Next we produce some input forms. Let’s start with an event title and description:

//Event Title
$html .= sprintf('<p><label for="my-frontend-event-%1$s"> %2$s
            <input type="text" name="my_frontend_event[%1$s]" id="my-frontend-event-%1$s" >
        </label></p>',
        'title',
        'Event Title'
    );

//Event Description
$html .= sprintf('<p><label for="my-frontend-event-%1$s"> %2$s
            <textarea name="my_frontend_event[%1$s]" id="my-frontend-event-%1$s"></textarea>
        </label></p>',
        'description',
        'Event Description'
    );

Now we’ll add in fields for the start and end date (you can also add fields to specify a start and end time, but in this example I’ll just be creating all day events).

//Start date
$html .= sprintf('<p><label for="my-frontend-event-%1$s"> %2$s
            <input type="text" name="my_frontend_event[%1$s]" id="my-frontend-event-%1$s" class="my-frontend-event-datepicker" >
        </label></p>',
        'startdate',
        'Start Date'
    );

//End date
$html .= sprintf('<p><label for="my-frontend-event-%1$s"> %2$s
            <input type="text" name="my_frontend_event[%1$s]" id="my-frontend-event-%1$s" class="my-frontend-event-datepicker" >
        </label></p>',
        'enddate',
        'End Date'
    );

Next we’ll create a drop-down menu so users can select a venue. Venues are just taxonomy terms (of the event-venue taxonomy), so we’ll make use of the WordPress function wp_dropdown_categories

//Venue
$html .= sprintf('<p><label for="my-frontend-event-%1$s"> %2$s %3$s </label></p>',
            'venue',
            'Venue',
            wp_dropdown_categories(array(
                'orderby'      => 'ID', 
                'order'        => 'ASC',
                'hide_empty'   => 0, 
                'echo'         => 0,
                'id'           => 'my-frontend-event-venue',
                'name'         => 'my_frontend_event[venue]',
                'taxonomy'     => 'event-venue'
            ))
        );

We’ll also add a checkbox list for event categories. Again event categories are just taxonomy terms (this time of the event-category taxonomy).

//Category - checklist
$cats = get_terms('event-category',array('hide_empty'=>0));
if( $cats ){
    $html .= '<p><label for="my-frontend-event-category">Category <ul>';
    foreach ( $cats as $cat ){
        $html .= sprintf('<li><label>
                         <input type="checkbox" name="my_frontend_event[%1$s][]" value="%2$s">
                         %3$s
                      </label></li>',
                'category',
                $cat->term_id,
                esc_html($cat->name)
                );
    }
    $html .= '</label></p>';
}

Finally we end the form with a submit button:

//The post button
$html .= '<p><input name="submit" type="submit" id="submit" value="Post Event"></p>';

$html .='</form>';

Step 2: Processing the data

The form should now render and post the data – but we’ll need to get hold of that data and do something with it. We’ll hook onto the init action, and check to see if our custom ‘action’ variable is set. If not, we don’t do anything.

add_action('init','my_frontend_event_post_listner');

function my_frontend_event_post_listner(){

    if( !isset($_POST['my-action']) || 'post-event' != $_POST['my-action'] )
        return;

    //Collect raw input
    $input = $_POST['my_frontend_event'];

    //Do something with the input

}

Before we do anything with the data we need to perform a few checks:

  • Is the user allowed to create events (in this example, only logged-in users can create events – you might want to perform other checks)
  • Did the users intended to post the form? (This is what the nonce are for?)
  • Is the data as you expect it? (This is called sanitisation, I’ve omitted it here. Its less of a security matter, and more of making sure that the data you using to create the event, makes sense).

For example:

//Check user is logged in:  
if( !is_user_logged_in() )  
return;

//Check nonce  
check_admin_referer( 'post-event', '_mynonce');

/*
*   IMPORTANT: Perform any other checks you need to here (e.g. should only users with a certain capability be able to post events?)  
*/

To create the event we are going to use the plug-in provided function eo_insert_event(). This accepts two arrays: the first concerns ‘post data’ and is passed to wp_insert_post() (so it accepts anything that wp_insert_post() does. The second is for event data – and that is explained below.

First, collecting the post data (which includes an array of term IDs for the event-category and event-venue taxonomies – the latter should only contain one ID).

/**
 * Set the post data (see http://codex.wordpress.org/Function_Reference/wp_insert_post)
 * This includes event-category and event-venue (taxonomy terms)
*/
//Event venue is just an ID
$event_venue = isset($input['venue']) ? (int) $input['venue'] : 0;

//Event cats are an array of IDs
$event_cats = !empty( $input['category'] ) ? $input['category'] : array();
$event_cats = array_map( 'intval', $event_cats );

$post_data =array(
    'post_title'=>$input['title'],
    'post_content'=>$input['description'],
    'tax_input'=>array(
        'event-venue'=>array($event_venue),
        'event-category'=>$event_cats,
    )
);

Next the event data. For this function, any dates must be passed as DateTime objects. The easiest way to do this is to collect the date as string, $datestring, in Y-m-d format (or Y-m-d H:i format to specify a time too) and use

 new DateTime($datestring) 

The timezone will be UTC unless you specify otherwise, so its recommended you use eo_get_bog_timezone() for your blogs current timezone. See full documentation of this function.

/**
 * Set the event data
*/
//Start and end dates need to be given as DateTime objects (timezone is UTC unless a timezone is given)
$start = new DateTime($input['startdate'],eo_get_blog_timezone());
$end = new DateTime($input['enddate'],eo_get_blog_timezone());
$event_data =array(
    'schedule' =>'once',  //specifies the reoccurrence pattern
    'all_day' =>  1, //1 if its an all day event, 0 if not - if not you'll need to specify a start/end time for the DateTimeobjects
    'start' =>  $start, //start date (of first occurrence)  as a datetime object
    'end' => $end,  //end date (of first occurrence)  as a datetime object
);

Finally create the event!

//Finally, Insert event.
$post_id = eo_insert_event($post_data,$event_data);

The code in its entirety can be found at this Gist.

8 thoughts on “Front End Event Posting

  1. I am trying to get this to work on a site right now and everything seems to be working perfectly except for the venue drop down. From what I can see, it starts adding in new venues with the ID of the one they had selected as the name for the ‘new’ venue, and has no other information (address or anything else).

    Any advice?

    • It sounds like the venue ID is being passed as an array with a string to the `tax_input` argument. The venue ID *must* be cast to an integer. The gist does this, so if you’ve just copied and pasted that and it doesn’t work then I the error could be somewhere else. I’ll double check the gist.

  2. Hi Stephen,

    Thanks for this in-depth tutorial. Forgive my naivety, but where do we put this code to use it, do we put it in our functions file?

    Thanks,
    J

    • You can do… though for proper separation of concerns its best to create a separate plug-in for it. (On a side note, the Event Organiser Front-End Submission extension shall hopefully be available very soon!).

  3. Hi Stephen,

    Any ETA on the new extension – when I saw you were already working on this I thought I would just wait rather than duplicate your work!

    Thanks,
    J

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>