EventBlender Hooks: How to exchange events with any 3rd party extension or plugin

Since version 2.x it is possible to use hooks in order to extend the available list of input sources and most importantly to publish/propagate events to 3rd party extensions, such as Joomla Events components, Wordpress Events plugins and any other event consumers.

In this tutorial we will examine an existing hook for fetching and storing events retrieved with EventBlender into a database table. At the end of the tutorial you will have a good idea of how to build your own hook in order to connect EventBlender with your favorite Events extension/plugin.

OK. let's start with the basics. There are two ways to use the existing hooks:

  • As a source of events. This is ideal if you want to extend the available list of event sources (Facwebook events, Google Calendar, Excel, CSV, etc) with a new one.
  • As a target of events. This can used if you want to add automatically an event retrieved with EventBlender from a given source into anther events consumer. For instance, you could use a hook to automatically publish events retrieved from a Facebook page into JEvents or another events extension.

Use a hook as a source of events

If you want to retrieve events from a source that has not built-in support, it is possible to create or use a hook that will expand the list with a new type of data source. At the end of the tutorial we will show how to create your own, but for the time being we will show you how to use an existing one.

When you create a new data source, set the data source type to hook as shown in the image below:

Then, set the hook source and optionally the hook filter.

The hook filter can have be can any format as specified by the creator of the hook and currently there is no strict rule on how to supply it. Just remember that it is optional and it can be omitted.

Use hook(s) as a target of events

If you create a new one or edit an existing data source you will notice that there is a new field called hooks. Right below that there is a list of the available hooks, as shown in the image below:

Generally speaking, the list follows the format name (description). So for instance, if you want to use the table hook all you have to do is to type the name of the hook (i.e. table) or click on the corresponding link. It is also important to note that you can use more than one output hooks and that you can provide additional hook arguments using the format below:

hook_1_name:hook_1_args^hook_2_name:hook_2_args^hook_3_name:hook_3_args^...

The arguments are optional and you can rewrite the above statement as:

hook_1_name^hook_2_name:hook_2_args^hook_3_name

In the example above, only hook #2 has arguments, while in the other two we have specified just the hook name.

How to create your own hook

In order to create your own hook you will need some working knowledge of the PHP programming language. If you are not familiar with PHP programming you can always ask us to build the hook for you for a small fee.

All it takes is a single PHP file that you should place under one of the following directories based on the CMS (Joomla/Wordpress) you are using:

{joomla root directory}/templates/eventblender/hooks

or

{wordpress root directory}/wp-content/plugins/eventblender/templates/eventblender/hooks

The file name can contain only lower case latin characters (a-z) and numbers (0-9) and the first character but be a letter. Also, make sure that the name is not used by another hook.

In the PHP file you just created, define a new class with the following skeleton code:

<?php

// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );

class EventBlenderHookXyz extends EventBlenderHook {

    function description() {
        return "a short description of your hook";
    }

    function isAvailable() {
		// return true or false, if the hook is available on this system
		// a good way to to this is by detecting the presense of the database table that's used by the hook
		// but you can do it any other way.
		// The #__ will be replaced by the actual database table prefix
		
		$db_table_used_by_hook = '#__db_table_name';
        return $this->databaseTableExist($db_table_used_by_hook);
    }

	/**
	This method is used when retrieving events from a hook, i.e. when the hook is used as a new data source type.
	If you are planning to create a hook as a target of events you can skip its implementation.
	
	The returned results should be an associative array, where the first row must be the header row which indicates the name of each column.	
	*/
	
    function selectEvents() {
        $event_rows = array();

        $criteria = array();        
		
		// construct the search criteria based on the variables below
		$from_datetime = $this->getDatetimeFrom();
        $to_datetime = $this->getDatetimeTo();
		$timezone = $this->getTimezone();
		$filter = $this->getFilter();
        $max_results = $this->getMaxResults();				       
		
        $field_id = 0;
        $header_row = array(
            $field_id++ => 'id',
            $field_id++ => 'title',
            $field_id++ => 'description',
            $field_id++ => 'avenue',
            $field_id++ => 'location',
            $field_id++ => 'geo',
            $field_id++ => 'start_date',
            $field_id++ => 'start_time',
            $field_id++ => 'start_datetime',
            $field_id++ => 'end_date',
            $field_id++ => 'end_time',
            $field_id++ => 'end_datetime',
            $field_id++ => 'timezone',
            $field_id++ => 'all_day_event',
            $field_id++ => 'multiday_event',
            $field_id++ => 'recurring_event',
            $field_id++ => 'organizer',
            $field_id++ => 'creator',
            $field_id++ => 'url',
            $field_id++ => 'cover',
            $field_id++ => 'category',
            $field_id++ => 'priority',
            $field_id++ => 'highligther',
            $field_id++ => 'source',
            $field_id++ => 'meta'
        );
        $header_row_set = false;
		
		// grab the events from your extensions/plugin/event source
		// if you want to query the database table use the $this->dbGetQueryObjectList($query) call 
		// even though you can use CSV native calls
		
		$query = 'SELECT FROM ....';
		$results = $this->dbGetQueryObjectList($query);			
		
		if (!$header_row_set) {
			$event_rows[] = $header_row;
			$header_row_set = true;
		}
		
		foreach ($results as $result) {
			$event_row = array();			
			// construct the $event row based on the value of the $result			
			// ....			
			$event_rows[] = $event_row;
		}
				
        return $event_rows;
    }
	

	/**
	The selectEvent method is used to detect the presense of the event row in the target system (extension, plugin or other event consumer).
	It should return the event id, if the event has been already added to the target system, or null otherwise.
	*/
	
    function selectEvent($event_row) {
		// the code may look similar to:
        $query = 'SELECT ...';
        $result = $this->dbGetQueryResult($query);
        if (empty($result)) return false;
        else return $result;
    }

	/**
	The $even_row is an associative array that contains the following key-value pairs:
$event_row['id']
$event_row['title']
$event_row['description']
$event_row['avenue']
$event_row['location']
$event_row['geo']
$event_row['start_date']
$event_row['start_time']
$event_row['start_datetime']
$event_row['end_date']
$event_row['end_time']
$event_row['end_datetime']
$event_row['timezone']
$event_row['all_day_event']
$event_row['multiday_event']
$event_row['recurring_event']
$event_row['organizer']
$event_row['creator']
$event_row['url']
$event_row['cover']
$event_row['category']
$event_row['priority']
$event_row['highligther']
$event_row['source']
$event_row['meta']
*/
	
    function insertEvent($event_row) {       
		// the optional hook arguments can be retrieved using the following call:
		$args = $this->getArgs();
	
		// the code may be similar to: 
		$query = 'INSERT INTO ...';
        return $this->dbExecuteQuery($query, $error_msg);
    }
	

	/**
	The event id is the key returned by the selectEvent method and it should be used to update the entries in the target system (extension, plugin or other event consumer)
	The $event_row is an associate array, as described in the insertEvent method
	*/
	
    function updateEvent($event_id, $event_row) {	
		// the optional hook arguments can be retrieved using the following call:
		$args = $this->getArgs();
		
		// the code may be similar to: 
        $query = 'UPDATE ... WHERE id = '.$event_id;
        return $this->dbExecuteQuery($query, $error_msg);
    }
	
}

?>

Important notes:

  • The class name must match the file name, i.e. it should follow the pattern :
    EventBlenderHookFilename
    For instance, if the file name is xyz.php then the class name should be EventBlenderHookXyz.
  • The class name must extend the EventBlenderHook class.
  • To block direct access to the file, don't forget to include the following line at the top of the file:
    // no direct access
    defined( '_JEXEC' ) or die( 'Restricted access' );