node_export_book.module 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /**
  3. * @file
  4. * Adds Book support to the Node export module.
  5. */
  6. /**
  7. * Implements hook_node_export_node_alter().
  8. */
  9. function node_export_book_node_export_node_alter(&$node, $original_node) {
  10. module_load_include('inc', 'node_export_book', 'node_export_book_utils');
  11. // Throw errors if the node doesn't have a UUID
  12. if (module_exists('uuid') and drupal_strlen(_node_export_book_nid_to_uuid($node->nid)) < 1) {
  13. drupal_set_message(t('The node %nid does not have a UUID; unable to export!', array('%nid' => $node->nid)), 'error');
  14. watchdog('node_export_book', 'Unable to export %nid because it is missing a UUID.', array('%nid' => $node->nid), WATCHDOG_CRITICAL);
  15. }
  16. elseif (module_exists('book') and property_exists($original_node, 'book')) {
  17. // Create a namespace for our export info in the book node
  18. if (!property_exists($node, 'node_export_book')) {
  19. $node->node_export_book = array();
  20. }
  21. // Dereference the Parent Link ID (PLID) and write the parent node's UUID
  22. if (array_key_exists('plid', $original_node->book) and menu_link_load($original_node->book['plid'])) {
  23. $node->node_export_book['#parent_uuid'] = _node_export_book_mlid_to_uuid($original_node->book['plid']);
  24. }
  25. // Dereference the Book ID (BID) and write the book node's UUID
  26. if (array_key_exists('bid', $original_node->book) and node_load($original_node->book['bid'])) {
  27. $node->node_export_book['#book_uuid'] = _node_export_book_nid_to_uuid($original_node->book['bid']);
  28. }
  29. // Add the weight of this page in the book heirarchy
  30. if (array_key_exists('weight', $original_node->book)) {
  31. $node->node_export_book['weight'] = intval($original_node->book['weight']);
  32. }
  33. if ($original_node->book['bid'] == $original_node->nid) {
  34. $node->node_export_book['#is_root'] = TRUE;
  35. }
  36. else {
  37. $node->node_export_book['#is_root'] = FALSE;
  38. }
  39. // When we're done, unset the book info in the node, so it isn't exported
  40. // and book.module on the destination site can't get confused
  41. unset($node->book);
  42. }
  43. }
  44. /**
  45. * Implements hook_node_export_after_import_alter().
  46. */
  47. function node_export_book_node_export_after_import_alter(&$nodes, $format, $save) {
  48. module_load_include('inc', 'node_export_book', 'node_export_book_utils');
  49. if (module_exists('book')) {
  50. // A smaller array of child nodes to parse later
  51. $child_nodes = array();
  52. // Loop through all the nodes, process books, and build a smaller array of nodes to parse later
  53. foreach ($nodes as &$node) {
  54. if (book_type_is_allowed($node->type) and property_exists($node, 'node_export_book')) {
  55. // If this is a root book node, create the book
  56. if (array_key_exists('#is_root', $node->node_export_book) and $node->node_export_book['#is_root']) {
  57. $node->book = array('bid' => 'new');
  58. book_node_update($node);
  59. }
  60. // Otherwise, it's a child node, so add it to a smaller array of nodes to parse
  61. else {
  62. $child_nodes[] = &$node;
  63. }
  64. }
  65. }
  66. // Add each child node to the book as a root item
  67. foreach ($child_nodes as &$node) {
  68. // Find the root book node
  69. $book_nid = _node_export_book_uuid_to_nid($node->node_export_book['#book_uuid']);
  70. // Set up the data we need to make this node a child of the root book node
  71. $node->book = array();
  72. $node->book['bid'] = $book_nid;
  73. $node->book['plid'] = _node_export_book_nid_to_mlid($book_nid);
  74. // Also set up the weight
  75. $node->book['weight'] = $node->node_export_book['weight'];
  76. // Add this node to the book
  77. book_node_update($node);
  78. // Derefernce the parent node's UUID to a nid
  79. $node->node_export_book['#parent_nid'] = _node_export_book_uuid_to_nid($node->node_export_book['#parent_uuid']);
  80. }
  81. // Re-structure the book as it was on the source site
  82. foreach ($child_nodes as &$node) {
  83. // Force a reload of the node
  84. $updated_node = node_load($node->nid, NULL, TRUE);
  85. // Update this node's Parent Link ID (PLID)
  86. $updated_node->book['plid'] = _node_export_book_nid_to_mlid($node->node_export_book['#parent_nid']);
  87. // Update the node
  88. book_node_update($updated_node);
  89. }
  90. }
  91. }
  92. /**
  93. * Implements hook_menu().
  94. */
  95. function node_export_book_menu() {
  96. $items = array();
  97. $items['admin/content/book/node_export_book/%node'] = array(
  98. 'title' => 'Export book',
  99. 'page callback' => '_node_export_book_run_export',
  100. 'page arguments' => array(4),
  101. 'access arguments' => array('export bulk nodes'),
  102. 'type' => MENU_CALLBACK,
  103. );
  104. return $items;
  105. }
  106. /**
  107. * Helper function to export a book.
  108. */
  109. function _node_export_book_run_export($book_root) {
  110. if (module_exists('node_export') and module_exists('book')) {
  111. $nids = array();
  112. // Include some useful utilities
  113. module_load_include('inc', 'node_export_book', 'node_export_book_utils');
  114. module_load_include('inc', 'node_export', 'node_export.pages');
  115. // Get a list of all nodes in this book
  116. $tree = book_menu_subtree_data(menu_link_load(_node_export_book_nid_to_mlid($book_root->nid)));
  117. $nids = _node_export_book_get_nids($tree);
  118. return node_export_gui($nids);
  119. }
  120. }
  121. /**
  122. * Helper function to return the node ID of a book page
  123. */
  124. function _node_export_book_get_nids($tree) {
  125. $answer = array();
  126. foreach ($tree as $key => $value) {
  127. // Base case: menu item is a node
  128. if (is_numeric($tree[$key]['link']['nid'])) {
  129. $answer[] = $tree[$key]['link']['nid'];
  130. }
  131. // Recursive case: menu item has children
  132. if ($tree[$key]['below']) {
  133. $sub_nids = _node_export_book_get_nids($tree[$key]['below']);
  134. $answer = array_merge($answer, $sub_nids);
  135. }
  136. }
  137. return $answer;
  138. }
  139. /**
  140. * Implements hook_menu_alter().
  141. */
  142. function node_export_book_menu_alter(&$items) {
  143. // Alter the page callback for the book overview page
  144. $items['admin/content/book']['page callback'] = '_node_export_book_book_admin_overview';
  145. }
  146. /**
  147. * Helper function to override the book overview page and add an Export book
  148. * operation.
  149. *
  150. * @see book_admin_overview()
  151. */
  152. function _node_export_book_book_admin_overview() {
  153. $rows = array();
  154. $headers = array(t('Book'), t('Operations'));
  155. // Add any recognized books to the table list.
  156. foreach (book_get_books() as $book) {
  157. $operations = array(
  158. 'links' => array(
  159. 'edit' => array(
  160. 'title' => t('edit order and titles'),
  161. 'href' => 'admin/content/book/' . $book['nid'],
  162. ),
  163. 'export' => array(
  164. 'title' => t('export book'),
  165. 'href' => 'admin/content/book/node_export_book/' . $book['nid'],
  166. ),
  167. ),
  168. 'attributes' => array('class' => array('links', 'inline')),
  169. );
  170. $rows[] = array(
  171. l($book['title'], $book['href'], $book['options']),
  172. theme('links', $operations)
  173. );
  174. }
  175. return theme('table', array(
  176. 'header' => $headers,
  177. 'rows' => $rows,
  178. 'empty' => t('No books available.')
  179. ));
  180. }