*
* This plugin uses Facebook's Graph API v2.7.
*
*/
// must be run within Dokuwiki
if(!defined('DOKU_INC')) die();
if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
require_once(DOKU_PLUGIN.'syntax.php');
// Syntax parameters
define( "FB_EVENTS_APPLICATION_ID", "appid" );
define( "FB_EVENTS_SECRET", "secret" );
define( "FB_EVENTS_FAN_PAGE_ID", "fanpageid" );
define( "FB_EVENTS_SHOW_AS", "showAs" );
define( "FB_EVENTS_FROM_DATE", "from" );
define( "FB_EVENTS_TO_DATE", "to" );
define( "FB_EVENTS_NR_ENTRIES", "numberOfEntries" );
define( "FB_EVENTS_SHOW_END_TIMES", "showEndTimes" );
define( "FB_EVENTS_LIMIT", "limit" );
// Configuration parameters
define( "FB_EVENTS_DATE_FORMAT", "dformat" );
define( "FB_EVENTS_TIME_FORMAT", "tformat" );
define( "FB_EVENTS_TEMPLATE", "template" );
/**
* This plugin retrieves facebook events and displays them in HTML.
*
* Usage: {{facebookevents#appid=1234&secret=12345&fanpageid=12345&showAs=default}}
*
*/
class syntax_plugin_facebookevents extends DokuWiki_Syntax_Plugin
{
function getInfo() {
return array(
'author' => 'J. Drost-Tenfelde',
'email' => 'info@drost-tenfelde.de',
'date' => '20162-09-29',
'name' => 'facebookevents',
'desc' => 'Displays facebook events as HTML',
'url' => 'https://www.dokuwiki.org/plugin:facebookevents',
);
}
// implement necessary Dokuwiki_Syntax_Plugin methods
function getType() {
return 'substition';
}
function getSort() {
return 42;
}
function connectTo($mode) {
$this->Lexer->addSpecialPattern('\{\{facebookevents.*?\}\}',$mode,'plugin_facebookevents');
}
function getData($url) {
$ch = curl_init();
$timeout = 5;
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
/**
* parse parameters from the {{facebookevents#...}} tag.
* @return an array that will be passed to the renderer function
*/
function handle($match, $state, $pos, &$handler) {
$match = substr($match, 17, -2);
parse_str($match, $params);
// Make sure the necessary data is set
if ( !$params[FB_EVENTS_APPLICATION_ID] ) {
$this->error = $this->getLang('error_appid_not_set');
}
if ( !$params[FB_EVENTS_SECRET] ) {
$this->error = $this->getLang('error_secret_not_set');
}
if ( !$params[FB_EVENTS_FAN_PAGE_ID] ) {
$this->error = $this->getLang('error_fanpageid_not_set');
}
if ( !$params[FB_EVENTS_SHOW_AS] ) {
$params[FB_EVENTS_SHOW_AS] = 'default';
}
if ( !$params[FB_EVENTS_LIMIT] ) {
$params[FB_EVENTS_LIMIT] = 0;
}
// Get the appropriate display template
$template = $this->getConf( $params[FB_EVENTS_SHOW_AS] );
if ( !isset($template ) || $template == '' ) {
$template = $this->getConf('default');
}
$params[FB_EVENTS_TEMPLATE] = $template;
// From
if ($params[FB_EVENTS_FROM_DATE] == 'today') {
$from = time();
} else if (preg_match('#(\d\d)/(\d\d)/(\d\d\d\d)#', $params[FB_EVENTS_FROM_DATE], $fromDate)) {
// must be MM/dd/yyyy
$from = mktime(0, 0, 0, $fromDate[2], $fromDate[1], $fromDate[3]);
} else if (preg_match('/\d+/', $params[FB_EVENTS_FROM_DATE])) {
$from = $params[FB_EVENTS_FROM_DATE];
}
$params[FB_EVENTS_FROM_DATE] = $from;
// Get the to parameter
if ($params[FB_EVENTS_TO_DATE] == 'today') {
$to = mktime(24, 0, 0, date("m") , date("d"), date("Y"));
} else if (preg_match('#(\d\d)/(\d\d)/(\d\d\d\d)#', $params[FB_EVENTS_TO_DATE], $toDate)) {
// must be MM/dd/yyyy
$to = mktime(0, 0, 0, $toDate[2], $toDate[1], $toDate[3]);
} else if (preg_match('/\d+/', $params[FB_EVENTS_TO_DATE])) {
$to = $params[FB_EVENTS_TO_DATE];
}
$params[FB_EVENTS_TO_DATE] = $to;
// Sorting
if ( !$params[FB_EVENTS_SORT ] ) {
$params[FB_EVENTS_SORT ] = 'ASC';
}
else {
if ( $params[FB_EVENTS_SORT] != 'DESC') {
$params[FB_EVENTS_SORT ] = 'ASC';
}
}
return $params;
}
/**
* Retrieves the facebook events and parses them to HTML.
*/
function render($mode, &$renderer, $data) {
$info = $this->getInfo();
$content = '';
if ($mode == 'xhtml') {
// Catch errors
if ($this->error) {
$renderer->doc .= 'Error in Plugin '.$info['name'].': '.$this->error;
return;
}
// Get the date format
$date_format = $this->getConf(FB_EVENTS_DATE_FORMAT);
$time_format = $this->getConf(FB_EVENTS_TIME_FORMAT);
// Get the facebook information
$fb_app_id = $data[FB_EVENTS_APPLICATION_ID];
$fb_secret = $data[FB_EVENTS_SECRET];
$fb_page_id = $data[FB_EVENTS_FAN_PAGE_ID];
// Get the access token using app-id and secret
$token_url ="https://graph.facebook.com/oauth/access_token?client_id={$fb_app_id}&client_secret={$fb_secret}&grant_type=client_credentials";
$token_data = $this->getData( $token_url );
$elements = split("=", $token_data );
if ( count($elements) < 2) {
$renderer->doc .= 'Access token could not be retrieved for Plugin '.$info['name'].': '.$this->error;
return;
}
$fb_access_token = $elements[1];
// Get the events
$since_date = $data[FB_EVENTS_FROM_DATE];
$until_date = $data[FB_EVENTS_TO_DATE];
$fb_fields="id,name,description,place,timezone,start_time,end_time,cover";
$json_link = "https://graph.facebook.com/v2.7/{$fb_page_id}/events/attending/?fields={$fb_fields}&access_token={$fb_access_token}&since={$since_date}&until={$until_date}";
$json = $this->getData( $json_link);
//$objects = json_decode($json, true, 512, JSON_BIGINT_AS_STRING);
$objects = json_decode($json, true);
// count the number of events
$event_count = count($objects['data']);
$displayed_entries = 0;
// Loop through the events
for ($index = $event_count - 1; $index >= 0; $index--){
$event = $objects['data'][$index];
date_default_timezone_set($event['timezone']);
$start_date = date( $date_format, strtotime($event['start_time']));
$start_time = date( $time_format, strtotime($event['start_time']));
if ( !isset($event['end_time'])) {
$event['end_time'] = $event['start_time'];
}
$end_date = date( $date_format, strtotime($event['end_time']));
$end_time = date( $time_format, strtotime($event['end_time']));
$eid = $event['id'];
$name = $event['name'];
$description = isset($event['description']) ? $event['description'] : "";
// Limit?
if ( isset( $data[FB_EVENTS_LIMIT]) && ($data[FB_EVENTS_LIMIT] > 0 ) ) {
if ( strlen( $description ) > $data[FB_EVENTS_LIMIT] ) {
$description = substr( $description, 0, $data[FB_EVENTS_LIMIT] );
// Find the first occurance of a space
$index = strrpos ( $description, ' ' );
$description = substr( $description, 0, $index ).'...';
}
}
$description = str_replace("\r\n", '
', $description );
$description = str_replace("\n", '
', $description );
$pic = isset($event['cover']['source']) ? $event['cover']['source'] : "https://graph.facebook.com/v2.7/{$fb_page_id}/picture";
// Add a fix for urls with get parameters
if ( strpos($pic, '?') > 0 )
{
$pic .= '&.png';
}
// place
$place_name = isset($event['place']['name']) ? $event['place']['name'] : "";
$street = isset($event['place']['location']['street']) ? $event['place']['location']['street'] : "";
$city = isset($event['place']['location']['city']) ? $event['place']['location']['city'] : "";
$country = isset($event['place']['location']['country']) ? $event['place']['location']['country'] : "";
$zip = isset($event['place']['location']['zip']) ? $event['place']['location']['zip'] : "";
$location="";
if ( $place_name && $street & $city && $country && $zip){
$location = "{$place_name}, {$street}, {$zip} {$city}, {$country}";
}
else{
$location = "Location not set or event data is too old.";
}
// Build the entry
$entry = $data['template'];
// Replace the values
$entry = str_replace('{title}', $name, $entry );
$entry = str_replace('{description}', $description, $entry );
$entry = str_replace('{location}', $location, $entry );
$entry = str_replace('{place}', $place_name, $entry );
$entry = str_replace('{city}', $city, $entry );
$entry = str_replace('{country}', $country, $entry );
$entry = str_replace('{zip}', $zip, $entry );
$entry = str_replace('{image}', $pic, $entry);
$entry = str_replace('{image_large}', $pic, $entry);
$entry = str_replace('{image_small}', $pic, $entry);
$entry = str_replace('{image_square}', $pic, $entry);
// DateTime
if ( (!isset( $data[FB_EVENTS_SHOW_END_TIMES])) || $data[FB_EVENTS_SHOW_END_TIMES] == '1' ) {
// Are they the same date?
$compare_start_date = date( "Ymd", strtotime($event['start_time']));
$compare_end_date = date( "Ymd", strtotime($event['end_time']));
if ( $compare_start_date == $compare_end_date ) {
$datetime_string = $start_date;
//if ( isset($event['is_date_only']) && (!$event['is_date_only'])) {
$datetime_string = $datetime_string.' '.$start_time.' - '.$end_time;
//}
$entry = str_replace('{date}', $date_string, $entry );
$entry = str_replace('{datetime}', $datetime_string, $entry );
}
else {
$date_string = $start_date.' - '.$end_date;
$datetime_string = $date_string;
//if ( isset($event['is_date_only']) && (!$event['is_date_only'])) {
$datetime_string = $start_date.' '.$start_time.' - '.$end_date.' '.$end_time;
//}
$entry = str_replace('{date}', $date_string, $entry );
$entry = str_replace('{datetime}', $datetime_string, $entry );
}
}
else {
$entry = str_replace('{date}', $start_date, $entry );
$entry = str_replace('{datetime}', $start_date.' '.$start_time);
}
// [[ url | read more ]
$event_url = "http://www.facebook.com/events/".$eid;
$entry = str_replace('{url}', $event_url, $entry );
$entry = str_replace('{more}', '[['.$event_url.'|'.$this->getLang('read_more').']]', $entry );
// Add the entry to the content
$content .= $entry;
// Only display a maximum number of entries (if set)
$displayed_entries++;
if ( isset( $data[FB_EVENTS_NR_ENTRIES] ) && $displayed_entries >= $data[FB_EVENTS_NR_ENTRIES] ) {
break;
}
}
//$renderer->doc .= $ret;
$html = p_render($mode, p_get_instructions( $content ), $info );
$renderer->doc .= $html;
// Set the timezone back to the original
//date_default_timezone_set($origin_timezone);
return true;
}
return false;
}
}
?>