Creating Custom Event Search Attributes

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.

If you create your own custom information for events, you may want to allow Events Manager to search by this attribute. With a few lines of code, you can hook your new features straight into the core of Events Manager’s event search engine and provide a seamless integration.

In this tutorial we’ll be extending our styles add-on which follows on from our previous tutorial on saving custom event information to the database.

Add ‘style’ to accepted search parameters

The first step to take is that we need to hook into the default search filter, so that our new search parameter isn’t ignored when Events Manager creates an events search query:

add_filter('em_events_get_default_search','my_em_styles_get_default_search',1,2);
add_filter('em_calendar_get_default_search','my_em_styles_get_default_search',1,2);
function my_em_styles_get_default_search($args, $array){
	$args['style'] = false; //registers 'style' as an acceptable value, although set to false by default
	if( !empty($array['style']) && is_numeric($array['style']) ){
		$args['style'] = $array['style'];
	}
	return $args;
}

The first two lines hook into the EM_Events and EM_Calendar default search arguments filters. These filters take a search request, filters and removes unwanted/bad search variables. At this point in the filter, $args represents an associative array of clean search parameters and values, $array is the originally supplied array which may contain ‘dirty’ data.

Currently $args does not contain our ‘style’ parameter, which was originally supplied in $array, because it’s not recognized by Events Manager and removed since it’s considered invalid. Therefore, we first start by adding a ‘style’ key to the $args array and then assigning it false on line 4, so that any time search arguments are generated, we know there’ll be a ‘style’ key we can refer to, with a default of false.

Then, we run a quick check to see if the ‘style’ key exists in the original $array, verify it is a valid format (in this case, a number representing a style ID) and copy it over into the clean $args array, before we pass it back to the filter function.

This sort of logic works on most object searches, which is why this is a helpful introduction into extending Events Manager. All objects that search, e.g. EM_Events, EM_Locations, EM_Categories, etc. have a filter in the form of em_[object]_get_default_search, which add extra attributes not present in the parent/base function located in EM_Object::get_default_search().

If you want all objects to support the ‘style’ parameter in searches, then you could use the main em_object_get_default_search filter instead. This is fairly safe to do too, because without the next step, the parameter will have no effect on searches for any object.

Filter event search results based on a style value

The next step is to add the function Events Manager needs to narrow down its results when a specific ‘style’ is being searched for.

add_filter( 'em_events_build_sql_conditions', 'my_em_styles_events_build_sql_conditions',1,2);
function my_em_styles_events_build_sql_conditions($conditions, $args){
	global $wpdb;
	if( !empty($args['style']) && is_numeric($args['style']) ){
		$sql = $wpdb->prepare("SELECT object_id FROM ".EM_META_TABLE." WHERE meta_value=%s AND meta_key='event-style'", $args['style']);
		$conditions['style'] = "event_id IN ($sql)";
	}
	return $conditions;
}

We do this by hooking into the em_events_build_sql_conditions filter on line 1. This filter is used to build the conditions that will be added to the WHERE part of a SQL statement used to search events.

We start by checking that the ‘style’ search parameter has a supplied argument (which may come from your shortcode, a PHP function or the event search forms) on line 4. If we have a ‘style’ ID to look for, we add a custom condition to the $conditions array. We gave the array key the name ‘style’, we advise you to go for something more unique so there are no clashes, the key name is only for internal reference anyway.

In this situation we’re looking for any event IDs (i.e. the event_id field row) that have ‘style’ ID, so we run a sub-select query to obtain all the event IDs in the wp_em_meta table with that style. This way, along with any other filters in the $conditions only events with the specific ‘style’ ID will be returned by the SQL query and fed into the final search results.

Using this new parameter/attribute

The new search parameter you just created is usable by event and calendar related shortcodes and functions. So, for example you could bring up a list of upcoming events with a ‘style’ ID 5 by adding the new ‘style’ shortcode attribute like so:

[events_list style=”5″ scope=”future”]

For a PHP search, you could do the same thing like this:

echo EM_Events::output( array('style'=>5, 'scope'=>'future') );

Supporting location searches

The above snippets will enable the ‘style’ search parameter to be used in event-specific searches, such as via the EM_Events, EM_Calendar PHP objects and shortcodes such as [events_list] and [events_calendar]. It currently does not, however, support location related searches. For example, this would ideally show any locations containing events that have a style ID of 5:

[locations_list style=”5″]

However, it will ignore the ‘style’ attribute. In order to support the ‘style’ attribute, we need to add a few more lines of code:

add_filter('em_locations_get_default_search','my_em_styles_get_default_search',1,2);
add_filter( 'em_locations_build_sql_conditions', 'my_em_styles_events_build_sql_conditions',1,2);

add_filter('em_locations_get_join_events_table', 'my_em_styles_locations_get_join_events_table', 10, 2);
function my_em_styles_locations_get_join_events_table( $join, $args ){
	if( !empty($args['style']) ){
		return true;
	}
	return $join;
}

Lines 1-2 expand on the two snippets further up by allowing the locations filters to also be run through those functions and allow the ‘style’ search parameter and also filter it with an SQL condition.

Line 4 onwards hooks into the em_locations_get_join_events_table filter (since EM 5.8), which tells Events Manager that if the ‘style’ parameter has been defined, that we will want to add a JOIN clause to the SQL statement being created to search the locations database. Without this, you will get SQL errors since event_id does not exist in the locations table.

Next Steps…

In our next tutorial we’ll be adding a custom field to the events search form so that users can make the best of this new filtering.