View source
<?php
define('AGENDA_SOURCEPATTERN', 'http://www.google.com/calendar/feeds/%s/%s/full?hl=en&singleevents=true&sortorder=ascending&orderby=starttime&start-min=%s&start-max=%s&max-results=%d&ctz=%s');
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/%/configure'] = array(
'title' => 'Configure agenda block',
'type' => MENU_CALLBACK,
'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/%/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',
);
$items['admin/config/services/agenda/%/debug'] = array(
'title' => 'Test settings',
'type' => MENU_CALLBACK,
'page callback' => 'agenda_debug',
'page arguments' => array(
4,
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
);
$items['admin/config/services/agenda/%/clear'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'agenda_clear',
'page arguments' => array(
4,
),
'access arguments' => array(
'configure agenda blocks',
),
'file' => 'agenda.admin.php',
);
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_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) {
$markup = agenda_display_block($delta);
if (!$markup) {
return FALSE;
}
$basepath = drupal_get_path('module', 'agenda');
return array(
'subject' => t('Agenda'),
'content' => array(
'#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_xml($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->entry as $eventxml) {
$event = _agenda_parse_event($eventxml, $block);
if (!$event) {
continue;
}
$event['index'] = (int) $calindex;
$event['calendar'] = (string) $calendar->title;
$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($xml, $block) {
$gd = $xml
->children('http://schemas.google.com/g/2005');
$tz = new DateTimeZone($block->timezone);
$updated = new DateTime($xml->updated, $tz);
$start = new DateTime((string) $gd->when
->attributes()->startTime, $tz);
$end = new DateTime((string) $gd->when
->attributes()->endTime, $tz);
try {
$published = new DateTime((string) $xml->published, $tz);
} catch (Exception $e) {
$published = new DateTime('now', $tz);
}
$event = array();
$event['title'] = htmlspecialchars((string) $xml->title);
$event['where'] = htmlspecialchars((string) $gd->where
->attributes()->valueString);
$event['description'] = _filter_autop(filter_xss((string) $xml->content));
$event['timezone'] = $block->timezone;
$event['start original'] = (string) $gd->when
->attributes()->startTime;
$event['start date'] = $start
->format($block->dateformat);
$event['start time'] = $start
->format($block->timeformat);
$event['start timestamp'] = strtotime($start
->format('c'));
$event['end original'] = (string) $gd->when
->attributes()->endTime;
$event['end date'] = $end
->format($block->dateformat);
$event['end time'] = $end
->format($block->timeformat);
$event['end timestamp'] = strtotime($end
->format('c'));
$event['published'] = $published
->format($block->dateformat);
$event['updated'] = $updated
->format($block->dateformat);
$link = (array) $xml->link[0];
$event['url'] = (string) $link['@attributes']['href'];
$event['link'] = l($block->linktext, $event['url']);
$event['when'] = $start
->format('Y-m-d');
if (strlen($gd->when
->attributes()->startTime) === 10) {
$event['start time'] = '';
$event['end time'] = '';
}
if ($event['start timestamp'] === $event['end timestamp'] - 86400) {
$event['end date'] = '';
}
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['published'] = t('Published');
$t['updated'] = t('Updated');
$t['url'] = t('URL');
$t['link'] = t('Link');
$t['when'] = t('When');
$t['calendar'] = t('Calendar');
$t['timezone'] = t('Timezone');
return $t[$field];
}
function _agenda_load_xml($address, $key, $block) {
$url = _agenda_feed_url($address, $key, $block);
$xml = drupal_http_request($url);
$data = FALSE;
if ($xml->code === '200') {
$data = simplexml_load_string($xml->data);
}
return $data;
}
function _agenda_feed_url($address, $key, $block) {
$url = sprintf(AGENDA_SOURCEPATTERN, urlencode(check_plain($address)), urlencode(check_plain($key)), date('Y-m-d', strtotime($block->start)), date('Y-m-d', strtotime($block->end)), $block->maxevents, $block->timezone);
return $url;
}
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;
}