summaryrefslogtreecommitdiff
path: root/modules/book/book.install
diff options
context:
space:
mode:
Diffstat (limited to 'modules/book/book.install')
-rw-r--r--modules/book/book.install227
1 files changed, 227 insertions, 0 deletions
diff --git a/modules/book/book.install b/modules/book/book.install
index 689225255..59ade1733 100644
--- a/modules/book/book.install
+++ b/modules/book/book.install
@@ -7,12 +7,239 @@
function book_install() {
// Create tables.
drupal_install_schema('book');
+ // Add the node type.
+ _book_install_type_create();
}
/**
* Implementation of hook_uninstall().
*/
function book_uninstall() {
+ // Delete menu links.
+ db_query("DELETE FROM {menu_links} WHERE module = 'book'");
+ menu_cache_clear_all();
// Remove tables.
drupal_uninstall_schema('book');
}
+
+function _book_install_type_create() {
+ // Create an additional node type
+ $book_node_type = array(
+ 'type' => 'book',
+ 'name' => t('Book page'),
+ 'module' => 'node',
+ 'description' => t("A static page. These posts (as well as other types) may be added to a book outline to create a hierarchical structure for your site."),
+ 'custom' => TRUE,
+ 'modified' => TRUE,
+ 'locked' => FALSE,
+ );
+
+ $book_node_type = (object)_node_type_set_defaults($book_node_type);
+ node_type_save($book_node_type);
+ // Default to not promoted.
+ variable_set('node_options_book', array('status'));
+ // Use this default type for adding content to books.
+ variable_set('book_allowed_types', array('book'));
+ variable_set('book_child_type', 'book');
+}
+
+/**
+ * Drupal 5.x to 6.x update.
+ *
+ * This function moves any existing book hierarchy into the new structure used
+ * in the 6.x module. Rather than storing the hierarchy in the {book} table,
+ * the menu API is used to store the hierarchy in the {menu_links} table and the
+ * {book} table serves to uniquely connect a node to a menu link.
+ *
+ * In order to accomplish this, the current hierarchy is processed using a stack.
+ * The stack insures that each parent is processed before any of its children
+ * in the book hierarchy, and is compatible with batched update processing.
+ *
+ */
+function book_update_6000() {
+ $ret = array();
+
+ // Set up for a multi-part update.
+ if (!isset($_SESSION['book_update_6000'])) {
+
+ $schema['book'] = array(
+ 'fields' => array(
+ 'mlid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+ 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+ 'bid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+ ),
+ 'indexes' => array(
+ 'nid' => array('nid'),
+ 'bid' => array('bid')
+ ),
+ 'primary key' => array('mlid'),
+ );
+ // Add the node type.
+ _book_install_type_create();
+
+ // Fix role permissions to account for the changed names
+ // Setup the array holding strings to match and the corresponding
+ // strings to replace them with.
+ $replace = array(
+ 'outline posts in books' => 'administer book outlines',
+ 'create book pages' => 'create book content',
+ 'edit book pages' => 'edit book content',
+ 'edit own book pages' => 'edit own book content',
+ 'see printer-friendly version' => 'access printer-friendly version',
+ );
+
+ // Loop over all the roles, and do the necessary transformations.
+ $query = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
+ while ($role = db_fetch_object($query)) {
+ // Replace all the old permissions with the corresponding new permissions.
+ $fixed_perm = strtr($role->perm, $replace);
+ // If the user could previously create book pages, they should get the new
+ // 'add content to books' permission.
+ if (strpos($role->perm, 'create book pages') !== FALSE) {
+ $fixed_perm .= ', add content to books';
+ }
+ // Only save if the permissions have changed.
+ if ($fixed_perm != $role->perm) {
+ $ret[] = update_sql("UPDATE {permission} SET perm = '$fixed_perm' WHERE rid = $role->rid");
+ }
+ }
+
+ // Determine whether there are any existing nodes in the book hierarchy.
+ if (db_result(db_query("SELECT COUNT(*) FROM {book}"))) {
+ // Temporary table for the old book hierarchy; we'll discard revision info.
+ $schema['book_temp'] = array(
+ 'fields' => array(
+ 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
+ 'parent' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+ 'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny')
+ ),
+ 'indexes' => array(
+ 'parent' => array('parent')
+ ),
+ 'primary key' => array('nid'),
+ );
+
+ db_create_table($ret, 'book_temp', $schema['book_temp']);
+
+ // Insert each node in the old table into the temporary table.
+ $ret[] = update_sql("INSERT INTO {book_temp} (nid, parent, weight) SELECT b.nid, b.parent, b.weight FROM {book} b INNER JOIN {node} n on b.vid = n.vid");
+ $ret[] = update_sql("DROP TABLE {book}");
+
+ db_create_table($ret, 'book', $schema['book']);
+
+ $_SESSION['book_update_6000_orphans']['from'] = 0;
+ $_SESSION['book_update_6000'] = array();
+ $result = db_query("SELECT * from {book_temp} WHERE parent = 0");
+
+ // Collect all books - top-level nodes.
+ while ($a = db_fetch_array($result)) {
+ $_SESSION['book_update_6000'][] = $a;
+ }
+ $ret['#finished'] = FALSE;
+ return $ret;
+ }
+ else {
+ // No exising nodes in the hierarchy, so drop the table and re-create it.
+ $ret[] = update_sql("DROP TABLE {book}");
+ db_create_table($ret, 'book', $schema['book']);
+ return $ret;
+ }
+ }
+ elseif ($_SESSION['book_update_6000_orphans']) {
+ // Do the first batched part of the update - collect orphans.
+ $update_count = 400; // Update this many at a time
+
+ $result = db_query_range("SELECT * FROM {book_temp}", $_SESSION['book_update_6000_orphans']['from'], $update_count);
+
+ if (db_num_rows($result)) {
+ $_SESSION['book_update_6000_orphans']['from'] += $update_count;
+ }
+ else {
+ // Done with this part
+ if (!empty($_SESSION['book_update_6000_orphans']['book'])) {
+ // The orphans' parent is added last, so it will be processed first.
+ $_SESSION['book_update_6000'][] = $_SESSION['book_update_6000_orphans']['book'];
+ }
+ $_SESSION['book_update_6000_orphans'] = FALSE;
+ }
+ // Go through the next $update_count book pages and locate the orphans.
+ while ($book = db_fetch_array($result)) {
+ // Orphans are defined as nodes whose parent does not exist in the table.
+ if ($book['parent'] && !db_result(db_query("SELECT COUNT(*) FROM {book_temp} WHERE nid = %d", $book['parent']))) {
+ if (empty($_SESSION['book_update_6000_orphans']['book'])) {
+ // The first orphan becomes the parent for all other orphans.
+ $book['parent'] = 0;
+ $_SESSION['book_update_6000_orphans']['book'] = $book;
+ $ret[] = array('success' => TRUE, 'query' => t('Relocated orphan book pages.'));
+ }
+ else {
+ // Re-assign the parent value of the book, and add it to the stack.
+ $book['parent'] = $_SESSION['book_update_6000_orphans']['book']['nid'];
+ $_SESSION['book_update_6000'][] = $book;
+ }
+ }
+ }
+ $ret['#finished'] = FALSE;
+ return $ret;
+ }
+ else {
+ // Do the next batched part of the update
+ $update_count = 100; // Update this many at a time
+
+ while ($update_count && $_SESSION['book_update_6000']) {
+ // Get the last node off the stack.
+ $book = array_pop($_SESSION['book_update_6000']);
+
+ // Add all of this node's children to the stack
+ $result = db_query("SELECT * FROM {book_temp} WHERE parent = %d", $book['nid']);
+ while ($a = db_fetch_array($result)) {
+ $_SESSION['book_update_6000'][] = $a;
+ }
+
+ if ($book['parent']) {
+ // If its not a top level page, get its parent's mlid.
+ $parent = db_fetch_array(db_query("SELECT b.mlid AS plid, b.bid FROM {book} b WHERE b.nid = %d", $book['parent']));
+ $book = array_merge($book, $parent);
+ }
+ else {
+ // There is not a parent - this is a new book.
+ $book['plid'] = 0;
+ $book['bid'] = $book['nid'];
+ }
+
+ $book += array(
+ 'module' => 'book',
+ 'link_path' => 'node/'. $book['nid'],
+ 'router_path' => 'node/%',
+ 'menu_name' => book_menu_name($book['bid']),
+ );
+ $book = array_merge($book, db_fetch_array(db_query("SELECT title AS link_title FROM {node} WHERE nid = %d", $book['nid'])));
+
+ // Items with depth > MENU_MAX_DEPTH cannot be saved.
+ if (menu_link_save($book)) {
+ db_query("INSERT INTO {book} (mlid, nid, bid) VALUES (%d, %d, %d)", $book['mlid'], $book['nid'], $book['bid']);
+ }
+ else {
+ // The depth was greater then MENU_MAX_DEPTH, so attach it to the
+ // closest valid parent.
+ $book['plid'] = db_result(db_query("SELECT plid FROM {menu_links} WHERE mlid = %d", $book['plid']));
+ if (menu_link_save($book)) {
+ db_query("INSERT INTO {book} (mlid, nid, bid) VALUES (%d, %d, %d)", $book['mlid'], $book['nid'], $book['bid']);
+ }
+ }
+ $update_count--;
+ }
+ $ret['#finished'] = FALSE;
+ }
+
+ if (empty($_SESSION['book_update_6000'])) {
+ $ret['#finished'] = TRUE;
+ $ret[] = array('success' => TRUE, 'query' => t('Relocated existing book pages.'));
+ $ret[] = update_sql("DROP TABLE {book_temp}");
+ unset($_SESSION['book_update_6000']);
+ unset($_SESSION['book_update_6000_orphans']);
+ }
+
+ return $ret;
+}
+