View source
<?php
function date_copy_menu() {
$items = array();
$items['admin/content/date'] = array(
'title' => 'Date Import/Export',
'description' => 'Import and export date data.',
'access arguments' => array(
'administer nodes',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'date_copy_import_ical_form',
),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/content/date/import'] = array(
'title' => 'Import',
'access arguments' => array(
'administer nodes',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'date_copy_import_ical_form',
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items['admin/content/date/export'] = array(
'title' => 'Export',
'access arguments' => array(
'administer nodes',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'date_copy_export_form',
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items['admin/content/date/import/ical'] = array(
'title' => 'iCal',
'access arguments' => array(
'administer nodes',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'date_copy_import_ical_form',
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
);
$items['admin/content/date/import/event'] = array(
'title' => 'Events',
'access arguments' => array(
'administer nodes',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'date_copy_import_event_form',
),
'type' => MENU_LOCAL_TASK,
'weight' => 2,
);
$items['admin/content/date/import/csv'] = array(
'title' => 'CSV',
'access arguments' => array(
'administer nodes',
),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'date_copy_import_csv_form',
),
'type' => MENU_LOCAL_TASK,
'weight' => 3,
);
return $items;
}
function date_copy_type_form($target = TRUE) {
$form = array();
$node_types = node_get_types('names');
$fields = content_fields();
$type_options = array();
foreach ($fields as $field_name => $field) {
if ($field['type'] == 'date' || $field['type'] == 'datestamp') {
$type_options[$field['type_name']] = $node_types[$field['type_name']];
}
}
if (sizeof($type_options) < 1) {
drupal_set_message(t('There are no date fields in this database to import the data into. Please add a date field to the desired node types and be sure to indicate it uses both a "from" and a "to" date.'));
return $form;
}
$type = $target ? 'target_type' : 'source_type';
$label = $target ? t('Target type') : t('Source type');
$form[$type] = array(
'#type' => 'select',
'#options' => $type_options,
'#title' => $label,
'#default_value' => '',
);
return $form;
}
function date_copy_type_fields_form($type, $extended = FALSE) {
$form = array();
$fields = content_fields();
$date_options = array();
$description_options = array(
'' => '',
);
$uid_options = array(
'' => '',
);
$url_options = array(
'' => '',
);
$location_options = array(
'' => '',
);
foreach ($fields as $field_name => $field) {
if ($field['type_name'] == $type) {
if ($field['type'] == 'date' || $field['type'] == 'datestamp') {
$date_options[$field_name] = $field['widget']['label'];
}
if ($field['type'] == 'text') {
$description_options[$field_name] = $field['widget']['label'];
$location_options[$field_name] = $field['widget']['label'];
$uid_options[$field_name] = $field['widget']['label'];
$url_options[$field_name] = $field['widget']['label'];
}
if ($field['type'] == 'link') {
$url_options[$field_name] = $field['widget']['label'];
}
}
}
$description_options['body'] = t('body');
if (sizeof($date_options) < 1) {
drupal_set_message(t('There are no date fields in this database to import the data into. Please add a date field to the desired node types and be sure to indicate it uses both a "from" and a "to" date.'));
return $form;
}
$form['date_field'] = array(
'#type' => 'select',
'#options' => $date_options,
'#title' => t('Date field'),
'#default_value' => '',
'#description' => t('The field which will contain the source dates in target content type.'),
);
$form['description_field'] = array(
'#type' => 'select',
'#options' => $description_options,
'#title' => t('Description field'),
'#default_value' => '',
'#description' => t('The text or body field which will contain the source description in the target content type.'),
);
if ($extended) {
$form['url_field'] = array(
'#type' => 'select',
'#options' => $url_options,
'#title' => t('Url field'),
'#default_value' => '',
'#description' => t('The text or link field which will contain the source url in the target content type.'),
);
$form['location_field'] = array(
'#type' => 'select',
'#options' => $location_options,
'#title' => t('Location field'),
'#default_value' => '',
'#description' => t('The text field which will contain the source location text in the target content type.'),
);
$form['uid_field'] = array(
'#type' => 'select',
'#options' => $uid_options,
'#title' => t('Uid field'),
'#default_value' => '',
'#description' => t('The text field which will contain the source uid in the target content type.'),
);
}
return $form;
}
function date_copy_type_misc_form($type) {
$form = array();
$vocabs = taxonomy_get_vocabularies($type);
if ($vocabs && count($vocabs) > 0) {
$taxonomy = isset($taxonomy) ? $taxonomy : array();
$node = (object) array(
'type' => $type,
'taxonomy' => date_import_taxonomy_form2node($taxonomy),
);
$subform = array(
'type' => array(
'#value' => $type,
),
'#node' => $node,
);
taxonomy_form_alter($subform, array(), $type . '_node_form');
$form['taxonomy'] = array(
'#type' => 'fieldset',
'#title' => t('Categories'),
'#description' => t('Select the categories that should be used for the imported nodes.'),
);
$form['taxonomy'] += $subform['taxonomy'];
}
if (module_exists('og')) {
og_form_add_og_audience($form_id, $form);
}
$form['name'] = array(
'#type' => 'textfield',
'#title' => t('Authored by'),
'#maxlength' => 60,
'#autocomplete_path' => 'user/autocomplete',
'#default_value' => $node->name ? $node->name : '',
'#description' => t('Leave blank for %anonymous.', array(
'%anonymous' => variable_get('anonymous', t('Anonymous')),
)),
);
$form['status'] = array(
'#type' => 'checkbox',
'#title' => t('Published'),
'#default_value' => $node->status,
);
$form['promote'] = array(
'#type' => 'checkbox',
'#title' => t('Promoted to front page'),
'#default_value' => $node->promote,
);
$form['sticky'] = array(
'#type' => 'checkbox',
'#title' => t('Sticky at top of lists'),
'#default_value' => $node->sticky,
);
$form['revision'] = array(
'#type' => 'checkbox',
'#title' => t('Create new revision'),
'#default_value' => $node->revision,
);
return $form;
}
function date_import_taxonomy_form2node($taxonomy) {
$tids = array();
foreach ($taxonomy as $key => $value) {
if ($key != 'tags') {
$value = is_array($value) ? $value : array(
$value,
);
foreach ($value as $tid) {
$tids[$tid] = taxonomy_get_term($tid);
}
}
else {
$tids[$key] = $value;
}
}
return $tids;
}
function date_copy_import_form() {
drupal_set_message(t('Import dates into CCK from various sources.'));
}
function date_copy_export_form() {
drupal_set_message(t('This feature is not yet functional.'));
}
function date_copy_import_csv_form() {
drupal_set_message(t('Importing dates into CCK from a comma separated file can be done using the !link.', array(
'!link' => l('Node Import module', 'http://drupal.org/project/node_import'),
)));
}
function date_copy_import_ical_form($form_values = NULL) {
if (!empty($form_values)) {
foreach ($form_values as $key => $value) {
$form[$key] = array(
'#type' => 'hidden',
'#default_value' => $value,
);
}
}
$step = intval($form_values['step'] + 1);
$form['step'] = array(
'#type' => 'hidden',
'#value' => $step,
);
$form['#multistep'] = TRUE;
$form['#redirect'] = FALSE;
switch ($step) {
case 1:
$form['#prefix'] = t('<p>Create a new CCK content type to import your events into. Make sure it has a date field that can allows a To date so it can accept the From date and To date of the iCal feed. If you are importing dates that have their own timezones, make sure you set the timezone handling of the date to \'date\'. Test the new type by trying to create a node manually and make sure all the right options are available in the form before attempting an import.</p><p><strong>The import will create new nodes and trigger all related hooks, so you may want to turn off automatic email messaging for this node type while performing the import!</strong></p>');
$form['source_file'] = array(
'#type' => 'textfield',
'#title' => t('Source file'),
'#default_value' => '',
);
$form += date_copy_type_form(TRUE);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
case 2:
$node_types = node_get_types('names');
$type = $form_values['target_type'];
$form['target_type'] = array(
'#value' => $type,
'#type' => 'hidden',
);
$form['source_file'] = array(
'#value' => $form_values['source_file'],
'#type' => 'hidden',
);
$form['fields'] = array(
'#type' => 'fieldset',
'#title' => t('!type Fields', array(
'!type' => $node_types[$type],
)),
'#weight' => -1,
);
$form['fields'] += date_copy_type_fields_form($type, TRUE);
$form += date_copy_type_misc_form($type);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
return $form;
}
function date_copy_import_ical_form_submit($form_id, $form_values) {
extract($form_values);
if ($step < 2) {
return;
}
include_once drupal_get_path('module', 'date_api') . '/date_api_ical.inc';
$imported_values = date_ical_import($source_file);
if (empty($imported_values)) {
drupal_set_message(t('This is an invalid file.'));
return;
}
$messages = drupal_get_messages();
$node_types = node_get_types('names');
$field = content_fields($date_field, $target_type);
$account = user_load(array(
'name' => $name,
));
$rows = array();
switch ($field['type']) {
case DATE_UNIX:
$format = 'U';
break;
case DATE_ISO:
$format = DATE_FORMAT_ISO;
break;
}
foreach ($imported_values as $calendars => $calendar) {
foreach ($calendar['VEVENT'] as $key => $value) {
if (empty($value['DTEND'])) {
$value['DTEND'] = $value['DTSTART'];
}
$start_date = date_ical_date($value['DTSTART']);
$end_date = date_ical_date($value['DTEND']);
$timezone = timezone_name_get(date_timezone_get($start_date));
$offset = date_offset_get($start_date);
$offset2 = date_offset_get($end_date);
date_timezone_set($start_date, 'UTC');
date_timezone_set($end_date, 'UTC');
$start = date_limit_value(date_format($start_date, $format), date_granularity($field), $field['type']);
$end = date_limit_value(date_format($end_date, $format), date_granularity($field), $field['type']);
$target_node = new stdClass();
$target_node->nid = 0;
$target_node->type = $target_type;
$target_node->name = $name;
$target_node->uid = $account->uid;
$target_node->status = $status;
$target_node->promote = $promote;
$target_node->sticky = $sticky;
$target_node->revision = $revision;
if (module_exists('og')) {
$target_node->og_public = $og_public;
$target_node->og_groups = $og_groups;
}
$target_node->title = stripslashes($value['SUMMARY']);
$target_node->{$date_field} = array(
0 => array(
'value' => $start,
'value2' => $end,
'timezone' => $timezone,
'offset' => $offset,
'offset2' => $offset2,
),
);
if ($description_field == 'body') {
$target_node->body = stripslashes($value['DESCRIPTION']);
}
elseif (!empty($description_field)) {
$target_node->{$description_field} = array(
0 => array(
'value' => stripslashes($value['DESCRIPTION']),
),
);
}
if (!empty($uid_field)) {
$target_node->{$uid_field} = array(
0 => array(
'value' => stripslashes($value['UID']),
),
);
}
if (!empty($location_field)) {
$target_node->{$location_field} = array(
0 => array(
'value' => stripslashes($value['LOCATION']),
),
);
}
if (!empty($url_field)) {
$target_node->{$url_field} = array(
0 => array(
'url' => stripslashes($value['URL']),
'title' => stripslashes($value['SUMMARY']),
),
);
}
$target_node->taxonomy = $taxonomy;
node_save($target_node);
watchdog('date_copy', t('!type: created %title.', array(
'!type' => t($target_type),
'%title' => $target_node->title,
)), WATCHDOG_NOTICE, l(t('view'), 'node/' . $target_node->nid));
$new_field = $target_node->{$date_field};
$rows[] = array(
l($target_node->title, 'node/' . $target_node->nid),
$target_node->nid,
$new_field[0]['value'],
$new_field[0]['value2'],
);
}
}
$_SESSION['messages'] = $messages;
if (!empty($rows)) {
drupal_set_message(t('%limit ical events have been added.', array(
'%limit' => sizeof($rows),
)));
drupal_set_message(theme('table', array(
t('Title'),
t('Id'),
t('Start'),
t('End'),
), $rows));
}
else {
drupal_set_message(t('No ical events have been added.'));
}
return;
}
function date_copy_import_event_form($form_values = NULL) {
if (!db_table_exists('event')) {
drupal_set_message(t('There is no event table in this database. No event import options are available.'));
return array();
}
$step = intval($form_values['step'] + 1);
$form['step'] = array(
'#type' => 'hidden',
'#value' => $step,
);
$form['#multistep'] = TRUE;
$form['#redirect'] = FALSE;
switch ($step) {
case 1:
$node_types = node_get_types('names');
$form['#prefix'] = t('<p>Create a new CCK content type to import your events into, or, if you do not want to create new nodes for your events, add a date field to the existing event type. Make sure the target content type has a date field that has an optional or required To date so it can accept the From date and To date of the event. If your source event has its own timezone field, make sure you set the target date timezone handling to \'date\'. Test the target type by trying to create a node manually and make sure all the right options are available in the form before attempting an import. </p><p><strong>The import will create new nodes and trigger all related hooks, so you may want to turn off automatic email messaging for this node type while performing the import!</strong></p>');
$source_type_options = array();
$result = db_query("SELECT DISTINCT n.type FROM {event} e INNER JOIN {node} n ON e.nid=n.nid");
while ($arr = db_fetch_array($result)) {
$source_type_options[$arr['type']] = $node_types[$arr['type']];
}
if (sizeof($source_type_options) < 1) {
drupal_set_message(t('There are no event nodes in this database. No event import options are available.'));
return array();
}
$form['source_type'] = array(
'#type' => 'select',
'#options' => $source_type_options,
'#title' => t('Source type'),
'#default_value' => '',
);
$form += date_copy_type_form(TRUE);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
case 2:
$type = $form_values['target_type'];
$form['target_type'] = array(
'#value' => $type,
'#type' => 'hidden',
);
$form['source_type'] = array(
'#value' => $form_values['source_type'],
'#type' => 'hidden',
);
$form['fields'] = array(
'#type' => 'fieldset',
'#title' => t('!type Fields', array(
'!type' => $node_types[$type],
)),
'#weight' => -1,
);
$form['fields'] += date_copy_type_fields_form($type);
$form['delete_old'] = array(
'#type' => 'select',
'#options' => array(
1 => t('Yes'),
0 => t('No'),
),
'#title' => t('Delete original event?'),
'#description' => t('Should the original entry be deleted once it has been copied to the new content type? If so, be sure to back up your database first.'),
);
$form['max'] = array(
'#type' => 'textfield',
'#title' => t('Limit'),
'#description' => t('The maximum number of nodes to convert in this pass.'),
'#required' => TRUE,
);
$form['start_nid'] = array(
'#type' => 'textfield',
'#title' => t('Starting nid'),
'#default_value' => 0,
'#description' => t('Convert nodes with nids greater than or equal to this number.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Submit'),
);
return $form;
}
}
function date_copy_import_event_form_submit($form_id, $form_values) {
extract($form_values);
if ($step != 2) {
return;
}
include_once drupal_get_path('module', 'date_php4') . '/date_php4_tz_map.inc';
$timezones = array(
'' => '',
);
$map = $timezone_map;
foreach ($map as $zone => $values) {
if (!empty($values['zid'])) {
$timezones[$values['zid']] = $zone;
}
}
$rows = array();
$i = 0;
$limit = min(10, intval($max));
while ($i < intval($max)) {
$new_rows = date_copy_convert_events($source_type, $target_type, $date_field, $description_field, $limit, $i, $delete_old, $start_nid, $timezones);
$rows = array_merge($rows, $new_rows);
$i += $limit;
}
if (!empty($rows)) {
drupal_set_message(t('%limit events have been converted.', array(
'%limit' => sizeof($rows),
)));
drupal_set_message(theme('table', array(
t('Title'),
t('Source Id'),
t('Target Id'),
t('Start'),
t('End'),
), $rows));
}
else {
drupal_set_message(t('No events have been converted.'));
}
return;
}
function date_copy_convert_events($source_type, $target_type, $date_field, $description_field, $limit, $start = 0, $delete_old, $start_nid, $timezones) {
$field = content_fields($date_field);
$tz_handling = $field['tz_handling'];
$event_tz_handling = variable_get('event_timezone_display', 'event');
$event_version = 1;
if (db_column_exists('event', 'has_time')) {
$event_version = 2;
}
$rows = array();
if ($start_nid) {
$where = " AND n.nid >= {$start_nid} ";
}
if (!($result = db_query_range("SELECT * FROM {event} e INNER JOIN {node} n ON e.nid=n.nid WHERE n.type = '%s' {$where} ORDER BY n.nid", array(
$source_type,
$start_nid,
), $start, $limit))) {
return array();
}
while ($event = db_fetch_object($result)) {
$source_nid = $event->nid;
$event_node = node_load($source_nid, NULL, TRUE);
if ($target_type != $source_type) {
$target_node = new stdClass();
$target_node->nid = 0;
$target_node->type = $target_type;
foreach ($event_node as $key => $val) {
if ($key != 'nid' && $key != 'type') {
$target_node->{$key} = $val;
}
}
}
else {
$target_node = $event_node;
}
if ($description_field != 'body') {
$target_node->{$description_field} = array(
0 => array(
'value' => $event_node->body,
),
);
unset($target_node->body);
}
$timezone = !empty($event->timezone) && $tz_handling == 'date' && $event_tz_handling == 'event' ? $timezones[$event->timezone] : date_default_timezone_name();
if ($event_version == 1) {
$date = array(
0 => array(),
);
$data[0]['timezone'] = $timezone;
$start = date_make_date($event->event_start, 'UTC', DATE_UNIX);
date_timezone_set($start, timezone_open($timezone));
$data[0]['offset'] = date_offset_get($start);
$end = date_make_date($event->event_end, 'UTC', DATE_UNIX);
date_timezone_set($end, timezone_open($timezone));
$data[0]['offset2'] = date_offset_get($end);
if ($event_node->start_offset != date_offset_get($start) || $event_node->end_offset != date_offset_get($end)) {
$adj = $event_node->start_offset - date_offset_get($start);
date_timezone_set($start, timezone_open('UTC'));
date_modify($start, $adj . ' seconds');
$adj = $event_node->end_offset - date_offset_get($end);
date_timezone_set($end, timezone_open('UTC'));
date_modify($end, $adj . ' seconds');
}
$data[0]['value'] = date_format($start, date_type_format($field['type']));
$data[0]['value2'] = date_format($end, date_type_format($field['type']));
}
else {
$date = array(
0 => array(),
);
$data[0]['timezone'] = $timezone;
$start = date_make_date($event->event_start, $timezone, DATE_DATETIME);
$data[0]['offset'] = date_offset_get($start);
$end = date_make_date($event->event_end, $timezone, DATE_DATETIME);
$data[0]['offset2'] = date_offset_get($end);
date_timezone_set($start, timezone_open('UTC'));
date_timezone_set($end, timezone_open('UTC'));
$data[0]['value'] = date_format($start, date_type_format($field['type']));
$data[0]['value2'] = date_format($end, date_type_format($field['type']));
}
$target_node->{$date_field} = $data;
$event_fields = array(
'event_start',
'event_end',
'timezone',
'start_offset',
'start_format',
'start_time_format',
'end_offset',
'end_format',
'end_time_format',
'event_node_title',
);
foreach ($event_fields as $e) {
unset($target_node->{$e});
}
node_save($target_node);
if ($target_type != $source_type) {
watchdog('date_copy', t('!type: created %title.', array(
'!type' => t($target_type),
'%title' => $target_node->title,
)), WATCHDOG_NOTICE, l(t('view'), 'node/' . $target_node->nid));
if ($delete_old) {
node_delete($source_nid);
}
}
else {
watchdog('date_copy', t('!type: updated %title.', array(
'!type' => t($target_type),
'%title' => $target_node->title,
)), WATCHDOG_NOTICE, l(t('view'), 'node/' . $target_node->nid));
}
$new_field = $target_node->{$date_field};
$rows[] = array(
l($target_node->title, 'node/' . $target_node->nid),
$source_nid,
$target_node->nid,
$new_field[0]['value'],
$new_field[0]['value2'],
);
}
return $rows;
}