View source
<?php
define('AGENDA_MIN_API_VERSION', '1.1.2');
function agenda_menu() {
$items = array();
$items['admin/config/services/agenda'] = array(
'title' => 'Agenda',
'type' => MENU_NORMAL_ITEM,
'description' => 'Create and configure agenda blocks which utilise Google Calendar\'s web service.',
'page callback' => 'agenda_admin',
'page arguments' => array(
'agenda_admin',
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
);
$items['admin/config/services/agenda/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/services/agenda/googleapi'] = array(
'title' => 'Settings',
'description' => 'Set Google API Key',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'agenda_admin_googleapi',
),
'access arguments' => array(
'configure agenda blocks',
),
'type' => MENU_LOCAL_TASK,
'file' => 'agenda.admin.php',
);
$items['admin/config/services/agenda/0/configure'] = array(
'title' => 'Add new block',
'type' => MENU_LOCAL_ACTION,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'agenda_admin_configure',
4,
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
);
$items['admin/config/services/agenda/%/configure'] = array(
'title' => 'Configure agenda block settings',
'type' => MENU_LOCAL_ACTION,
'context' => MENU_CONTEXT_INLINE,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'agenda_admin_configure',
4,
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
'weight' => -4,
);
$items['admin/config/services/agenda/%/delete'] = array(
'title' => 'Delete agenda block',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'agenda_admin_delete',
4,
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
'weight' => -3,
);
$items['admin/config/services/agenda/%/debug'] = array(
'title' => 'Debug agenda block',
'type' => MENU_LOCAL_ACTION,
'context' => MENU_CONTEXT_INLINE,
'page callback' => 'agenda_debug',
'page arguments' => array(
4,
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
'weight' => -2,
);
$items['admin/config/services/agenda/%/clear'] = array(
'title' => 'Clear agenda block cache',
'type' => MENU_LOCAL_ACTION,
'context' => MENU_CONTEXT_INLINE,
'page callback' => 'agenda_clear',
'page arguments' => array(
4,
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
'weight' => -1,
);
return $items;
}
function agenda_permission() {
return array(
'access agenda content' => array(
'title' => t('access agenda content'),
'description' => t('View blocks created by Agenda module'),
),
'configure agenda blocks' => array(
'title' => t('configure agenda blocks'),
'description' => t('Create and edit Agenda blocks'),
),
);
}
function agenda_libraries_info() {
$libraries['google-api-php-client'] = array(
'name' => 'Google API Client Library for PHP',
'vendor url' => 'https://github.com/google/google-api-php-client',
'download url' => 'https://github.com/google/google-api-php-client/archive/1.1.2.zip',
'version arguments' => array(
'file' => 'src/Google/Client.php',
'pattern' => '/LIBVER = "([0-9\\.a-z]+)/',
'lines' => 29,
),
'versions' => array(
AGENDA_MIN_API_VERSION => array(),
),
'files' => array(
'php' => array(
'src/Google/Client.php',
),
),
);
return $libraries;
}
function agenda_block_info() {
$res = db_query("SELECT bid, value FROM {agenda} WHERE name = :name", array(
':name' => 'title',
));
$blocks = array();
while ($block = $res
->fetchObject()) {
$blocks[$block->bid] = array(
'info' => t('Agenda: @title', array(
'@title' => agenda_variable_get($block->bid, 'title', 'New block'),
)),
'cache' => DRUPAL_CACHE_GLOBAL,
);
}
return $blocks;
}
function agenda_block_view($delta) {
if (!user_access('access agenda content')) {
return FALSE;
}
$markup = agenda_display_block($delta);
if (!$markup) {
return FALSE;
}
$basepath = drupal_get_path('module', 'agenda');
return array(
'subject' => t('Agenda'),
'content' => array(
'#contextual_links' => array(
'agenda' => array(
'admin/config/services/agenda',
array(
$delta,
),
),
),
'#markup' => $markup,
'#attached' => array(
'css' => array(
$basepath . '/agenda.css',
),
'js' => array(
$basepath . '/agenda.js',
),
),
),
);
}
function agenda_theme($existing, $type, $theme, $path) {
$theme = array(
'agenda_block' => array(
'variables' => array(
'events' => array(),
'block' => new stdClass(),
),
'template' => 'agenda-block',
),
'agenda_admin' => array(
'variables' => array(
'table' => '',
),
'template' => 'agenda-admin',
),
);
return $theme;
}
function agenda_display_block($delta = 0) {
if ($delta === 0 || !($block = agenda_settings($delta))) {
return false;
}
$events = agenda_get_events($block);
$events = agenda_group_events_for_block($block, $events);
if (count($events)) {
$output = theme('agenda_block', array(
'events' => $events,
'block' => $block,
));
}
elseif (empty($block->noeventstext)) {
$output = NULL;
}
else {
$output = filter_xss($block->noeventstext);
}
return $output;
}
function agenda_settings($delta) {
$res = db_query('SELECT name, value FROM {agenda} WHERE bid = :bid', array(
':bid' => $delta,
));
$settings = new stdClass();
$settings->bid = $delta;
while ($row = $res
->fetchAssoc()) {
$settings->{$row['name']} = $row['value'];
}
if (!count($settings) || !isset($settings->title)) {
$settings = FALSE;
}
return $settings;
}
function agenda_variable_get($delta, $parameter, $default_value) {
$value = db_query("SELECT value FROM {agenda} WHERE bid = :bid AND name = :name", array(
':bid' => $delta,
':name' => $parameter,
))
->fetchField();
if ($value === FALSE) {
$value = $default_value;
}
return $value;
}
function agenda_variable_set($bid, $name, $value) {
return db_merge('agenda')
->key(array(
'bid' => $bid,
'name' => $name,
))
->fields(array(
'value' => $value,
))
->execute();
}
function agenda_get_events($block, $cache = TRUE) {
if ($cache) {
$cache_key = 'agenda_block_' . $block->bid;
$eventdata = cache_get($cache_key, 'cache');
if ($eventdata && $eventdata->expire > REQUEST_TIME) {
return $eventdata->data;
}
}
$calendars = preg_split('@\\r\\n?|\\n@', $block->calendars);
$calendars = array_map('trim', $calendars);
if (empty($calendars)) {
return FALSE;
}
$eventdata = array();
foreach ($calendars as $calindex => $googleid) {
list($address, $token) = _agenda_parse_googleid($googleid);
$calendar = _agenda_load_google($address, $token, $block);
if (!$calendar) {
watchdog('agenda', 'Unable to load the calendar feed (@feed) for block @bid', array(
'@feed' => $googleid,
'@bid' => $block->bid,
));
continue;
}
foreach ($calendar
->getItems() as $google_event) {
$event = _agenda_parse_event($google_event, $block);
if (!$event) {
continue;
}
$event['index'] = (int) $calindex;
$event['calendar'] = (string) $calendar->summary;
$eventdata[] = $event;
}
}
$timestamps = array();
foreach ($eventdata as $event) {
$timestamps[] = $event['start timestamp'];
}
array_multisort($timestamps, SORT_NUMERIC, $eventdata);
if ($cache) {
$expires = REQUEST_TIME + $block->cachetime;
cache_set($cache_key, $eventdata, 'cache', $expires);
}
return $eventdata;
}
function _agenda_parse_event($google_response, $block) {
$tz = new DateTimeZone($block->timezone);
$updated = new DateTime($google_response->updated, $tz);
$start = new DateTime((string) $google_response->start->dateTime ? $google_response->start->dateTime : $google_response->start->date, $tz);
$end = new DateTime((string) $google_response->end->dateTime ? $google_response->end->dateTime : date('Y-m-d', strtotime($google_response->end->date . " -1 day")), $tz);
$event = array();
$event['title'] = htmlspecialchars((string) $google_response->summary);
$event['where'] = htmlspecialchars((string) $google_response->location);
$event['description'] = _filter_autop(filter_xss((string) $google_response->description));
$event['timezone'] = $block->timezone;
$event['start original'] = (string) $google_response->start->dateTime;
$event['start date'] = format_date(strtotime($start
->format('c')), 'custom', $block->dateformat, $block->timezone);
$event['start time'] = format_date(strtotime($start
->format('c')), 'custom', $block->timeformat, $block->timezone);
$event['start timestamp'] = strtotime($start
->format('c'));
$event['end original'] = (string) $google_response->end->dateTime;
$event['end date'] = format_date(strtotime($end
->format('c')), 'custom', $block->dateformat, $block->timezone);
$event['end time'] = format_date(strtotime($end
->format('c')), 'custom', $block->timeformat, $block->timezone);
$event['end timestamp'] = strtotime($end
->format('c'));
$event['updated'] = format_date(strtotime($updated
->format('c')), 'custom', $block->dateformat, $block->timezone);
$event['url'] = (string) $google_response->htmlLink;
$event['link'] = l($block->linktext, $event['url'] . '&ctz=' . $block->timezone);
$event['when'] = $start
->format('Y-m-d');
$event['event id'] = $google_response->id;
$event['hangout url'] = $google_response->hangoutLink;
$event['hangout link'] = !empty($block->hangoutlinktext) ? l($block->hangoutlinktext, $event['hangout url']) : NULL;
$event['iCalUID'] = $google_response->iCalUID;
$event['recurringEventId'] = $google_response->recurringEventId;
$event['creator email'] = $google_response->creator->email;
$event['creator displayName'] = $google_response->creator->displayName;
$event['organizer email'] = $google_response->organizer->email;
$event['organizer displayName'] = $google_response->organizer->displayName;
if ($google_response->start->date) {
$event['start time'] = '';
}
if ($google_response->end->date) {
$event['end time'] = '';
}
if ($google_response->start->date && $google_response->end->date) {
$event['allday'] = true;
}
return $event;
}
function _agenda_translate($field) {
$t['title'] = t('Title');
$t['where'] = t('Where');
$t['description'] = t('Description');
$t['start original'] = t('Start original');
$t['start timestamp'] = t('Start timestamp');
$t['start date'] = t('Start date');
$t['start time'] = t('Start time');
$t['end original'] = t('End original');
$t['end timestamp'] = t('End timestamp');
$t['end date'] = t('End date');
$t['end time'] = t('End time');
$t['updated'] = t('Updated');
$t['url'] = t('URL');
$t['link'] = t('Link');
$t['when'] = t('When');
$t['calendar'] = t('Calendar');
$t['timezone'] = t('Timezone');
$t['event id'] = t('Event ID');
$t['hangout url'] = t('Hangout URL');
$t['hangout link'] = t('Hangout link');
$t['iCalUID'] = t('iCal UID');
$t['recurringEventId'] = t('Recurring Event ID');
$t['creator email'] = t('Creator Email');
$t['creator displayName'] = t('Creator Display Name');
$t['organizer email'] = t('Organizer Email');
$t['organizer displayName'] = t('Organizer Display Name');
return $t[$field];
}
function _agenda_load_google($address, $key, $block) {
$calendar_id = $address;
$googlekey = !empty($block->googleapi_override) ? $block->googleapi_override : variable_get('agenda_googleapi', '');
$autoload_path = libraries_get_path('google-api-php-client') . '/autoload.php';
if (!file_exists($autoload_path)) {
drupal_set_message('Agenda: The google-api-php-client library was not found.
See admin/reports/status and/or the Agenda module\'s README for more
information.', 'error');
return;
}
include_once $autoload_path;
$client = new Google_Client();
$client
->setApplicationName('agenda_events_feed');
$client
->setDeveloperKey($googlekey);
$service = new Google_Service_Calendar($client);
$optParams = array(
'orderBy' => 'startTime',
'singleEvents' => 'true',
'timeMin' => date('Y-m-d', strtotime($block->start)) . 'T00:00:00' . date('P'),
'timeMax' => date('Y-m-d', strtotime($block->end)) . 'T00:00:00' . date('P'),
'maxResults' => $block->maxevents,
'timeZone' => $block->timezone,
);
try {
$events = $service->events
->listEvents($calendar_id, $optParams);
} catch (Exception $e) {
drupal_set_message(t('Agenda: Bad call to list events. Check Google API Key or Calendar Address.'), 'error');
drupal_set_message('<pre>' . $e . '</pre>', 'error');
return;
}
return $events;
}
function _agenda_parse_googleid($googleid) {
$parts = explode('/', $googleid);
if (!valid_email_address($parts[0])) {
return FALSE;
}
$token = 'public';
if (count($parts) === 2) {
$token = $parts[1];
}
return array(
$parts[0],
$token,
);
}
function agenda_group_events_for_block($block, array $events) {
$groupedevents = array();
foreach ($events as $event) {
$groupedevents[$event['when']][] = $event;
}
ksort($groupedevents);
$datelimit = $block->datelimit;
$count = 0;
$events = array();
foreach ($groupedevents as $date => $eventdata) {
if ($count >= $datelimit) {
break;
}
$events[$date] = $eventdata;
$count++;
}
return $events;
}