1<?php 2 3/** 4 * Plugin facebookevents: Displays facebook events. 5 * 6 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 7 * @version 1.2 8 * @date September 2016 9 * @author J. Drost-Tenfelde <info@drost-tenfelde.de> 10 * 11 * This plugin uses Facebook's Graph API v2.7. 12 * 13 */ 14 15// must be run within Dokuwiki 16if(!defined('DOKU_INC')) die(); 17 18if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 19require_once(DOKU_PLUGIN.'syntax.php'); 20 21// Syntax parameters 22define( "FB_EVENTS_APPLICATION_ID", "appid" ); 23define( "FB_EVENTS_SECRET", "secret" ); 24define( "FB_EVENTS_FAN_PAGE_ID", "fanpageid" ); 25define( "FB_EVENTS_SHOW_AS", "showAs" ); 26define( "FB_EVENTS_FROM_DATE", "from" ); 27define( "FB_EVENTS_TO_DATE", "to" ); 28define( "FB_EVENTS_NR_ENTRIES", "numberOfEntries" ); 29define( "FB_EVENTS_SHOW_END_TIMES", "showEndTimes" ); 30define( "FB_EVENTS_LIMIT", "limit" ); 31 32// Configuration parameters 33define( "FB_EVENTS_DATE_FORMAT", "dformat" ); 34define( "FB_EVENTS_TIME_FORMAT", "tformat" ); 35define( "FB_EVENTS_TEMPLATE", "template" ); 36 37/** 38 * This plugin retrieves facebook events and displays them in HTML. 39 * 40 * Usage: {{facebookevents#appid=1234&secret=12345&fanpageid=12345&showAs=default}} 41 * 42 */ 43class syntax_plugin_facebookevents extends DokuWiki_Syntax_Plugin 44{ 45 function getInfo() { 46 return array( 47 'author' => 'J. Drost-Tenfelde', 48 'email' => 'info@drost-tenfelde.de', 49 'date' => '20162-09-29', 50 'name' => 'facebookevents', 51 'desc' => 'Displays facebook events as HTML', 52 'url' => 'https://www.dokuwiki.org/plugin:facebookevents', 53 ); 54 } 55 56 // implement necessary Dokuwiki_Syntax_Plugin methods 57 function getType() { 58 return 'substition'; 59 } 60 61 function getSort() { 62 return 42; 63 } 64 65 function connectTo($mode) { 66 $this->Lexer->addSpecialPattern('\{\{facebookevents.*?\}\}',$mode,'plugin_facebookevents'); 67 } 68 69 function getData($url) { 70 $ch = curl_init(); 71 $timeout = 5; 72 curl_setopt($ch, CURLOPT_URL, $url); 73 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 74 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); 75 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 76 $data = curl_exec($ch); 77 curl_close($ch); 78 return $data; 79 } 80 81 /** 82 * parse parameters from the {{facebookevents#...}} tag. 83 * @return an array that will be passed to the renderer function 84 */ 85 function handle($match, $state, $pos, &$handler) { 86 $match = substr($match, 17, -2); 87 parse_str($match, $params); 88 89 // Make sure the necessary data is set 90 if ( !$params[FB_EVENTS_APPLICATION_ID] ) { 91 $this->error = $this->getLang('error_appid_not_set'); 92 } 93 if ( !$params[FB_EVENTS_SECRET] ) { 94 $this->error = $this->getLang('error_secret_not_set'); 95 } 96 if ( !$params[FB_EVENTS_FAN_PAGE_ID] ) { 97 $this->error = $this->getLang('error_fanpageid_not_set'); 98 } 99 if ( !$params[FB_EVENTS_SHOW_AS] ) { 100 $params[FB_EVENTS_SHOW_AS] = 'default'; 101 } 102 if ( !$params[FB_EVENTS_LIMIT] ) { 103 $params[FB_EVENTS_LIMIT] = 0; 104 } 105 106 // Get the appropriate display template 107 $template = $this->getConf( $params[FB_EVENTS_SHOW_AS] ); 108 if ( !isset($template ) || $template == '' ) { 109 $template = $this->getConf('default'); 110 } 111 $params[FB_EVENTS_TEMPLATE] = $template; 112 113 // From 114 if ($params[FB_EVENTS_FROM_DATE] == 'today') { 115 $from = time(); 116 } else if (preg_match('#(\d\d)/(\d\d)/(\d\d\d\d)#', $params[FB_EVENTS_FROM_DATE], $fromDate)) { 117 // must be MM/dd/yyyy 118 $from = mktime(0, 0, 0, $fromDate[2], $fromDate[1], $fromDate[3]); 119 } else if (preg_match('/\d+/', $params[FB_EVENTS_FROM_DATE])) { 120 $from = $params[FB_EVENTS_FROM_DATE]; 121 } 122 $params[FB_EVENTS_FROM_DATE] = $from; 123 124 // Get the to parameter 125 if ($params[FB_EVENTS_TO_DATE] == 'today') { 126 $to = mktime(24, 0, 0, date("m") , date("d"), date("Y")); 127 128 } else if (preg_match('#(\d\d)/(\d\d)/(\d\d\d\d)#', $params[FB_EVENTS_TO_DATE], $toDate)) { 129 // must be MM/dd/yyyy 130 $to = mktime(0, 0, 0, $toDate[2], $toDate[1], $toDate[3]); 131 } else if (preg_match('/\d+/', $params[FB_EVENTS_TO_DATE])) { 132 $to = $params[FB_EVENTS_TO_DATE]; 133 } 134 $params[FB_EVENTS_TO_DATE] = $to; 135 136 // Sorting 137 if ( !$params[FB_EVENTS_SORT ] ) { 138 $params[FB_EVENTS_SORT ] = 'ASC'; 139 } 140 else { 141 if ( $params[FB_EVENTS_SORT] != 'DESC') { 142 $params[FB_EVENTS_SORT ] = 'ASC'; 143 } 144 } 145 146 return $params; 147 } 148 149 /** 150 * Retrieves the facebook events and parses them to HTML. 151 */ 152 function render($mode, &$renderer, $data) { 153 $info = $this->getInfo(); 154 155 $content = ''; 156 157 if ($mode == 'xhtml') { 158 // Catch errors 159 if ($this->error) { 160 $renderer->doc .= 'Error in Plugin '.$info['name'].': '.$this->error; 161 return; 162 } 163 164 // Get the date format 165 $date_format = $this->getConf(FB_EVENTS_DATE_FORMAT); 166 $time_format = $this->getConf(FB_EVENTS_TIME_FORMAT); 167 168 // Get the facebook information 169 $fb_app_id = $data[FB_EVENTS_APPLICATION_ID]; 170 $fb_secret = $data[FB_EVENTS_SECRET]; 171 $fb_page_id = $data[FB_EVENTS_FAN_PAGE_ID]; 172 173 // Get the access token using app-id and secret 174 $token_url ="https://graph.facebook.com/oauth/access_token?client_id={$fb_app_id}&client_secret={$fb_secret}&grant_type=client_credentials"; 175 $token_data = $this->getData( $token_url ); 176 177 $elements = split("=", $token_data ); 178 if ( count($elements) < 2) { 179 $renderer->doc .= 'Access token could not be retrieved for Plugin '.$info['name'].': '.$this->error; 180 return; 181 } 182 $fb_access_token = $elements[1]; 183 184 // Get the events 185 $since_date = $data[FB_EVENTS_FROM_DATE]; 186 $until_date = $data[FB_EVENTS_TO_DATE]; 187 188 $fb_fields="id,name,description,place,timezone,start_time,end_time,cover"; 189 190 $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}"; 191 $json = $this->getData( $json_link); 192 193 //$objects = json_decode($json, true, 512, JSON_BIGINT_AS_STRING); 194 $objects = json_decode($json, true); 195 196 // count the number of events 197 $event_count = count($objects['data']); 198 $displayed_entries = 0; 199 // Loop through the events 200 for ($index = $event_count - 1; $index >= 0; $index--){ 201 $event = $objects['data'][$index]; 202 203 date_default_timezone_set($event['timezone']); 204 205 $start_date = date( $date_format, strtotime($event['start_time'])); 206 $start_time = date( $time_format, strtotime($event['start_time'])); 207 208 if ( !isset($event['end_time'])) { 209 $event['end_time'] = $event['start_time']; 210 } 211 $end_date = date( $date_format, strtotime($event['end_time'])); 212 $end_time = date( $time_format, strtotime($event['end_time'])); 213 214 $eid = $event['id']; 215 $name = $event['name']; 216 217 $description = isset($event['description']) ? $event['description'] : ""; 218 // Limit? 219 if ( isset( $data[FB_EVENTS_LIMIT]) && ($data[FB_EVENTS_LIMIT] > 0 ) ) { 220 if ( strlen( $description ) > $data[FB_EVENTS_LIMIT] ) { 221 $description = substr( $description, 0, $data[FB_EVENTS_LIMIT] ); 222 // Find the first occurance of a space 223 $index = strrpos ( $description, ' ' ); 224 $description = substr( $description, 0, $index ).'...'; 225 } 226 } 227 $description = str_replace("\r\n", '<html><br /></html>', $description ); 228 $description = str_replace("\n", '<html><br /></html>', $description ); 229 230 231 $pic = isset($event['cover']['source']) ? $event['cover']['source'] : "https://graph.facebook.com/v2.7/{$fb_page_id}/picture"; 232 // Add a fix for urls with get parameters 233 if ( strpos($pic, '?') > 0 ) 234 { 235 $pic .= '&.png'; 236 } 237 238 // place 239 $place_name = isset($event['place']['name']) ? $event['place']['name'] : ""; 240 $street = isset($event['place']['location']['street']) ? $event['place']['location']['street'] : ""; 241 $city = isset($event['place']['location']['city']) ? $event['place']['location']['city'] : ""; 242 $country = isset($event['place']['location']['country']) ? $event['place']['location']['country'] : ""; 243 $zip = isset($event['place']['location']['zip']) ? $event['place']['location']['zip'] : ""; 244 245 $location=""; 246 247 if ( $place_name && $street & $city && $country && $zip){ 248 $location = "{$place_name}, {$street}, {$zip} {$city}, {$country}"; 249 } 250 else{ 251 $location = "Location not set or event data is too old."; 252 } 253 254 // Build the entry 255 $entry = $data['template']; 256 257 // Replace the values 258 $entry = str_replace('{title}', $name, $entry ); 259 $entry = str_replace('{description}', $description, $entry ); 260 $entry = str_replace('{location}', $location, $entry ); 261 $entry = str_replace('{place}', $place_name, $entry ); 262 $entry = str_replace('{city}', $city, $entry ); 263 $entry = str_replace('{country}', $country, $entry ); 264 $entry = str_replace('{zip}', $zip, $entry ); 265 $entry = str_replace('{image}', $pic, $entry); 266 $entry = str_replace('{image_large}', $pic, $entry); 267 $entry = str_replace('{image_small}', $pic, $entry); 268 $entry = str_replace('{image_square}', $pic, $entry); 269 270 // DateTime 271 if ( (!isset( $data[FB_EVENTS_SHOW_END_TIMES])) || $data[FB_EVENTS_SHOW_END_TIMES] == '1' ) { 272 273 // Are they the same date? 274 $compare_start_date = date( "Ymd", strtotime($event['start_time'])); 275 $compare_end_date = date( "Ymd", strtotime($event['end_time'])); 276 277 if ( $compare_start_date == $compare_end_date ) { 278 $datetime_string = $start_date; 279 //if ( isset($event['is_date_only']) && (!$event['is_date_only'])) { 280 $datetime_string = $datetime_string.' '.$start_time.' - '.$end_time; 281 282 //} 283 $entry = str_replace('{date}', $date_string, $entry ); 284 $entry = str_replace('{datetime}', $datetime_string, $entry ); 285 } 286 else { 287 $date_string = $start_date.' - '.$end_date; 288 $datetime_string = $date_string; 289 //if ( isset($event['is_date_only']) && (!$event['is_date_only'])) { 290 $datetime_string = $start_date.' '.$start_time.' - '.$end_date.' '.$end_time; 291 //} 292 $entry = str_replace('{date}', $date_string, $entry ); 293 $entry = str_replace('{datetime}', $datetime_string, $entry ); 294 } 295 } 296 else { 297 $entry = str_replace('{date}', $start_date, $entry ); 298 $entry = str_replace('{datetime}', $start_date.' '.$start_time); 299 } 300 301 302 // [[ url | read more ] 303 $event_url = "http://www.facebook.com/events/".$eid; 304 $entry = str_replace('{url}', $event_url, $entry ); 305 $entry = str_replace('{more}', '[['.$event_url.'|'.$this->getLang('read_more').']]', $entry ); 306 307 // Add the entry to the content 308 $content .= $entry; 309 310 // Only display a maximum number of entries (if set) 311 $displayed_entries++; 312 if ( isset( $data[FB_EVENTS_NR_ENTRIES] ) && $displayed_entries >= $data[FB_EVENTS_NR_ENTRIES] ) { 313 break; 314 } 315 } 316 317 //$renderer->doc .= $ret; 318 $html = p_render($mode, p_get_instructions( $content ), $info ); 319 $renderer->doc .= $html; 320 321 // Set the timezone back to the original 322 //date_default_timezone_set($origin_timezone); 323 324 return true; 325 } 326 return false; 327 } 328} 329 330?>