Saving Custom Event Information

This tutorial forms part of our series of tutorials for creating an custom add-on for Events Manager called “Styles”, where we will be able to select from a list of styles during event registration.

In our previous tutorial, we showed you how to add a meta box with extra form fields for users to add customized information about their event. The following tutorial will show how to save this information whilst the normal event data is updated/added.

Saving styles when an event is saved

add_filter('em_event_save','my_em_styles_event_save',1,2);
function my_em_styles_event_save($result,$EM_Event){
	global $wpdb;
	//First delete any old saves
	$wpdb->query("DELETE FROM ".EM_META_TABLE." WHERE object_id='{$EM_Event->event_id}' AND meta_key='event-style'");
	if( $EM_Event->event_id && !empty($_POST['event_styles']) ){
		$my_em_styles = (is_array(get_option('my_em_styles'))) ? get_option('my_em_styles'):array();
		$ids_to_add = array();
		$EM_Event->styles = array();
		foreach( $_POST['event_styles'] as $style_id ){
			if( array_key_exists($style_id, $my_em_styles) ){
				$ids_to_add[] = "({$EM_Event->event_id}, 'event-style', '$style_id')";
				$EM_Event->styles[] = $style_id;
			}
		}
		if( count($ids_to_add) > 0 ){
			$wpdb->query("INSERT INTO ".EM_META_TABLE." (object_id, meta_key, meta_value) VALUES ".implode(',',$ids_to_add));
		}
	}
	return $result;
}

The first line adds a filter to the em_event_save filter, which is called every time an event has been saved, and also passes on the result of the save and the EM_Event object being saved.

We’ll firstly delete all previous styles associated to this event in Line 5, since we will re-add them again further down or possibly not add any at all if all style checkboxes have been unchecked.

Line 6 checks to make sure that event styles have in fact been submitted, and if this event has been saved. In many cases it’s handy to check $result as we then know if an event was successfully submitted without errors, however in this case we only need to know if an event ID has been assigned via $EM_Event->event_id, because there may be situations where an event is incomplete (and therefore stored as a draft) but still partially saved.

Line 7 obtains the styles array from the database, or loads up an empty array.

We then loop through the $_POST[‘event_styles’] array, which contains the user’s selected styles and add the styles that exist in our $styles array to this event. Note that we’re just adding style ID numbers, as we can obtain style information by referring to the $my_em_styles array in the future (or obtain it again).

We finally save the new style ids to the wp_em_meta table (wp_ prefix may differ on your install), which we refer to as the constant EM_META_TABLE. We will be storing our style associations to this table because with an event ID, it is very easy to retrieve all style IDs that are associated with that event.

Handling recurring events

The above snippet will save style information for both regular events and recurring events, but not the individual recurrences of a recurring event. For that, we’ll need to hook into a different filter called em_event_save_events, which is called after a recurring event has been saved and consequently created or modified the individual recurrences.

add_filter('em_event_save_events', 'my_em_styles_event_save_events', 10, 3);
function my_em_styles_event_save_events($result, $EM_Event, $event_ids){
	if( $result ){
		global $wpdb;
		array_walk($event_ids, 'absint'); //absint here as $event_ids is used in both insert and delete
		//first, delete all the previous data in case we've changed the styles
		$wpdb->query('DELETE FROM '.EM_META_TABLE.' WHERE object_id IN (' . implode(',', $event_ids).") AND meta_key='event-style'");
		//build array of inserts
		$inserts = array();
		foreach( $EM_Event->styles as $style_id ){
			foreach( $event_ids as $event_id ){
				$inserts[] = "(".$event_id.", 'event-style', ".absint($style_id).")";
			}
		}
		//join inserts into one insert statement, it's faster
		if( !empty($inserts) ){
			$wpdb->query("INSERT INTO ".EM_META_TABLE." (object_id, meta_key, meta_value) VALUES " . implode(',', $inserts));
		}
	}
	return $result;
}

The flow of logic is quite similar to how we save styles for normal events, however, there are some important differences.

Firstly, you’ll notice that we do in this case check if $result is true on line 3, and this is because recurrences are only saved if the recurring event template is successfully saved with a valid recurrence pattern, otherwise individual recurrences are not created or modified.

Additionally, rather than interacting with $EM_Event, we’re going to be saving/deleting based on the $event_ids variable, which is an array containing the event IDs of all the recurrences associated with this recurring event. We already saved the style information in em_event_save and the style information is already loaded into $EM_Event->styles which we’ll use to copy onto all the recurrences.

As we did in em_event_save, we’ll start by deleting all styles associated with the array of event IDs we’ve been given. Then, we’ll proceed between lines 9-18 to build an INSERT SQL query and add all the style associations in one statement (considerably faster than looping through each recurrence and adding a separate INSERT statement).

Next step…

Now, both the database and the object are updated with the latest style values and can be obtained in other parts of your site! However, before we can access the event styles information, we need to add styles data to events on load, as they are not automatically loaded.