? files
? generate-content.php
? sites/foo.delocalizedham.com.drupal
Index: database/database.mysql
===================================================================
RCS file: /cvs/drupal/drupal/database/database.mysql,v
retrieving revision 1.163
diff -u -F^f -r1.163 database.mysql
--- database/database.mysql	7 Dec 2004 16:55:38 -0000	1.163
+++ database/database.mysql	11 Dec 2004 00:18:36 -0000
@@ -118,6 +118,7 @@
 --
 
 CREATE TABLE blocks (
+  bid int(10) unsigned NOT NULL auto_increment,
   module varchar(64) DEFAULT '' NOT NULL,
   delta varchar(32) NOT NULL default '0',
   status tinyint(2) DEFAULT '0' NOT NULL,
@@ -126,7 +127,9 @@
   custom tinyint(2) DEFAULT '0' NOT NULL,
   throttle tinyint(1) DEFAULT '0' NOT NULL,
   visibility tinyint(1) DEFAULT '0' NOT NULL,
-  pages text NOT NULL
+  pages text NOT NULL,
+  PRIMARY KEY (bid),
+  INDEX (weight)
 ) TYPE=MyISAM;
 
 --
@@ -143,17 +146,16 @@
 ) TYPE=MyISAM;
 
 --
--- Table structure for table 'boxes'
+-- Table structure for table 'blocks_custom'
 --
 
-CREATE TABLE boxes (
-  bid tinyint(4) NOT NULL auto_increment,
+CREATE TABLE blocks_custom (
+  delta tinyint(4) NOT NULL,
   title varchar(64) NOT NULL default '',
   body longtext,
   info varchar(128) NOT NULL default '',
   format int(4) NOT NULL default '0',
-  PRIMARY KEY  (bid),
-  UNIQUE KEY title (title),
+  PRIMARY KEY  (delta),
   UNIQUE KEY info (info)
 ) TYPE=MyISAM;
 
@@ -800,8 +802,9 @@
 REPLACE variable SET name='update_start', value='s:10:"2004-10-18;"';
 REPLACE variable SET name='theme_default', value='s:10:"bluemarine";';
 
-REPLACE blocks SET module = 'user', delta = '0', status = '1';
-REPLACE blocks SET module = 'user', delta = '1', status = '1';
+REPLACE blocks SET bid = 1, module = 'user', delta = '0', status = '1';
+REPLACE blocks SET bid = 2, module = 'user', delta = '1', status = '1';
+INSERT INTO sequences (name, id) VALUES ('blocks_bid', 2);
 
 INSERT INTO sequences (name, id) VALUES ('menu_mid', 1);
 
Index: database/updates.inc
===================================================================
RCS file: /cvs/drupal/drupal/database/updates.inc,v
retrieving revision 1.78
diff -u -F^f -r1.78 updates.inc
--- database/updates.inc	7 Dec 2004 16:55:38 -0000	1.78
+++ database/updates.inc	11 Dec 2004 00:18:37 -0000
@@ -90,7 +90,8 @@
   "2004-11-07" => "update_111",
   "2004-11-15" => "update_112",
   "2004-11-28" => "update_113",
-  "2004-12-05" => "update_114"
+  "2004-12-05" => "update_114",
+  "2004-12-10" => "update_115"
 );
 
 function update_32() {
@@ -2063,6 +2064,46 @@ function update_114() {
   $ret[] = update_sql("ALTER TABLE {node} DROP score");
   $ret[] = update_sql("ALTER TABLE {node} DROP users");
 
+  return $ret;
+}
+
+function update_115() {
+  $ret = array();
+
+  if ($GLOBALS['db_type'] == 'mysql') {
+    $ret[] = update_sql('ALTER TABLE {boxes} RENAME TO {blocks_custom}');
+    $ret[] = update_sql('ALTER TABLE {blocks_custom} CHANGE bid delta tinyint(4) NOT NULL');
+    $ret[] = update_sql('ALTER TABLE {blocks_custom} DROP INDEX title');
+    $result = db_fetch_object(db_query('SELECT MAX(delta) AS id FROM {blocks_custom}'));
+    if ($result->id) {
+      $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{blocks_custom}_delta', ". $result->id .")");
+    }
+
+    $ret[] = update_sql('ALTER TABLE {blocks} ADD bid int(10) unsigned NOT NULL auto_increment, ADD PRIMARY KEY (bid)');
+    $result = db_fetch_object(db_query('SELECT MAX(bid) AS id FROM {blocks}'));
+    if ($result->id) {
+      $ret[] = update_sql("INSERT INTO {sequences} (name, id) VALUES ('{blocks}_bid', ". $result->id .")");
+    }
+    $ret[] = update_sql('ALTER TABLE {blocks} ADD INDEX (weight)');
+
+    $result = db_query('SELECT bid, module, delta FROM {blocks}');
+    $block_ids = array();
+    while ($block = db_fetch_object($result)) {
+      $block_ids[$block->module][$block->delta] = $block->bid;
+    }
+    $result = db_query("SELECT uid FROM {users} WHERE data LIKE '%block%'");
+    while ($uid = db_fetch_object($result)) {
+      $user = user_load(array('uid' => $uid->uid));
+      $data['block'] = array();
+      foreach ($user->block as $module => $blocks) {
+        foreach ($blocks as $delta => $block) {
+          $data['block'][$block_ids[$module][$delta]] = $block;
+        }
+      }
+      user_save($user, $data);
+    }
+  }
+  
   return $ret;
 }
 
Index: modules/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block.module,v
retrieving revision 1.144
diff -u -F^f -r1.144 block.module
--- modules/block.module	15 Nov 2004 11:26:04 -0000	1.144
+++ modules/block.module	11 Dec 2004 00:18:38 -0000
@@ -72,11 +72,11 @@ function block_menu($may_cache) {
       'type' => MENU_CALLBACK);
     $items[] = array('path' => 'admin/block/delete', 'title' => t('delete block'),
       'access' => user_access('administer blocks'),
-      'callback' => 'block_box_delete',
+      'callback' => 'block_custom_delete',
       'type' => MENU_CALLBACK);
     $items[] = array('path' => 'admin/block/add', 'title' => t('add block'),
       'access' => user_access('administer blocks'),
-      'callback' => 'block_box_add',
+      'callback' => 'block_custom_add',
       'type' => MENU_LOCAL_TASK);
   }
 
@@ -91,25 +91,25 @@ function block_menu($may_cache) {
 function block_block($op = 'list', $delta = 0, $edit = array()) {
   switch ($op) {
     case 'list':
-      $result = db_query('SELECT bid, title, info FROM {boxes} ORDER BY title');
+      $result = db_query('SELECT delta, title, info FROM {blocks_custom} ORDER BY title');
       while ($block = db_fetch_object($result)) {
-        $blocks[$block->bid]['info'] = $block->info;
+        $blocks[$block->delta]['info'] = $block->info;
       }
       return $blocks;
 
     case 'configure':
-      $box = block_box_get($delta);
-      if (filter_access($box['format'])) {
-        return block_box_form($box);
+      $edit = db_fetch_array(db_query('SELECT * FROM {blocks_custom} WHERE delta = %d', $delta));
+      if (filter_access($edit['format'])) {
+        return block_custom_form($edit);
       }
       break;
 
     case 'save':
-      block_box_save($edit, $delta);
+      block_custom_save($edit, $delta);
       break;
 
     case 'view':
-      $block = db_fetch_object(db_query('SELECT * FROM {boxes} WHERE bid = %d', $delta));
+      $block = db_fetch_object(db_query('SELECT title, body, format FROM {blocks_custom} WHERE delta = %d', $delta));
       $data['subject'] = $block->title;
       $data['content'] = check_output($block->body, $block->format);
       return $data;
@@ -117,11 +117,9 @@ function block_block($op = 'list', $delt
 }
 
 function block_admin_save($edit) {
-  foreach ($edit as $module => $blocks) {
-    foreach ($blocks as $delta => $block) {
-      db_query("UPDATE {blocks} SET region = %d, status = %d, weight = %d, throttle = %d WHERE module = '%s' AND delta = '%s'",
-                $block['region'], $block['status'], $block['weight'], $block['throttle'], $module, $delta);
-    }
+  foreach ($edit as $bid => $block) {
+    db_query("UPDATE {blocks} SET region = %d, status = %d, weight = %d, throttle = %d WHERE bid = %d",
+        $block['region'], $block['status'], $block['weight'], $block['throttle'], $bid);
   }
 
   return t('The block settings have been updated.');
@@ -138,47 +136,53 @@ function block_admin_save($edit) {
  *   Blocks currently exported by modules, sorted by $order_by.
  */
 function _block_rehash($order_by = array('weight')) {
-  $result = db_query('SELECT * FROM {blocks} ');
+  $result = db_query('SELECT * FROM {blocks}');
+  $old_blocks = array();
   while ($old_block = db_fetch_object($result)) {
     $old_blocks[$old_block->module][$old_block->delta] = $old_block;
   }
 
-  db_query('DELETE FROM {blocks} ');
-
+  $blocks = array();
+  $order = array();
   foreach (module_list() as $module) {
     $module_blocks = module_invoke($module, 'block', 'list');
     if ($module_blocks) {
       foreach ($module_blocks as $delta => $block) {
-        $block['module'] = $module;
-        $block['delta']  = $delta;
         if ($old_blocks[$module][$delta]) {
-          $block['status'] = $old_blocks[$module][$delta]->status;
-          $block['weight'] = $old_blocks[$module][$delta]->weight;
-          $block['region'] = $old_blocks[$module][$delta]->region;
-          $block['visibility'] = $old_blocks[$module][$delta]->visibility;
-          $block['pages'] = $old_blocks[$module][$delta]->pages;
-          $block['custom'] = $old_blocks[$module][$delta]->custom;
-          $block['throttle'] = $old_blocks[$module][$delta]->throttle;
+          $old_blocks[$module][$delta]->info = $block['info'];
+          $block = $old_blocks[$module][$delta];
         }
         else {
-          $block['status'] = $block['weight'] = $block['region'] = $block['custom'] = 0;
-          $block['pages']   = '';
-        }
+          $block = array2object($block);
+          $block->bid    = db_next_id('{blocks}_bid');
+          $block->module = $module;
+          $block->delta  = $delta;
+          $block->status = $block->weight = $block->region = $block->custom = 0;
+          $block->pages  = '';
 
-        // reinsert blocks into table
-        db_query("INSERT INTO {blocks} (module, delta, status, weight, region, visibility, pages, custom, throttle) VALUES ('%s', '%s', %d, %d, %d, %d, '%s', %d, %d)",
-                  $block['module'], $block['delta'], $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle']);
+          db_query("INSERT INTO {blocks} (bid, module, delta, status, weight, region, visibility, pages, custom, throttle) VALUES (%d, '%s', '%s', %d, %d, %d, %d, '%s', %d, %d)",
+              $block->bid, $block->module, $block->delta, $block->status, $block->weight, $block->region, $block->visibility, $block->pages, $block->custom, $block->throttle);
+        }
 
-        $blocks[] = $block;
+        $blocks[$block->bid] = $block;
 
         // build array to sort on
-        $order[$order_by[0]][] = $block[$order_by[0]];
+        $order[] = $block->{$order_by[0]};
+      }
+    }
+  }
+
+  // Remove any no longer existant blocks from the table
+  foreach ($old_blocks as $module_blocks) {
+    foreach ($module_blocks as $block) {
+      if (!$blocks[$block->bid]) {
+        db_query('DELETE FROM {blocks} WHERE bid = %d', $block->bid);
       }
     }
   }
 
   // sort
-  array_multisort($order[$order_by[0]], $order_by[1] ? $order_by[1] : SORT_ASC, $order_by[2] ? $order_by[2] : SORT_REGULAR, $blocks);
+  array_multisort($order, $order_by[1] ? $order_by[1] : SORT_ASC, $order_by[2] ? $order_by[2] : SORT_REGULAR, array_keys($blocks), $blocks);
 
   return $blocks;
 }
@@ -197,44 +201,34 @@ function block_admin_display() {
 
 
   foreach ($blocks as $block) {
-    if ($block['module'] == 'block') {
-      $operation = l(t('delete'), 'admin/block/delete/'. $block['delta']);
-    }
-    else {
-      $operation = '';
-    }
-
-    $row = array($block['info'], array('data' => form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][status', 1, $block['status']), 'align' => 'center'), form_weight(NULL, $block['module'] .']['. $block['delta'] .'][weight', $block['weight']), form_radios(NULL, $block['module'] .']['. $block['delta'] .'][region', $block['region'], array(t('left'), t('right'))));
-
-    $row = array($block['info'], array('data' => form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][status', 1, $block['status']), 'align' => 'center'), form_weight(NULL, $block['module'] .']['. $block['delta'] .'][weight', $block['weight']), form_radios(NULL, $block['module'] .']['. $block['delta'] .'][region', $block['region'], array(t('left'), t('right'))));
+    $row = array($block->info, array('data' => form_checkbox(NULL, $block->bid .'][status', 1, $block->status), 'align' => 'center'), form_weight(NULL, $block->bid .'][weight', $block->weight), form_radios(NULL, $block->bid .'][region', $block->region, array(t('left'), t('right'))));
     if (module_exist('throttle')) {
-      $row[] = array('data' => form_checkbox(NULL, $block['module'] .']['. $block['delta'] .'][throttle', 1, $block['throttle']), 'align' => 'center');
+      $row[] = array('data' => form_checkbox(NULL, $block->bid .'][throttle', 1, $block->throttle), 'align' => 'center');
     }
-    $row[] = array('data' => l(t('configure'), 'admin/block/configure/'. $block['module'] .'/'. $block['delta']), $operation);
+    $row[] = l(t('configure'), 'admin/block/configure/'. $block->bid);
+    $row[] = ($block->module == 'block') ? l(t('delete'), 'admin/block/delete/'. $block->delta) : '';
+
     $rows[] = $row;
   }
 
   $output = theme('table', $header, $rows);
   $output .= form_submit(t('Save blocks'));
 
-  return form($output, 'post', url('admin/block'));
-}
-
-function block_box_get($bid) {
-  return db_fetch_array(db_query('SELECT * FROM {boxes} WHERE bid = %d', $bid));
+  return form($output);
 }
 
 /**
  * Menu callback; displays the block configuration form.
  */
-function block_admin_configure($module = NULL, $delta = 0) {
+function block_admin_configure($bid) {
   $edit = $_POST['edit'];
   $op = $_POST['op'];
+  $block = db_fetch_object(db_query('SELECT module, delta FROM {blocks} WHERE bid = %d', $bid));
 
   switch ($op) {
     case t('Save block'):
-      db_query("UPDATE {blocks} SET visibility = %d, pages = '%s', custom = %d WHERE module = '%s' AND delta = '%s'", $edit['visibility'], $edit['pages'], $edit['custom'], $module, $delta);
-      module_invoke($module, 'block', 'save', $delta, $edit);
+      db_query("UPDATE {blocks} SET visibility = %d, pages = '%s', custom = %d WHERE bid = %d", $edit['visibility'], $edit['pages'], $edit['custom'], $bid);
+      module_invoke($block->module, 'block', 'save', $block->delta, $edit);
       drupal_set_message('The block configuration has been saved.');
       cache_clear_all();
       drupal_goto('admin/block');
@@ -242,17 +236,17 @@ function block_admin_configure($module =
     default:
       // Always evaluates to TRUE, but a validation step may be added later.
       if (!$edit) {
-        $edit = db_fetch_array(db_query("SELECT pages, visibility, custom FROM {blocks} WHERE module = '%s' AND delta = '%s'", $module, $delta));
+        $edit = db_fetch_array(db_query("SELECT pages, visibility, custom FROM {blocks} WHERE bid = %d", $bid));
       }
 
       // Module-specific block configurations.
-      if ($settings = module_invoke($module, 'block', 'configure', $delta)) {
+      if ($settings = module_invoke($block->module, 'block', 'configure', $block->delta)) {
         $form = form_group(t('Block-specific settings'), $settings);
       }
 
       // Get the block subject for the page title.
-      $info = module_invoke($module, 'block', 'list');
-      drupal_set_title(t("'%name' block", array('%name' => $info[$delta]['info'])));
+      $info = module_invoke($block->module, 'block', 'list');
+      drupal_set_title(t("'%name' block", array('%name' => $info[$block->delta]['info'])));
 
       // Standard block configurations.
       $group = form_radios(t('Show on specific pages'), 'visibility', $edit['visibility'], array(t('Show on every page except the listed pages.'), t('Show on only the listed pages.')));
@@ -271,18 +265,18 @@ function block_admin_configure($module =
 /**
  * Menu callback; displays the block creation form.
  */
-function block_box_add() {
+function block_custom_add() {
   $edit = $_POST['edit'];
   $op = $_POST['op'];
 
   switch ($op) {
     case t('Save block'):
-      block_box_save($edit);
+      block_custom_save($edit);
       drupal_set_message(t('The new block has been added.'));
       drupal_goto('admin/block');
 
     default:
-      $form = block_box_form();
+      $form = block_custom_form();
       $form .= form_submit(t('Save block'));
       $output .= form($form);
   }
@@ -293,19 +287,19 @@ function block_box_add() {
 /**
  * Menu callback; confirm and delete custom blocks.
  */
-function block_box_delete($bid = 0) {
+function block_custom_delete($delta = 0) {
   $op = $_POST['op'];
-  $box = block_box_get($bid);
+  $block = db_fetch_object(db_query('SELECT info FROM {blocks_custom} WHERE delta = %d', $delta));
 
   switch ($op) {
     case t('Delete'):
-      db_query('DELETE FROM {boxes} WHERE bid = %d', $bid);
-      drupal_set_message(t('The block %name has been deleted.', array('%name' => '<em>'. $box['info'] .'</em>')));
+      db_query('DELETE FROM {blocks_custom} WHERE delta = %d', $delta);
+      drupal_set_message(t('The block %name has been deleted.', array('%name' => '<em>'. $block->info .'</em>')));
       cache_clear_all();
       drupal_goto('admin/block');
 
     default:
-      $form = '<p>'. t('Are you sure you want to delete the block %name?', array('%name' => '<em>'. $box['info'] .'</em>')) ."</p>\n";
+      $form = '<p>'. t('Are you sure you want to delete the block %name?', array('%name' => '<em>'. $block->info .'</em>')) ."</p>\n";
       $form .= form_submit(t('Delete'));
       $output = form($form);
   }
@@ -313,7 +307,7 @@ function block_box_delete($bid = 0) {
   print theme('page', $output);
 }
 
-function block_box_form($edit = array()) {
+function block_custom_form($edit = array()) {
   $output = form_textfield(t('Block title'), 'title', $edit['title'], 50, 64, t('The title of the block as shown to the user.'));
   $output .= filter_form('format', $edit['format']);
   $output .= form_textarea(t('Block body'), 'body', $edit['body'], 70, 10, t('The content of the block as shown to the user.'));
@@ -322,16 +316,17 @@ function block_box_form($edit = array())
   return $output;
 }
 
-function block_box_save($edit, $delta = NULL) {
+function block_custom_save($edit, $delta = NULL) {
   if (!filter_access($edit['format'])) {
     $edit['format'] = FILTER_FORMAT_DEFAULT;
   }
 
   if (isset($delta)) {
-    db_query("UPDATE {boxes} SET title = '%s', body = '%s', info = '%s', format = %d WHERE bid = %d", $edit['title'], $edit['body'], $edit['info'], $edit['format'], $delta);
+    db_query("UPDATE {blocks_custom} SET title = '%s', body = '%s', info = '%s', format = %d WHERE delta = %d", $edit['title'], $edit['body'], $edit['info'], $edit['format'], $delta);
   }
   else {
-    db_query("INSERT INTO {boxes} (title, body, info, format) VALUES  ('%s', '%s', '%s', %d)", $edit['title'], $edit['body'], $edit['info'], $edit['format']);
+    $delta = db_next_id('{blocks_custom}_delta');
+    db_query("INSERT INTO {blocks_custom} (delta, title, body, info, format) VALUES (%d, '%s', '%s', '%s', %d)", $delta, $edit['title'], $edit['body'], $edit['info'], $edit['format']);
   }
 }
 
@@ -365,7 +360,7 @@ function block_user($type, $edit, &$user
         while ($block = db_fetch_object($result)) {
           $data = module_invoke($block->module, 'block', 'list');
           if ($data[$block->delta]['info']) {
-            $form .= form_checkbox($data[$block->delta]['info'], 'block]['. $block->module .']['. $block->delta, 1, isset($user->block[$block->module][$block->delta]) ? $user->block[$block->module][$block->delta] : ($block->custom == 1));
+            $form .= form_checkbox($data[$block->delta]['info'], 'block]['. $block->bid, 1, isset($user->block[$block->bid]) ? $user->block[$block->bid] : ($block->custom == 1));
           }
         }
 
@@ -392,9 +387,6 @@ function block_user($type, $edit, &$user
  *
  * @see <a href="http://drupal.org/node/1042" target="_top">[feature]
  *   Generic template design difficult w/o block region "look-ahead"</a>
- * @todo add a proper primary key (bid) to the blocks table so we don't have
- *   to mess around with this <i>module</i>_<i>delta</i> construct. currently,
- *   "blocks" has no primary key defined (bad)!
  */
 function block_list($region) {
   global $user, $base_url;
@@ -402,13 +394,13 @@ function block_list($region) {
 
   if (!isset($blocks[$region])) {
     $blocks[$region] = array();
-    $result = db_query('SELECT * FROM {blocks} WHERE status = 1 '. ($region != 'all' ? 'AND region = %d ' : '') .'ORDER BY weight, module', $region == 'left' ? 0 : 1);
+    $result = db_query('SELECT * FROM {blocks} WHERE status = 1 '. ($region != 'all' ? 'AND region = %d ' : '') .'ORDER BY weight, bid', $region == 'left' ? 0 : 1);
 
     while ($result && ($block = db_fetch_array($result))) {
       // Use the user's block visibility setting, if necessary
       if ($block['custom'] != 0) {
-        if ($user->uid && isset($user->block[$block['module']][$block['delta']])) {
-          $enabled = $user->block[$block['module']][$block['delta']];
+        if ($user->uid && isset($user->block[$block['bid']])) {
+          $enabled = $user->block[$block['bid']];
         }
         else {
           $enabled = ($block['custom'] == 1);
