date_copy.module

Tracking 5.x-2.x branch
  1. drupal
    1. 5 contributions/date/date_copy/date_copy.module

Functions & methods

NameDescription
date_copy_convert_events
date_copy_export_form
date_copy_helpDate Copy
date_copy_import_csv_form
date_copy_import_event_formEvent import form.
date_copy_import_event_form_submitEvent import processing.
date_copy_import_formAdministration page
date_copy_import_ical_formiCal import form.
date_copy_import_ical_form_submit
date_copy_menuImplementation of hook_menu()
date_copy_type_fields_formA form to select fields from a content type.
date_copy_type_formA form to select a content type.
date_copy_type_misc_formA form to select miscellaneous other options for a content type.
date_import_taxonomy_form2nodeConvert the taxonomy array from the form form to the node form. Borrowed from the Node Import module.

File

View source
  1. <?php
  2. /**
  3. * Date Copy
  4. *
  5. * A module to import and export date data in various ways.
  6. * Currently only imports date data from events and ical.
  7. *
  8. * Importing data from csv files can currently be done using the Node Import module, no need to add that here.
  9. *
  10. * @todo
  11. * Add export capabilities, possibly add support for csv import.
  12. */
  13. function date_copy_help($section) {
  14. switch ($section) {
  15. case 'admin/modules#description':
  16. return t('Copy data in and out of Date module.');
  17. break;
  18. }
  19. }
  20. /**
  21. * Implementation of hook_menu()
  22. */
  23. function date_copy_menu($may_cache) {
  24. $items = array();
  25. if (!$may_cache) {
  26. $items[] = array(
  27. 'path' => 'admin/content/date',
  28. 'title' => t('Date Import/Export'),
  29. 'description' => t('Import and export date data.'),
  30. 'access' => user_access('administer nodes'),
  31. 'callback' => 'drupal_get_form',
  32. 'callback arguments' => 'date_copy_import_ical_form',
  33. 'type' => MENU_NORMAL_ITEM,
  34. );
  35. $items[] = array(
  36. 'path' => 'admin/content/date/import',
  37. 'title' => t('Import'),
  38. 'access' => user_access('administer nodes'),
  39. 'callback' => 'drupal_get_form',
  40. 'callback arguments' => 'date_copy_import_ical_form',
  41. 'type' => MENU_DEFAULT_LOCAL_TASK,
  42. 'weight' => 1,
  43. );
  44. $items[] = array(
  45. 'path' => 'admin/content/date/export',
  46. 'title' => t('Export'),
  47. 'access' => user_access('administer nodes'),
  48. 'callback' => 'drupal_get_form',
  49. 'callback arguments' => 'date_copy_export_form',
  50. 'type' => MENU_LOCAL_TASK,
  51. 'weight' => 2,
  52. );
  53. $items[] = array(
  54. 'path' => 'admin/content/date/import/ical',
  55. 'title' => t('iCal'),
  56. 'access' => user_access('administer nodes'),
  57. 'callback' => 'drupal_get_form',
  58. 'callback arguments' => 'date_copy_import_ical_form',
  59. 'type' => MENU_DEFAULT_LOCAL_TASK,
  60. 'weight' => 1,
  61. );
  62. $items[] = array(
  63. 'path' => 'admin/content/date/import/event',
  64. 'title' => t('Events'),
  65. 'access' => user_access('administer nodes'),
  66. 'callback' => 'drupal_get_form',
  67. 'callback arguments' => 'date_copy_import_event_form',
  68. 'type' => MENU_LOCAL_TASK,
  69. 'weight' => 2,
  70. );
  71. $items[] = array(
  72. 'path' => 'admin/content/date/import/csv',
  73. 'title' => t('CSV'),
  74. 'access' => user_access('administer nodes'),
  75. 'callback' => 'drupal_get_form',
  76. 'callback arguments' => 'date_copy_import_csv_form',
  77. 'type' => MENU_LOCAL_TASK,
  78. 'weight' => 3,
  79. );
  80. return $items;
  81. }
  82. }
  83. /**
  84. * A form to select a content type.
  85. */
  86. function date_copy_type_form($target = TRUE) {
  87. $form = array();
  88. $node_types = node_get_types('names');
  89. $fields = content_fields();
  90. $type_options = array();
  91. // Find out what content types contain date fields and set them up as target options.
  92. foreach ($fields as $field_name => $field) {
  93. if ($field['type'] == 'date' || $field['type'] == 'datestamp') {
  94. $type_options[$field['type_name']] = $node_types[$field['type_name']];
  95. }
  96. }
  97. if (sizeof($type_options) < 1) {
  98. 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.'));
  99. return $form;
  100. }
  101. $type = $target ? 'target_type' : 'source_type';
  102. $label = $target ? t('Target type') : t('Source type');
  103. $form[$type] = array(
  104. '#type' => 'select',
  105. '#options' => $type_options,
  106. '#title' => $label,
  107. '#description' => t('Only content types with date fields appear in this list as possible target types.'),
  108. '#default_value' => '',
  109. );
  110. // If Content Copy is enabled, offer an import link.
  111. if (module_exists('content_copy')) {
  112. $form['macro'] = array(
  113. '#type' => 'fieldset',
  114. '#title' => t('Add'),
  115. '#description' => t('If your desired target type does not already have a date field, follow this link and select a content type to add a date field to that type.'),
  116. '#collapsible' => TRUE,
  117. '#collapsed' => FALSE,
  118. );
  119. $form['macro']['link'] = array(
  120. '#type' => 'markup',
  121. '#value' => l(t('Add new date field'), 'admin/content/types/import', array(), 'macro_file='. drupal_get_path('module', 'date_copy') .'/date_field.php'),
  122. );
  123. }
  124. return $form;
  125. }
  126. /**
  127. * A form to select fields from a content type.
  128. */
  129. function date_copy_type_fields_form($type, $extended = FALSE) {
  130. $form = array();
  131. $fields = content_fields();
  132. $date_options = array();
  133. $description_options = array('' => '');
  134. $uid_options = array('' => '');
  135. $url_options = array('' => '');
  136. $location_options = array('' => '');
  137. // Find out what content types contain date fields and set them up as target options.
  138. foreach ($fields as $field_name => $field) {
  139. if ($field['type_name'] == $type) {
  140. if ($field['type'] == 'date' || $field['type'] == 'datestamp') {
  141. $date_options[$field_name] = $field['widget']['label'];
  142. }
  143. if ($field['type'] == 'text') {
  144. $description_options[$field_name] = $field['widget']['label'];
  145. $location_options[$field_name] = $field['widget']['label'];
  146. $uid_options[$field_name] = $field['widget']['label'];
  147. $url_options[$field_name] = $field['widget']['label'];
  148. }
  149. if ($field['type'] == 'link') {
  150. $url_options[$field_name] = $field['widget']['label'];
  151. }
  152. }
  153. }
  154. // The body field is also available as an option for the description.
  155. $description_options['body'] = t('body');
  156. if (sizeof($date_options) < 1) {
  157. 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.'));
  158. return $form;
  159. }
  160. $form['date_field'] = array(
  161. '#type' => 'select',
  162. '#options' => $date_options,
  163. '#title' => t('Date field'),
  164. '#default_value' => '',
  165. '#description' => t('The field which will contain the source dates in target content type.'),
  166. );
  167. $form['description_field'] = array(
  168. '#type' => 'select',
  169. '#options' => $description_options,
  170. '#title' => t('Description field'),
  171. '#default_value' => '',
  172. '#description' => t('The text or body field which will contain the source description in the target content type.'),
  173. );
  174. if ($extended) {
  175. $form['url_field'] = array(
  176. '#type' => 'select',
  177. '#options' => $url_options,
  178. '#title' => t('Url field'),
  179. '#default_value' => '',
  180. '#description' => t('The text or link field which will contain the source url in the target content type.'),
  181. );
  182. $form['location_field'] = array(
  183. '#type' => 'select',
  184. '#options' => $location_options,
  185. '#title' => t('Location field'),
  186. '#default_value' => '',
  187. '#description' => t('The text field which will contain the source location text in the target content type.'),
  188. );
  189. $form['uid_field'] = array(
  190. '#type' => 'select',
  191. '#options' => $uid_options,
  192. '#title' => t('Uid field'),
  193. '#default_value' => '',
  194. '#description' => t('The text field which will contain the source uid in the target content type.'),
  195. );
  196. }
  197. return $form;
  198. }
  199. /**
  200. * A form to select miscellaneous other options for a content type.
  201. */
  202. function date_copy_type_misc_form($type) {
  203. $form = array();
  204. $vocabs = taxonomy_get_vocabularies($type);
  205. if ($vocabs && count($vocabs) > 0) {
  206. $taxonomy = isset($taxonomy) ? $taxonomy : array();
  207. $node = (object)array(
  208. 'type' => $type,
  209. 'taxonomy' => date_import_taxonomy_form2node($taxonomy),
  210. );
  211. $subform = array(
  212. 'type' => array(
  213. '#value' => $type,
  214. ),
  215. '#node' => $node,
  216. );
  217. taxonomy_form_alter($type .'_node_form', $subform);
  218. $form['taxonomy'] = array(
  219. '#type' => 'fieldset',
  220. '#title' => t('Categories'),
  221. '#description' => t('Select the categories that should be used for the imported nodes.'),
  222. );
  223. $form['taxonomy'] += $subform['taxonomy'];
  224. }
  225. if (module_exists('og')) {
  226. og_form_add_og_audience($form_id, $form);
  227. }
  228. $form['name'] = array(
  229. '#type' => 'textfield', '#title' => t('Authored by'),
  230. '#maxlength' => 60, '#autocomplete_path' => 'user/autocomplete',
  231. '#default_value' => $node->name ? $node->name : '',
  232. '#description' => t('Leave blank for %anonymous.', array(
  233. '%anonymous' => variable_get('anonymous', t('Anonymous')))));
  234. $form['status'] = array(
  235. '#type' => 'checkbox', '#title' => t('Published'),
  236. '#default_value' => $node->status);
  237. $form['promote'] = array(
  238. '#type' => 'checkbox', '#title' => t('Promoted to front page'),
  239. '#default_value' => $node->promote);
  240. $form['sticky'] = array(
  241. '#type' => 'checkbox', '#title' => t('Sticky at top of lists'),
  242. '#default_value' => $node->sticky);
  243. $form['revision'] = array(
  244. '#type' => 'checkbox', '#title' => t('Create new revision'),
  245. '#default_value' => $node->revision);
  246. return $form;
  247. }
  248. /**
  249. * Convert the taxonomy array from the form form to the node form.
  250. * Borrowed from the Node Import module.
  251. */
  252. function date_import_taxonomy_form2node($taxonomy) {
  253. $tids = array();
  254. foreach ($taxonomy as $key => $value) {
  255. if ($key != 'tags') {
  256. $value = is_array($value) ? $value : array($value);
  257. foreach ($value as $tid) {
  258. $tids[$tid] = taxonomy_get_term($tid);
  259. }
  260. }
  261. else {
  262. $tids[$key] = $value;
  263. }
  264. }
  265. return $tids;
  266. }
  267. /**
  268. * Administration page
  269. */
  270. function date_copy_import_form() {
  271. // PLACEHOLDER
  272. drupal_set_message(t('Import dates into CCK from various sources.'));
  273. }
  274. function date_copy_export_form() {
  275. // PLACEHOLDER
  276. drupal_set_message(t('This feature is not yet functional.'));
  277. }
  278. function date_copy_import_csv_form() {
  279. // PLACEHOLDER
  280. drupal_set_message(t('Importing dates into CCK from a comma separated file can be done using the <a href="@link">Node Import module</a>.', array('@link' => url('http://drupal.org/project/node_import'))));
  281. }
  282. /**
  283. * iCal import form.
  284. */
  285. function date_copy_import_ical_form($form_values = NULL) {
  286. if (!empty($form_values)) {
  287. foreach ($form_values as $key => $value) {
  288. $form[$key] = array('#type' => 'hidden', '#default_value' => $value);
  289. }
  290. }
  291. $step = intval($form_values['step'] + 1);
  292. $form['step'] = array(
  293. '#type' => 'hidden',
  294. '#value' => $step,
  295. );
  296. $form['#multistep'] = TRUE;
  297. $form['#redirect'] = FALSE;
  298. switch ($step) {
  299. case 1: // Select a content type to import into.
  300. $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>');
  301. $form['source_file'] = array(
  302. '#type' => 'textfield',
  303. '#title' => t('Source file'),
  304. '#default_value' => '',
  305. );
  306. $form += date_copy_type_form(TRUE);
  307. $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
  308. return $form;
  309. case 2: // Select the fields to import into.
  310. $node_types = node_get_types('names');
  311. $type = $form_values['target_type'];
  312. $form['target_type'] = array(
  313. '#value' => $type,
  314. '#type' => 'hidden',
  315. );
  316. $form['source_file'] = array(
  317. '#value' => $form_values['source_file'],
  318. '#type' => 'hidden',
  319. );
  320. $form['fields'] = array(
  321. '#type' => 'fieldset',
  322. '#title' => t('!type Fields', array('!type' => $node_types[$type])),
  323. '#weight' => -1,
  324. );
  325. $form['fields'] += date_copy_type_fields_form($type, TRUE);
  326. $form += date_copy_type_misc_form($type);
  327. $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
  328. return $form;
  329. }
  330. return $form;
  331. }
  332. function date_copy_import_ical_form_submit($form_id, $form_values) {
  333. extract($form_values);
  334. if ($step < 2) {
  335. return;
  336. }
  337. require_once('./'. drupal_get_path('module', 'date_api') .'/date_api_ical.inc');
  338. $imported_values = date_ical_import($source_file);
  339. if (empty($imported_values)) {
  340. drupal_set_message(t('This is an invalid file.'));
  341. return;
  342. }
  343. // workaround to disable drupal messages when nodes are created or deleted
  344. $messages = drupal_get_messages();
  345. $node_types = node_get_types('names');
  346. $field = content_fields($date_field, $target_type);
  347. $account = user_load(array('name' => $name));
  348. $rows = array();
  349. switch ($field['type']) {
  350. case DATE_UNIX:
  351. $format = 'U';
  352. break;
  353. case DATE_ISO:
  354. $format = DATE_FORMAT_ISO;
  355. break;
  356. }
  357. foreach ($imported_values as $calendars => $calendar) {
  358. foreach ($calendar['VEVENT'] as $key => $value) {
  359. if (empty($value['DTEND'])) {
  360. $value['DTEND'] = $value['DTSTART'];
  361. }
  362. $start_date = date_ical_date($value['DTSTART']);
  363. $end_date = date_ical_date($value['DTEND']);
  364. $timezone = timezone_name_get(date_timezone_get($start_date));
  365. $offset = date_offset_get($start_date);
  366. $offset2 = date_offset_get($end_date);
  367. date_timezone_set($start_date, date_get_timezone_db($field['tz_handling']));
  368. date_timezone_set($end_date, date_get_timezone_db($field['tz_handling']));
  369. $start = date_limit_value(date_format($start_date, $format), date_granularity($field), $field['type']);
  370. $end = date_limit_value(date_format($end_date, $format), date_granularity($field), $field['type']);
  371. $target_node = new stdClass();
  372. $target_node->nid = 0;
  373. $target_node->type = $target_type;
  374. $target_node->name = $name;
  375. $target_node->uid = $account->uid;
  376. $target_node->status = $status;
  377. $target_node->promote = $promote;
  378. $target_node->sticky = $sticky;
  379. $target_node->revision = $revision;
  380. if (module_exists('og')) {
  381. $target_node->og_public = $og_public;
  382. $target_node->og_groups = $og_groups;
  383. }
  384. $target_node->title = stripslashes($value['SUMMARY']);
  385. $target_node->$date_field = array(0 => array(
  386. 'value' => $start,
  387. 'value2' => $end,
  388. 'timezone' => $timezone,
  389. 'offset' => $offset,
  390. 'offset2' => $offset2,
  391. ));
  392. if ($description_field == 'body') {
  393. $target_node->body = stripslashes($value['DESCRIPTION']);
  394. }
  395. elseif (!empty($description_field)) {
  396. $target_node->$description_field = array(0 => array('value' => stripslashes($value['DESCRIPTION'])));
  397. }
  398. if (!empty($uid_field)) {
  399. $target_node->$uid_field = array(0 => array('value' => stripslashes($value['UID'])));
  400. }
  401. if (!empty($location_field)) {
  402. $target_node->$location_field = array(0 => array('value' => stripslashes($value['LOCATION'])));
  403. }
  404. if (!empty($url_field)) {
  405. $target_node->$url_field = array(0 => array('url' => stripslashes($value['URL']), 'title' => stripslashes($value['SUMMARY'])));
  406. }
  407. $target_node->taxonomy = $taxonomy;
  408. node_save($target_node);
  409. watchdog('date_copy', '!type: created %title.', array(
  410. '!type' => t($target_type),
  411. '%title' => $target_node->title),
  412. WATCHDOG_NOTICE,
  413. l(t('view'), 'node/'. $target_node->nid));
  414. $new_field = $target_node->$date_field;
  415. $rows[] = array(
  416. l($target_node->title,
  417. 'node/'. $target_node->nid),
  418. $target_node->nid,
  419. $new_field[0]['value'],
  420. $new_field[0]['value2'],
  421. );
  422. }
  423. }
  424. // write back the old messages
  425. $_SESSION['messages'] = $messages;
  426. if (!empty($rows)) {
  427. drupal_set_message(t('%limit ical events have been added.', array('%limit' => sizeof($rows))));
  428. drupal_set_message(theme('table', array(t('Title'), t('Id'), t('Start'), t('End')), $rows));
  429. }
  430. else {
  431. drupal_set_message(t('No ical events have been added.'));
  432. }
  433. return;
  434. }
  435. /**
  436. * Event import form.
  437. */
  438. function date_copy_import_event_form($form_values = NULL) {
  439. // We can do an import if there are event fields available whether or not the event module is enabled
  440. // so we just check whether the table exists.
  441. if (!db_table_exists('event')) {
  442. drupal_set_message(t('There is no event table in this database. No event import options are available.'));
  443. return array();
  444. }
  445. $step = intval($form_values['step'] + 1);
  446. $form['step'] = array(
  447. '#type' => 'hidden',
  448. '#value' => $step,
  449. );
  450. $form['#multistep'] = TRUE;
  451. $form['#redirect'] = FALSE;
  452. switch ($step) {
  453. case 1: // Select a content type to import into.
  454. $node_types = node_get_types('names');
  455. $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>');
  456. $source_type_options = array();
  457. $result = db_query("SELECT DISTINCT n.type FROM {event} e INNER JOIN {node} n ON e.nid=n.nid");
  458. while ($arr = db_fetch_array($result)) {
  459. $source_type_options[$arr['type']] = $node_types[$arr['type']];
  460. }
  461. if (sizeof($source_type_options) < 1) {
  462. drupal_set_message(t('There are no event nodes in this database. No event import options are available.'));
  463. return array();
  464. }
  465. $form['source_type'] = array(
  466. '#type' => 'select',
  467. '#options' => $source_type_options,
  468. '#title' => t('Source type'),
  469. '#default_value' => '',
  470. );
  471. $form += date_copy_type_form(TRUE);
  472. $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
  473. return $form;
  474. case 2: // Select the fields to import into.
  475. $type = $form_values['target_type'];
  476. $form['target_type'] = array(
  477. '#value' => $type,
  478. '#type' => 'hidden',
  479. );
  480. $form['source_type'] = array(
  481. '#value' => $form_values['source_type'],
  482. '#type' => 'hidden',
  483. );
  484. $form['fields'] = array(
  485. '#type' => 'fieldset',
  486. '#title' => t('!type Fields', array('!type' => $node_types[$type])),
  487. '#weight' => -1,
  488. );
  489. $form['fields'] += date_copy_type_fields_form($type);
  490. $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.'));
  491. $form['max'] = array('#type' => 'textfield', '#title' => t('Limit'), '#description' => t('The maximum number of nodes to convert in this pass.'), '#required' => TRUE);
  492. $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.'));
  493. $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
  494. return $form;
  495. }
  496. }
  497. /**
  498. * Event import processing.
  499. */
  500. function date_copy_import_event_form_submit($form_id, $form_values) {
  501. extract($form_values);
  502. if ($step != 2) return;
  503. // workaround to disable drupal messages when nodes are created or deleted
  504. //$messages = drupal_get_messages();
  505. // The array that maps event timezone zids to timezone names is in
  506. // date_php4_tz_map.inc, need to reverse it so the zid is the key.
  507. require_once('./'. drupal_get_path('module', 'date_php4') .'/date_php4_tz_map.inc');
  508. $timezones = array('' => '');
  509. $map = $timezone_map;
  510. foreach ($map as $zone => $values) {
  511. if (!empty($values['zid'])) {
  512. $timezones[$values['zid']] = $zone;
  513. }
  514. }
  515. $rows = array();
  516. $i = 0;
  517. // Get $max records, 10 at a time.
  518. $limit = min(10, intval($max));
  519. while ($i < intval($max)) {
  520. $new_rows = date_copy_convert_events($source_type, $target_type, $date_field, $description_field, $limit, $i, $delete_old, $start_nid, $timezones);
  521. $rows = array_merge($rows, $new_rows);
  522. $i += $limit;
  523. }
  524. // write back the old messages
  525. //$_SESSION['messages'] = $messages;
  526. if (!empty($rows)) {
  527. drupal_set_message(t('%limit events have been converted.', array('%limit' => sizeof($rows))));
  528. drupal_set_message(theme('table', array(t('Title'), t('Source Id'), t('Target Id'), t('Start'), t('End')), $rows));
  529. }
  530. else {
  531. drupal_set_message(t('No events have been converted.'));
  532. }
  533. return;
  534. }
  535. function date_copy_convert_events( $source_type, $target_type, $date_field, $description_field, $limit, $start = 0, $delete_old, $start_nid, $timezones) {
  536. // Get info about the field we are importing into
  537. $field = content_fields($date_field);
  538. // Get date tz handling, could be date, site, GMT, or none.
  539. $tz_handling = $field['tz_handling'];
  540. // Get event tz handling, could be event, site, or user.
  541. $event_tz_handling = variable_get('event_timezone_display', 'event');
  542. // Check which version of the Event module this database was built in.
  543. $event_version = 1;
  544. require_once('./'. drupal_get_path('module', 'date') .'/date.install');
  545. if (date_column_exists('event', 'has_time')) {
  546. $event_version = 2;
  547. }
  548. $rows = array();
  549. if ($start_nid) {
  550. $where = " AND n.nid >= $start_nid ";
  551. }
  552. 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)) {
  553. return array();
  554. }
  555. while ($event = db_fetch_object($result)) {
  556. $source_nid = $event->nid;
  557. $event_node = node_load($source_nid, NULL, TRUE);
  558. // Creating new nodes or converting existing ones??
  559. if ($target_type != $source_type) {
  560. $target_node = new stdClass();
  561. $target_node->nid = 0;
  562. $target_node->type = $target_type;
  563. foreach ($event_node as $key => $val) {
  564. if ($key != 'nid' && $key != 'type') {
  565. $target_node->$key = $val;
  566. }
  567. }
  568. }
  569. else {
  570. $target_node = $event_node;
  571. }
  572. if ($description_field != 'body') {
  573. $target_node->$description_field = array(0 => array('value' => $event_node->body));
  574. unset($target_node->body);
  575. }
  576. // Set the date timezone value.
  577. $timezone = !empty($event->timezone) && $tz_handling == 'date' && $event_tz_handling == 'event' ? $timezones[$event->timezone] : date_default_timezone_name();
  578. // If this is a deprecated timezone, replace it.
  579. require_once(drupal_get_path('module', 'date_timezone') .'/date_timezone.install');
  580. $timezone = _date_timezone_replacement($timezone);
  581. // Find the original timezone value (might not be the same as the date timezone).
  582. $event_timezone = !empty($event->timezone) ? $timezones[$event->timezone] : date_default_timezone_name();
  583. // If this is a deprecated timezone, replace it.
  584. $event_timezone = _date_timezone_replacement($event_timezone);
  585. if ($event_version == 1) {
  586. // Version 1 stores the UTC value in the database as a timestamp.
  587. $date = array(0 => array());
  588. $data[0]['timezone'] = $timezone;
  589. $start = date_make_date($event->event_start, 'UTC', DATE_UNIX);
  590. date_timezone_set($start, timezone_open($timezone));
  591. $data[0]['offset'] = date_offset_get($start);
  592. $end = date_make_date($event->event_end, 'UTC', DATE_UNIX);
  593. date_timezone_set($end, timezone_open($timezone));
  594. $data[0]['offset2'] = date_offset_get($end);
  595. // If the original event had the wrong offset, the 'UTC' value it
  596. // created will also be wrong, correct it here.
  597. if ($event_node->start_offset != date_offset_get($start) || $event_node->end_offset != date_offset_get($end)) {
  598. $adj = $event_node->start_offset - date_offset_get($start);
  599. date_timezone_set($start, timezone_open('UTC'));
  600. date_modify($start, $adj .' seconds');
  601. $adj = $event_node->end_offset - date_offset_get($end);
  602. date_timezone_set($end, timezone_open('UTC'));
  603. date_modify($end, $adj .' seconds');
  604. }
  605. $data[0]['value'] = date_format($start, date_type_format($field['type']));
  606. $data[0]['value2'] = date_format($end, date_type_format($field['type']));
  607. }
  608. else {
  609. // Version 2 stores the local value in the database as a datetime field.
  610. $date = array(0 => array());
  611. $data[0]['timezone'] = $timezone;
  612. $start = date_make_date($event->event_start, $event_timezone, DATE_DATETIME);
  613. if ($event_timezone != $timezone) {
  614. date_timezone_set($start, timezone_open($timezone));
  615. }
  616. $data[0]['offset'] = date_offset_get($start);
  617. $end = date_make_date($event->event_end, $event_timezone, DATE_DATETIME);
  618. if ($event_timezone != $timezone) {
  619. date_timezone_set($end, timezone_open($timezone));
  620. }
  621. $data[0]['offset2'] = date_offset_get($end);
  622. date_timezone_set($start, timezone_open('UTC'));
  623. date_timezone_set($end, timezone_open('UTC'));
  624. $data[0]['value'] = date_format($start, date_type_format($field['type']));
  625. $data[0]['value2'] = date_format($end, date_type_format($field['type']));
  626. }
  627. $target_node->$date_field = $data;
  628. $event_fields = array(
  629. 'event_start', 'event_end', 'timezone', 'start_offset',
  630. 'start_format', 'start_time_format', 'end_offset',
  631. 'end_format', 'end_time_format', 'event_node_title');
  632. foreach ($event_fields as $e) {
  633. unset($target_node->$e);
  634. }
  635. node_save($target_node);
  636. if ($target_type != $source_type) {
  637. watchdog('date_copy', '!type: created %title.', array(
  638. '!type' => t($target_type),
  639. '%title' => $target_node->title),
  640. WATCHDOG_NOTICE,
  641. l(t('view'), 'node/'. $target_node->nid));
  642. if ($delete_old) {
  643. node_delete($source_nid);
  644. }
  645. }
  646. else {
  647. watchdog('date_copy', '!type: updated %title.', array(
  648. '!type' => t($target_type),
  649. '%title' => $target_node->title),
  650. WATCHDOG_NOTICE,
  651. l(t('view'), 'node/'. $target_node->nid));
  652. }
  653. $new_field = $target_node->$date_field;
  654. $rows[] = array(
  655. l($target_node->title,
  656. 'node/'. $target_node->nid),
  657. $source_nid,
  658. $target_node->nid,
  659. $new_field[0]['value'],
  660. $new_field[0]['value2']);
  661. }
  662. return $rows;
  663. }