annotate modules/book/book.install @ 1:c1f4ac30525a 6.0

Drupal 6.0
author Franck Deroche <webmaster@defr.org>
date Tue, 23 Dec 2008 14:28:28 +0100
parents
children 3edae6ecd6c6
rev   line source
webmaster@1 1 <?php
webmaster@1 2 // $Id: book.install,v 1.20 2008/01/10 18:13:42 goba Exp $
webmaster@1 3
webmaster@1 4 /**
webmaster@1 5 * Implementation of hook_install().
webmaster@1 6 */
webmaster@1 7 function book_install() {
webmaster@1 8 // Create tables.
webmaster@1 9 drupal_install_schema('book');
webmaster@1 10 // Add the node type.
webmaster@1 11 _book_install_type_create();
webmaster@1 12 }
webmaster@1 13
webmaster@1 14 /**
webmaster@1 15 * Implementation of hook_uninstall().
webmaster@1 16 */
webmaster@1 17 function book_uninstall() {
webmaster@1 18 // Delete menu links.
webmaster@1 19 db_query("DELETE FROM {menu_links} WHERE module = 'book'");
webmaster@1 20 menu_cache_clear_all();
webmaster@1 21 // Remove tables.
webmaster@1 22 drupal_uninstall_schema('book');
webmaster@1 23 }
webmaster@1 24
webmaster@1 25 function _book_install_type_create() {
webmaster@1 26 // Create an additional node type
webmaster@1 27 $book_node_type = array(
webmaster@1 28 'type' => 'book',
webmaster@1 29 'name' => t('Book page'),
webmaster@1 30 'module' => 'node',
webmaster@1 31 'description' => t('A <em>book page</em> is a page of content, organized into a collection of related entries collectively known as a <em>book</em>. A <em>book page</em> automatically displays links to adjacent pages, providing a simple navigation system for organizing and reviewing structured content.'),
webmaster@1 32 'custom' => TRUE,
webmaster@1 33 'modified' => TRUE,
webmaster@1 34 'locked' => FALSE,
webmaster@1 35 );
webmaster@1 36
webmaster@1 37 $book_node_type = (object)_node_type_set_defaults($book_node_type);
webmaster@1 38 node_type_save($book_node_type);
webmaster@1 39 // Default to not promoted.
webmaster@1 40 variable_set('node_options_book', array('status'));
webmaster@1 41 // Use this default type for adding content to books.
webmaster@1 42 variable_set('book_allowed_types', array('book'));
webmaster@1 43 variable_set('book_child_type', 'book');
webmaster@1 44 }
webmaster@1 45
webmaster@1 46 /**
webmaster@1 47 * Drupal 5.x to 6.x update.
webmaster@1 48 *
webmaster@1 49 * This function moves any existing book hierarchy into the new structure used
webmaster@1 50 * in the 6.x module. Rather than storing the hierarchy in the {book} table,
webmaster@1 51 * the menu API is used to store the hierarchy in the {menu_links} table and the
webmaster@1 52 * {book} table serves to uniquely connect a node to a menu link.
webmaster@1 53 *
webmaster@1 54 * In order to accomplish this, the current hierarchy is processed using a stack.
webmaster@1 55 * The stack insures that each parent is processed before any of its children
webmaster@1 56 * in the book hierarchy, and is compatible with batched update processing.
webmaster@1 57 *
webmaster@1 58 */
webmaster@1 59 function book_update_6000() {
webmaster@1 60 $ret = array();
webmaster@1 61
webmaster@1 62 // Set up for a multi-part update.
webmaster@1 63 if (!isset($_SESSION['book_update_6000'])) {
webmaster@1 64
webmaster@1 65 $schema['book'] = array(
webmaster@1 66 'fields' => array(
webmaster@1 67 'mlid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
webmaster@1 68 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
webmaster@1 69 'bid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
webmaster@1 70 ),
webmaster@1 71 'primary key' => array('mlid'),
webmaster@1 72 'unique keys' => array(
webmaster@1 73 'nid' => array('nid'),
webmaster@1 74 ),
webmaster@1 75 'indexes' => array(
webmaster@1 76 'bid' => array('bid'),
webmaster@1 77 ),
webmaster@1 78 );
webmaster@1 79 // Add the node type.
webmaster@1 80 _book_install_type_create();
webmaster@1 81
webmaster@1 82 // Fix role permissions to account for the changed names
webmaster@1 83 // Setup the array holding strings to match and the corresponding
webmaster@1 84 // strings to replace them with.
webmaster@1 85 $replace = array(
webmaster@1 86 'outline posts in books' => 'administer book outlines',
webmaster@1 87 'create book pages' => 'create book content',
webmaster@1 88 'edit book pages' => 'edit any book content',
webmaster@1 89 'edit own book pages' => 'edit own book content',
webmaster@1 90 'see printer-friendly version' => 'access printer-friendly version',
webmaster@1 91 );
webmaster@1 92
webmaster@1 93 // Loop over all the roles, and do the necessary transformations.
webmaster@1 94 $query = db_query("SELECT rid, perm FROM {permission} ORDER BY rid");
webmaster@1 95 while ($role = db_fetch_object($query)) {
webmaster@1 96 // Replace all the old permissions with the corresponding new permissions.
webmaster@1 97 $fixed_perm = strtr($role->perm, $replace);
webmaster@1 98 // If the user could previously create book pages, they should get the new
webmaster@1 99 // 'add content to books' permission.
webmaster@1 100 if (strpos($role->perm, 'create book pages') !== FALSE) {
webmaster@1 101 $fixed_perm .= ', add content to books';
webmaster@1 102 }
webmaster@1 103 // Only save if the permissions have changed.
webmaster@1 104 if ($fixed_perm != $role->perm) {
webmaster@1 105 $ret[] = update_sql("UPDATE {permission} SET perm = '$fixed_perm' WHERE rid = $role->rid");
webmaster@1 106 }
webmaster@1 107 }
webmaster@1 108
webmaster@1 109 // Determine whether there are any existing nodes in the book hierarchy.
webmaster@1 110 if (db_result(db_query("SELECT COUNT(*) FROM {book}"))) {
webmaster@1 111 // Temporary table for the old book hierarchy; we'll discard revision info.
webmaster@1 112 $schema['book_temp'] = array(
webmaster@1 113 'fields' => array(
webmaster@1 114 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
webmaster@1 115 'parent' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
webmaster@1 116 'weight' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny')
webmaster@1 117 ),
webmaster@1 118 'indexes' => array(
webmaster@1 119 'parent' => array('parent')
webmaster@1 120 ),
webmaster@1 121 'primary key' => array('nid'),
webmaster@1 122 );
webmaster@1 123
webmaster@1 124 db_create_table($ret, 'book_temp', $schema['book_temp']);
webmaster@1 125
webmaster@1 126 // Insert each node in the old table into the temporary table.
webmaster@1 127 $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");
webmaster@1 128 $ret[] = update_sql("DROP TABLE {book}");
webmaster@1 129
webmaster@1 130 db_create_table($ret, 'book', $schema['book']);
webmaster@1 131
webmaster@1 132 $_SESSION['book_update_6000_orphans']['from'] = 0;
webmaster@1 133 $_SESSION['book_update_6000'] = array();
webmaster@1 134 $result = db_query("SELECT * from {book_temp} WHERE parent = 0");
webmaster@1 135
webmaster@1 136 // Collect all books - top-level nodes.
webmaster@1 137 while ($a = db_fetch_array($result)) {
webmaster@1 138 $_SESSION['book_update_6000'][] = $a;
webmaster@1 139 }
webmaster@1 140 $ret['#finished'] = FALSE;
webmaster@1 141 return $ret;
webmaster@1 142 }
webmaster@1 143 else {
webmaster@1 144 // No exising nodes in the hierarchy, so drop the table and re-create it.
webmaster@1 145 $ret[] = update_sql("DROP TABLE {book}");
webmaster@1 146 db_create_table($ret, 'book', $schema['book']);
webmaster@1 147 return $ret;
webmaster@1 148 }
webmaster@1 149 }
webmaster@1 150 elseif ($_SESSION['book_update_6000_orphans']) {
webmaster@1 151 // Do the first batched part of the update - collect orphans.
webmaster@1 152 $update_count = 400; // Update this many at a time
webmaster@1 153
webmaster@1 154 $result = db_query_range("SELECT * FROM {book_temp}", $_SESSION['book_update_6000_orphans']['from'], $update_count);
webmaster@1 155 $has_rows = FALSE;
webmaster@1 156 // Go through the next $update_count book pages and locate the orphans.
webmaster@1 157 while ($book = db_fetch_array($result)) {
webmaster@1 158 $has_rows = TRUE;
webmaster@1 159 // Orphans are defined as nodes whose parent does not exist in the table.
webmaster@1 160 if ($book['parent'] && !db_result(db_query("SELECT COUNT(*) FROM {book_temp} WHERE nid = %d", $book['parent']))) {
webmaster@1 161 if (empty($_SESSION['book_update_6000_orphans']['book'])) {
webmaster@1 162 // The first orphan becomes the parent for all other orphans.
webmaster@1 163 $book['parent'] = 0;
webmaster@1 164 $_SESSION['book_update_6000_orphans']['book'] = $book;
webmaster@1 165 $ret[] = array('success' => TRUE, 'query' => 'Relocated orphan book pages.');
webmaster@1 166 }
webmaster@1 167 else {
webmaster@1 168 // Re-assign the parent value of the book, and add it to the stack.
webmaster@1 169 $book['parent'] = $_SESSION['book_update_6000_orphans']['book']['nid'];
webmaster@1 170 $_SESSION['book_update_6000'][] = $book;
webmaster@1 171 }
webmaster@1 172 }
webmaster@1 173 }
webmaster@1 174 if ($has_rows) {
webmaster@1 175 $_SESSION['book_update_6000_orphans']['from'] += $update_count;
webmaster@1 176 }
webmaster@1 177 else {
webmaster@1 178 // Done with this part
webmaster@1 179 if (!empty($_SESSION['book_update_6000_orphans']['book'])) {
webmaster@1 180 // The orphans' parent is added last, so it will be processed first.
webmaster@1 181 $_SESSION['book_update_6000'][] = $_SESSION['book_update_6000_orphans']['book'];
webmaster@1 182 }
webmaster@1 183 $_SESSION['book_update_6000_orphans'] = FALSE;
webmaster@1 184 }
webmaster@1 185 $ret['#finished'] = FALSE;
webmaster@1 186 return $ret;
webmaster@1 187 }
webmaster@1 188 else {
webmaster@1 189 // Do the next batched part of the update
webmaster@1 190 $update_count = 100; // Update this many at a time
webmaster@1 191
webmaster@1 192 while ($update_count && $_SESSION['book_update_6000']) {
webmaster@1 193 // Get the last node off the stack.
webmaster@1 194 $book = array_pop($_SESSION['book_update_6000']);
webmaster@1 195
webmaster@1 196 // Add all of this node's children to the stack
webmaster@1 197 $result = db_query("SELECT * FROM {book_temp} WHERE parent = %d", $book['nid']);
webmaster@1 198 while ($a = db_fetch_array($result)) {
webmaster@1 199 $_SESSION['book_update_6000'][] = $a;
webmaster@1 200 }
webmaster@1 201
webmaster@1 202 if ($book['parent']) {
webmaster@1 203 // If its not a top level page, get its parent's mlid.
webmaster@1 204 $parent = db_fetch_array(db_query("SELECT b.mlid AS plid, b.bid FROM {book} b WHERE b.nid = %d", $book['parent']));
webmaster@1 205 $book = array_merge($book, $parent);
webmaster@1 206 }
webmaster@1 207 else {
webmaster@1 208 // There is not a parent - this is a new book.
webmaster@1 209 $book['plid'] = 0;
webmaster@1 210 $book['bid'] = $book['nid'];
webmaster@1 211 }
webmaster@1 212
webmaster@1 213 $book += array(
webmaster@1 214 'module' => 'book',
webmaster@1 215 'link_path' => 'node/'. $book['nid'],
webmaster@1 216 'router_path' => 'node/%',
webmaster@1 217 'menu_name' => 'book-toc-'. $book['bid'],
webmaster@1 218 );
webmaster@1 219 $book = array_merge($book, db_fetch_array(db_query("SELECT title AS link_title FROM {node} WHERE nid = %d", $book['nid'])));
webmaster@1 220
webmaster@1 221 // Items with depth > MENU_MAX_DEPTH cannot be saved.
webmaster@1 222 if (menu_link_save($book)) {
webmaster@1 223 db_query("INSERT INTO {book} (mlid, nid, bid) VALUES (%d, %d, %d)", $book['mlid'], $book['nid'], $book['bid']);
webmaster@1 224 }
webmaster@1 225 else {
webmaster@1 226 // The depth was greater then MENU_MAX_DEPTH, so attach it to the
webmaster@1 227 // closest valid parent.
webmaster@1 228 $book['plid'] = db_result(db_query("SELECT plid FROM {menu_links} WHERE mlid = %d", $book['plid']));
webmaster@1 229 if (menu_link_save($book)) {
webmaster@1 230 db_query("INSERT INTO {book} (mlid, nid, bid) VALUES (%d, %d, %d)", $book['mlid'], $book['nid'], $book['bid']);
webmaster@1 231 }
webmaster@1 232 }
webmaster@1 233 $update_count--;
webmaster@1 234 }
webmaster@1 235 $ret['#finished'] = FALSE;
webmaster@1 236 }
webmaster@1 237
webmaster@1 238 if (empty($_SESSION['book_update_6000'])) {
webmaster@1 239 $ret['#finished'] = TRUE;
webmaster@1 240 $ret[] = array('success' => TRUE, 'query' => 'Relocated existing book pages.');
webmaster@1 241 $ret[] = update_sql("DROP TABLE {book_temp}");
webmaster@1 242 unset($_SESSION['book_update_6000']);
webmaster@1 243 unset($_SESSION['book_update_6000_orphans']);
webmaster@1 244 }
webmaster@1 245
webmaster@1 246 return $ret;
webmaster@1 247 }
webmaster@1 248
webmaster@1 249 /**
webmaster@1 250 * Implementation of hook_schema().
webmaster@1 251 */
webmaster@1 252 function book_schema() {
webmaster@1 253 $schema['book'] = array(
webmaster@1 254 'description' => t('Stores book outline information. Uniquely connects each node in the outline to a link in {menu_links}'),
webmaster@1 255 'fields' => array(
webmaster@1 256 'mlid' => array(
webmaster@1 257 'type' => 'int',
webmaster@1 258 'unsigned' => TRUE,
webmaster@1 259 'not null' => TRUE,
webmaster@1 260 'default' => 0,
webmaster@1 261 'description' => t("The book page's {menu_links}.mlid."),
webmaster@1 262 ),
webmaster@1 263 'nid' => array(
webmaster@1 264 'type' => 'int',
webmaster@1 265 'unsigned' => TRUE,
webmaster@1 266 'not null' => TRUE,
webmaster@1 267 'default' => 0,
webmaster@1 268 'description' => t("The book page's {node}.nid."),
webmaster@1 269 ),
webmaster@1 270 'bid' => array(
webmaster@1 271 'type' => 'int',
webmaster@1 272 'unsigned' => TRUE,
webmaster@1 273 'not null' => TRUE,
webmaster@1 274 'default' => 0,
webmaster@1 275 'description' => t("The book ID is the {book}.nid of the top-level page."),
webmaster@1 276 ),
webmaster@1 277 ),
webmaster@1 278 'primary key' => array('mlid'),
webmaster@1 279 'unique keys' => array(
webmaster@1 280 'nid' => array('nid'),
webmaster@1 281 ),
webmaster@1 282 'indexes' => array(
webmaster@1 283 'bid' => array('bid'),
webmaster@1 284 ),
webmaster@1 285 );
webmaster@1 286
webmaster@1 287 return $schema;
webmaster@1 288 }
webmaster@1 289
webmaster@1 290