public function date_ical_plugin_row_ical_fields::render in Date iCal 7.3
Same name and namespace in other branches
- 7.2 includes/date_ical_plugin_row_ical_fields.inc \date_ical_plugin_row_ical_fields::render()
Returns an Event array row in the query with index: $row->index.
Overrides views_plugin_row::render
File
- includes/
date_ical_plugin_row_ical_fields.inc, line 117 - Defines the iCal Fields row style plugin, which lets users map view fields to the components of the VEVENTs in the iCal feed.
Class
- date_ical_plugin_row_ical_fields
- A Views plugin which builds an iCal VEVENT from a views row with Fields.
Code
public function render($row) {
$date_field_name = $this->options['date_field'];
// If this view is set to use the first populated date field, check each
// field in the row to find the first non-NULL Date field.
if ($date_field_name == 'first_available') {
foreach (get_object_vars($row) as $name => $value) {
if (strpos($name, 'field_field') === 0) {
// This property's name starts with "field_field", which means it's
// the actual field data for a field in this view.
if (!empty($value[0]['raw']['date_type'])) {
// Cut off the first "field_" from $name to get the field name.
$date_field_name = substr($name, 6);
break;
}
}
}
}
// Fetch the event's date information.
try {
if ($date_field_name == 'first_available') {
// If $date_field_name is still 'first_available' at this point, we
// couldn't find an available Date value. Processing cannot proceed.
$title = strip_tags($this->view->style_plugin
->get_field($row->index, $this->options['title_field']));
if (empty($title)) {
$title = "Undetermined title";
}
throw new BlankDateFieldException(t('The row titled "@title" has no available Date value. An iCal entry cannot be created for it.', array(
'@title' => $title,
)));
}
$date = $this
->get_row_date($row, $date_field_name);
} catch (BlankDateFieldException $e) {
// Unless the user has specifically said that they want to skip rows
// with blank dates, let this exception percolate.
if ($this->options['additional_settings']['skip_blank_dates']) {
return NULL;
}
else {
throw $e;
}
}
// Create the event by starting with the date array from this row.
$event = $date;
$entity = $row->_field_data[$this->view->base_field]['entity'];
$entity_type = $row->_field_data[$this->view->base_field]['entity_type'];
// Add the CREATED, LAST-MODIFIED, and URL components based on the entity.
// According to the iCal standard, CREATED and LAST-MODIFIED must be UTC.
// Fortunately, Drupal stores timestamps in the DB as UTC, so we just need
// to specify that UTC be used rather than the server's local timezone.
if (isset($entity->created)) {
$event['created'] = new DateObject($entity->created, 'UTC');
}
if (isset($entity->changed)) {
$event['last-modified'] = new DateObject($entity->changed, 'UTC');
}
elseif (isset($entity->created)) {
// If changed is unset, but created is, use that for last-modified.
$event['last-modified'] = new DateObject($entity->created, 'UTC');
}
$uri = entity_uri($entity_type, $entity);
$uri['options']['absolute'] = TRUE;
$event['url'] = url($uri['path'], $uri['options']);
// Generate a unique ID for this event by emulating the way the Date module
// creates a Date ID.
$is_relationaship = FALSE;
$date_field_delta = 0;
if (isset($row->{"field_data_{$date_field_name}_delta"})) {
$date_field_delta = $row->{"field_data_{$date_field_name}_delta"};
}
else {
if (!empty($entity->{$date_field_name})) {
// I'm not sure why the "field_data_{field_name}_delta" field is part of
// the $row, so it's possible that it will sometimes be missing. If it
// is, make an educated guess about the delta by comparing this row's
// start date to each of the entity's dates.
if (!empty($entity->{$date_field_name}['und'])) {
foreach ($entity->{$date_field_name}['und'] as $ndx => $date_array) {
if ($date['start']->originalTime == $date_array['value']) {
$date_field_delta = $ndx;
break;
}
}
}
}
else {
if (!empty($this->display->display_options['fields'][$date_field_name]['relationship'])) {
// This block covers another potential situation where
// "field_data_{field_name}_delta" is missing: dates gathered through a
// relationship. We retrieve the name of the relationship through which
// the date field is being gathered, and the delta of that relationship,
// in case it's multi-delta.
$rel_name = $this->display->display_options['fields'][$date_field_name]['relationship'];
$rel_delta = $row->index;
$is_relationaship = TRUE;
}
else {
// We couldn't obtain enough info to determine the real $date_field_delta.
// So we just leave it as 0. Hopefully this won't cause problems.
}
}
}
$entity_id = $row->{$this->view->base_field};
global $base_url;
$domain = preg_replace('#^https?://#', '', $base_url);
if (!$is_relationaship) {
$event['uid'] = "calendar.{$entity_id}.{$date_field_name}.{$date_field_delta}@{$domain}";
}
else {
$event['uid'] = "calendar.{$entity_id}.{$rel_name}.{$rel_delta}.{$date_field_name}.{$date_field_delta}@{$domain}";
}
// Because of the way that Date implements repeating dates, we're going to
// be given a separate view result for each repeat. We only want to
// render a VEVENT (with an RRULE) for the first instance of that date, so
// we need to record the entity ID and field name for each result that has
// an RRULE, then skip any that we've already seen.
if (!empty($date['rrule'])) {
$repeat_id = "{$entity_id}.{$date_field_name}";
if (!isset($this->repeated_dates[$repeat_id])) {
$this->repeated_dates[$repeat_id] = $repeat_id;
}
else {
return FALSE;
}
}
// Retrieve the rendered text fields.
$text_fields['summary'] = $this
->get_field($row->index, $this->options['title_field']);
$text_fields['description'] = $this
->get_field($row->index, $this->options['description_field']);
$text_fields['location'] = $this
->get_field($row->index, $this->options['location_field']);
$text_fields['categories'] = $this
->get_field($row->index, $this->options['categories_field']);
// Allow other modules to alter the rendered text fields before they get
// sanitized for iCal-compliance. This is most useful for fields of type
// "Content: Rendered Node", which are likely to have complex HTML.
$context = array(
'row' => $row,
'row_index' => $row->index,
'language' => $this->language,
'options' => $this->options,
);
drupal_alter('date_ical_export_html', $text_fields, $this->view, $context);
// Sanitize the text fields for iCal compliance, and add them to the event.
$event['summary'] = date_ical_sanitize_text($text_fields['summary']);
$event['location'] = date_ical_sanitize_text($text_fields['location']);
$event['description'] = date_ical_sanitize_text($text_fields['description']);
$event['categories'] = date_ical_sanitize_text($text_fields['categories']);
// Allow other modules to alter the event object before it gets passed to
// the style plugin to be converted into an iCal VEVENT.
drupal_alter('date_ical_export_raw_event', $event, $this->view, $context);
return $event;
}