Commit fe4415f8 authored by Robert Rollins's avatar Robert Rollins

Several changes:

- Issue #1529506, Added optional webcal:// support.
- Issue #1890736, Added ability to exclude the X-WR-CALNAME property.
- Issue #1565410, Sites with "Clean URLs" disabled can now download feeds normally.
- Several minor bigfixes, and cleanup of the iCal icon theming.
parent df42e7c1
Date iCal 7.x
===================
===================
Version 7.x-2.1 through 7.x-2.3
===================
- Issue #1529506, Added optional webcal:// support.
- Issue #1890736, Added ability to exclude the X-WR-CALNAME property.
- Issue #1565410, Sites with "Clean URLs" disabled can now download feeds normally.
- Several minor bigfixes, and cleanup of the iCal icon theming.
===================
Version 7.x-2.0
===================
......
......@@ -114,9 +114,11 @@ The Feeds plugin was originally written by ekes, for the "iCal feed parser"
module (http://www.drupal.org/project/parser_ical). It was modified and
improved for Date iCal by coredumperror.
At this time, Date iCal supports outputting iCal calendars only for groups of
events. To put an "Add to calendar" button on individual event nodes, try the
<a href="http://drupal.org/project/addtocal">Add to Cal</a> module.
At this time, Date iCal supports outputting iCal calendars only through Views.
To put an "Add to calendar" button on individual event nodes, try the
<a href="http://drupal.org/project/addtocal">Add to Cal</a> module, or follow
the instructions created by the estimable nmc at:
http://nmc-codes.blogspot.ca/2012/11/creating-ical-feed-for-single-node-in.html
Developers who wish to implement more powerful manipulation of event data can
read the date_ical.api.php file to learn about the various alter hooks that
......
......@@ -23,7 +23,7 @@ function date_ical_views_api() {
function date_ical_theme($existing, $type, $theme, $path) {
return array(
'date_ical_icon' => array(
'variables' => array('url' => NULL),
'variables' => array('url' => NULL, 'tooltip' => NULL),
),
);
}
......@@ -32,26 +32,20 @@ function date_ical_theme($existing, $type, $theme, $path) {
* The theme for the ical icon.
*/
function theme_date_ical_icon($variables) {
$url = $variables['url'];
$variables = array(
'path' => drupal_get_path('module', 'date_ical') . '/images/ical-feed-icon-34x14.png',
'title' => t('Add to my calendar'),
'alt' => t('Add to my calendar'),
);
// Change the scheme to webcal:// so that calendar clients can automatically
// subscribe via the iCal link.
$url = str_replace('http://', 'webcal://', $url);
$variables['path'] = drupal_get_path('module', 'date_ical') . '/images/ical-feed-icon-34x14.png';
$variables['alt'] = $variables['title'] = $variables['tooltip'];
if ($image = theme('image', $variables)) {
return '<a href="' . check_url($url) . '" class="ical-icon" title="ical">' . $image . '</a>';
return "<a href='{$variables['url']}' class='ical-icon'>$image</a>";
}
else {
return "<a href='{$variables['url']}' class='ical-icon'>{$variables['tooltip']}</a>";
}
}
/**
* Implements hook_preprocess_HOOK() for nodes.
*
* Hide extraneous information when printing an iCal node. The same thing can be
* done in the theme for other entities, and this function can be overridden in
* the theme to produce different results for nodes.
* Hide extraneous information when rendering the iCal view mode of a node.
*/
function date_ical_preprocess_node(&$variables) {
if (isset($variables['view_mode']) && $variables['view_mode'] == 'ical') {
......@@ -323,13 +317,14 @@ function date_ical_get_location_fields($base = 'node', $reset = FALSE) {
/**
* Identify all potential LOCATION fields.
* This is a cut down version of _date_views_fields() from date_views_fields.inc in date_views module.
* This is a cut down version of _date_views_fields() from date_views_fields.inc
* in date_views module.
*
* @return
* array with fieldname, type, and table.
* @see
* date_views_date_views_fields() which implements
* the hook_date_views_fields() for the core date fields.
* date_views_date_views_fields(), which implements hook_date_views_fields()
* for the core date fields.
*/
function _date_ical_get_location_fields($base = 'node') {
// Make sure $base is never empty.
......
......@@ -68,7 +68,7 @@ class date_ical_plugin_row_ical_entity extends views_plugin_row {
// Build the select dropdown for the text/node_reference field that the user
// wants to use to (optionally) populate the LOCATION.
$location_fields = date_ical_get_location_fields($this->base_table);
$location_options = array('none' => '- None -');
$location_options = array('none' => t('- None -'));
foreach ($location_fields['name'] as $item => $value) {
$location_options[$item] = $value['label'];
}
......
......@@ -10,11 +10,8 @@
*/
class date_ical_plugin_style_ical_feed extends views_plugin_style {
function _default_calendar_name() {
$view_title = $this->view->get_title();
$calendar_name = variable_get('site_name', 'Drupal');
$calendar_name .= !empty($view_title) ? ': ' . $view_title : '';
return $calendar_name;
function _get_option($option_name) {
return isset($this->options[$option_name]) ? $this->options[$option_name] : '';
}
// Sets up the iCal feed icon on calendar pages.
......@@ -26,13 +23,23 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
$url_options['query'] = $input;
}
$url_options['absolute'] = TRUE;
$url = url($this->view->get_url(NULL, $path), $url_options);
if (empty($this->preview)) {
$this->view->feed_icon .= theme('date_ical_icon', array('url' => $url, 'title' => $title));
// If the user didn't disable the option, change the scheme to webcal:// so
// that calendar clients can automatically subscribe via the iCal link.
if (!$this->_get_option('disable_webcal')) {
$url = str_replace('http://', 'webcal://', $url);
}
// Only render the feed icon and header tag if this isn't a Preview on the
// View config page.
if (empty($this->view->live_preview)) {
$tooltip = t('Add to My Calendar');
$this->view->feed_icon .= theme('date_ical_icon', array('url' => check_url($url), 'tooltip' => $tooltip));
drupal_add_html_head_link(array(
'rel' => 'alternate',
'type' => 'application/calendar',
'title' => $title,
'type' => 'text/calendar',
'title' => $tooltip,
'href' => $url
));
}
......@@ -44,17 +51,33 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
$form['cal_name'] = array(
'#type' => 'textfield',
'#title' => t('iCal Calendar Name'),
'#default_value' => $this->options['cal_name'],
'#default_value' => $this->_get_option('cal_name'),
'#description' => t('This will appear as the title of the iCal feed. If ' .
'left blank, the View Title will be used. If that is also blank, the site ' .
'name will be inserted as the iCal feed title.'),
);
$form['no_calname'] = array(
'#type' => 'checkbox',
'#title' => t('Exclude Calendar Name'),
'#default_value' => $this->_get_option('no_calname'),
'#description' => t("Excluding the X-WR-CALNAME value from the iCal Feed causes
some calendar clients to add the events in the feed to an existing calendar, rather
than creating a whole new calendar for them."),
);
$form['disable_webcal'] = array(
'#type' => 'checkbox',
'#title' => t('Disable webcal://'),
'#default_value' => $this->_get_option('disable_webcal'),
'#description' => t("By default, the feed URL will use the webcal:// scheme, which allows calendar
clients to easily subscribe to the feed. If you want your users to instead download this iCal
feed as a file, activate this option."),
);
}
function render() {
if (empty($this->row_plugin) || $this->row_plugin->plugin_name != 'date_ical') {
debug('views_plugin_style_ical_feed: This style plugin supports only the iCal Entity row plugin.');
return 'To enable iCal output, this view\'s Format must be configured to Show: iCal Entity.';
return t('To enable iCal output, this view\'s Format must be configured to Show: iCal Entity.');
}
$rows = array();
foreach ($this->view->result as $row_index => $row) {
......@@ -72,9 +95,9 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
$vcalendar->setMethod('PUBLISH');
// If the iCal Calendar Name has been set in the Feed Style options, it's used as the
// title in the iCal feed. If not, the View Title is used. If that is blank, then the
// Site Name is used.
$cal_name = $this->options['cal_name'];
// title in the iCal feed. If not, the View Title is used. If that is also blank, then
// the Site Name is used.
$cal_name = $this->_get_option('cal_name');
if (empty($cal_name)) {
$view_title = $this->view->get_title();
if (!empty($view_title)) {
......@@ -84,9 +107,12 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
$cal_name = variable_get('site_name', 'Drupal');
}
}
$vcalendar->setProperty('x-wr-calname', $cal_name, array('VALUE' => 'TEXT'));
// Only include the X-WR-CALNAME property if the user didn't check "Exclude Calendar Name".
if (!$this->_get_option('no_calname')) {
$vcalendar->setProperty('x-wr-calname', $cal_name, array('VALUE' => 'TEXT'));
}
// Now add the vevents.
// Now add the VEVENTs.
$timezones = array();
foreach ($rows as $row) {
if (empty($row)) {
......@@ -152,14 +178,14 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
date_timezone_set($except, $rendered_start['tz']);
$rendered_date = $except->toArray();
$exdates[] = array(
'year' => $rendered_date['year'],
'year' => $rendered_date['year'],
'month' => $rendered_date['month'],
'day' => $rendered_date['day'],
'day' => $rendered_date['day'],
// Use the time information from the start date.
'hour' => $rendered_start['hour'],
'min' => $rendered_start['minute'],
'hour' => $rendered_start['hour'],
'min' => $rendered_start['minute'],
'second' => $rendered_start['second'],
'tz' => $rendered_start['tz']->getName(),
'tz' => $rendered_start['tz']->getName(),
);
}
// Add those exclusions as 'EXDATE's.
......@@ -174,27 +200,27 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
$rendered_date = $add->toArray();
$add_date = array(
'year' => $rendered_date['year'],
'year' => $rendered_date['year'],
'month' => $rendered_date['month'],
'day' => $rendered_date['day'],
'day' => $rendered_date['day'],
// Use the time information from the start date.
'hour' => $rendered_start['hour'],
'min' => $rendered_start['minute'],
'hour' => $rendered_start['hour'],
'min' => $rendered_start['minute'],
'second' => $rendered_start['second'],
'tz' => $rendered_start['tz']->getName(),
'tz' => $rendered_start['tz']->getName(),
);
// If there was an end date specified, use that too.
if (!empty($row['end'])) {
$add_date = array($add_date);
$add_date[] = array(
'year' => $rendered_date['year'],
'year' => $rendered_date['year'],
'month' => $rendered_date['month'],
'day' => $rendered_date['day'],
'day' => $rendered_date['day'],
// Use the time information from the end date.
'hour' => $rendered_end['hour'],
'min' => $rendered_end['minute'],
'hour' => $rendered_end['hour'],
'min' => $rendered_end['minute'],
'second' => $rendered_end['second'],
'tz' => $rendered_end['tz']->getName(),
'tz' => $rendered_end['tz']->getName(),
);
}
......@@ -230,7 +256,7 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
drupal_alter('date_ical_feed_ical_vevent_render', $vevent, $this->view, $row);
}
// Now add all the timezones we just used to the file too.
// Now add all the timezones we just used to the calendar.
foreach ($timezones as $timezone) {
iCalUtilityFunctions::createTimezone($vcalendar, $timezone);
}
......@@ -244,21 +270,22 @@ class date_ical_plugin_style_ical_feed extends views_plugin_style {
// The iCalcreator library isn't available, so we can't output anything.
$output = 'Please install the iCalcreator library to enable iCal output.';
}
if (empty($variables['view']->live_preview)) {
// These steps shouldn't be run when doing a Preview on the View config page.
if (empty($this->view->live_preview)) {
// Prevent devel module from appending queries to ical export.
$GLOBALS['devel_shutdown'] = FALSE;
drupal_add_http_header('Content-Type', 'application/calendar; charset=utf-8');
}
header('Content-type: text/calendar');
// For sites with Clean URLs disabled, the "path" value in the view Display
// doesn't actually get applied to the URL of the calendar feed. So, we
// need to manually instruct browsers to download a .ics file.
if (!variable_get('clean_url', FALSE)) {
$path_array = explode('/', $this->display->display_options['path']);
$filename = array_pop($path_array);
header("Content-Disposition: attachment; filename=\"$filename\"");
drupal_add_http_header('Content-Type', 'text/calendar; charset=utf-8');
// For sites with Clean URLs disabled, the "path" value in the view Display
// doesn't actually get applied to the URL of the calendar feed. So, we
// need to manually instruct browsers to download a .ics file.
if (!variable_get('clean_url', FALSE)) {
$path_array = explode('/', $this->display->display_options['path']);
$filename = array_pop($path_array);
drupal_add_http_header('Content-Disposition', "attachment; filename=\"$filename\"");
}
}
return $output;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment