node_export_relation.node_reference.inc 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <?php
  2. /**
  3. * @file
  4. * The Node export relation node reference include.
  5. *
  6. * Helps maintain node reference relationships between nodes during node export operations.
  7. */
  8. /**
  9. * Implements hook_form_FORM_ID_alter().
  10. */
  11. function node_export_relation_settings_form_node_reference(&$form, &$form_state, $form_id) {
  12. $form['node_reference'] = array(
  13. '#type' => 'fieldset',
  14. '#title' => t('Node references'),
  15. );
  16. // Not supported yet.
  17. $form['node_reference']['node_export_node_reference_auto_inc'] = array(
  18. '#type' => 'checkbox',
  19. '#title' => t('Automatically include referenced nodes in exports'),
  20. '#default' => variable_get('node_export_node_reference_auto_inc', TRUE),
  21. );
  22. $form['node_reference']['node_export_node_reference_skip'] = array(
  23. '#type' => 'checkbox',
  24. '#title' => t('Skip referenced nodes that cannot be exported'),
  25. '#default' => variable_get('node_export_node_reference_skip', TRUE),
  26. '#description' => t('If this is disabled, node exports will fail if a referenced node cannot be exported, for example if the user performing the export does not have access.'),
  27. );
  28. }
  29. /**
  30. * Update node references after import.
  31. */
  32. function node_export_relation_node_reference_update($nodes) {
  33. foreach ($nodes as $node) {
  34. $uuid[$node->uuid] = $node->nid;
  35. }
  36. foreach ($nodes as $node) {
  37. $node_reference_fields = node_export_relation_node_reference_fields($node->type);
  38. if (!empty($node_reference_fields)) {
  39. foreach ($node_reference_fields as $node_reference_field) {
  40. $items = field_get_items('node', $node, $node_reference_field);
  41. $langcode = field_language('node', $node, $node_reference_field);
  42. if (!empty($items)) {
  43. foreach ($items as $key => &$node_reference) {
  44. if (!empty($node_reference['nid'])) {
  45. $node_uuid = node_export_relation_node_reference_map($node_reference['nid']);
  46. $node->{$node_reference_field}[$langcode][$key] = array('nid' => $uuid[$node_uuid]);
  47. }
  48. }
  49. }
  50. }
  51. }
  52. node_save($node);
  53. }
  54. }
  55. /**
  56. * Recursively load node references.
  57. */
  58. function node_export_relation_node_reference_load(&$nodes, $nid, $reset = FALSE) {
  59. // Alias for easy referencing.
  60. $node = &$nodes[$nid];
  61. // Get list of node reference fields for this node
  62. $node_reference_fields = node_export_relation_node_reference_fields($node->type);
  63. if (!empty($node_reference_fields)) {
  64. foreach ($node_reference_fields as $node_reference_field) {
  65. $items = field_get_items('node', $node, $node_reference_field);
  66. if (!empty($items)) {
  67. foreach ($items as &$node_reference) {
  68. if (!empty($node_reference['nid'])) {
  69. // Load the referenced nodes only if its not already loaded
  70. // This will save if from infinite loop of back references
  71. if (!isset($nodes[$node_reference['nid']])) {
  72. $new_node = node_load($node_reference['nid'], NULL, $reset);
  73. if (node_export_access_export($new_node, $reset)) {
  74. $new_node = node_export_prepare_node($new_node);
  75. $nodes[$new_node->nid] = $new_node;
  76. // Recursively load references of new nodes
  77. node_export_relation_node_reference_load($nodes, $new_node->nid, $reset);
  78. }
  79. elseif (!variable_get('node_export_node_reference_skip', TRUE)) {
  80. // Set this node to FALSE to trigger an error in node export.
  81. // Do not use $new_node in this code in case there is a problem with it.
  82. $nodes[$node_reference['nid']] = FALSE;
  83. // Add a warning to watchdog.
  84. watchdog('node_export_relation', 'No access to export node reference %nid', array('%nid' => $node_reference['nid']), WATCHDOG_WARNING);
  85. }
  86. }
  87. }
  88. }
  89. }
  90. }
  91. }
  92. }
  93. /**
  94. * Statically cache old node ids for mapping.
  95. */
  96. function node_export_relation_node_reference_map($id, $uuid = NULL, $type = 'node') {
  97. static $map;
  98. if (isset($uuid)) {
  99. $map[$type][$id] = $uuid;
  100. }
  101. else {
  102. return $map[$type][$id];
  103. }
  104. }
  105. /**
  106. * Get an array listing the names of all node reference fields.
  107. *
  108. * @return
  109. * Array of all created node reference fields.
  110. */
  111. function node_export_relation_node_reference_fields($content_type_name) {
  112. // cache result
  113. static $node_reference_fields = array();
  114. if (empty($node_reference_fields[$content_type_name])) {
  115. $fields = field_info_instances('node', $content_type_name);
  116. if (!empty($fields)) {
  117. foreach ($fields as $field) {
  118. if (isset($field['widget']['module']) && $field['widget']['module'] == 'node_reference' && !empty($field['field_name'])) {
  119. $node_reference_fields[$content_type_name][$field['field_name']] = $field['field_name'];
  120. }
  121. }
  122. }
  123. }
  124. if (array_key_exists($content_type_name, $node_reference_fields)) {
  125. return $node_reference_fields[$content_type_name];
  126. }
  127. else {
  128. return NULL;
  129. }
  130. }