Index: block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.260
diff -u -r1.260 block.module
--- block.module	14 May 2007 13:53:01 -0000	1.260
+++ block.module	19 May 2007 10:57:45 -0000
@@ -7,10 +7,11 @@
  */
 
 /**
- * Denotes that a block is not enabled in any region and should not
- * be shown.
+ * BLOCK_REGION_NONE:   Denotes that a block is not enabled in any region and should not be shown.
+ * BLOCK_REGION_SELECT: Denotes that a region for this block is not selected
  */
-define('BLOCK_REGION_NONE', -1);
+define('BLOCK_REGION_NONE',   -1);
+define('BLOCK_REGION_SELECT', -2);
 
 /**
  * Implementation of hook_help().
@@ -53,7 +54,13 @@
  */
 function block_theme() {
   return array(
-    'block_admin_display' => array(
+    'block_admin_theme' => array(
+      'arguments' => array('form' => NULL),
+    ),
+    'block_admin_block' => array(
+      'arguments' => array('form' => NULL),
+    ),
+    'block_admin_block_list' => array(
       'arguments' => array('form' => NULL),
     ),
   );
@@ -74,13 +81,54 @@
     'title' => 'Blocks',
     'description' => 'Configure what block content appears in your site\'s sidebars and other regions.',
     'page callback' => 'drupal_get_form',
-    'page arguments' => array('block_admin_display'),
+    'page arguments' => array('block_admin_theme'),
     'access arguments' => array('administer blocks'),
   );
-  $items['admin/build/block/list'] = array(
-    'title' => 'List',
+  // Blocks 'by theme'
+  $items['admin/build/block/theme'] = array(
+    'title' => 'By theme',
     'type' => MENU_DEFAULT_LOCAL_TASK,
-    'weight' => -10,
+    'weight' => 0,
+  );
+  $default = variable_get('theme_default', 'garland');
+  foreach (list_themes() as $key => $theme) {
+    $items['admin/build/block/theme/'. $key] = array(
+      'title' => '!key settings',
+      'title arguments' => array('!key' => $theme->info['name']),
+      'page arguments' => array('block_admin_theme', $key),
+      'type' => ($key == $default) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+      'weight' => ($key == $default) ? -10 : 0,
+    );
+  }
+  // Blocks 'by block'
+  $items['admin/build/block/block'] = array(
+    'title' => 'By block',
+    'page arguments' => array('block_admin_block'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 1,
+  );
+  $items['admin/build/block/block/%'] = array(
+    'page arguments' => array('block_admin_block_list', 4),
+    'type' => MENU_CALLBACK,
+  );
+  foreach (module_list() as $module) {
+    $module_blocks = module_invoke($module, 'block', 'list');
+    if ($module_blocks) {
+      foreach ($module_blocks as $delta => $block) {
+        $items['admin/build/block/block/'. $module .'/'. $delta] = array(
+          'title' => $block['info'],
+          'page arguments' => array('block_admin_block', array($module, $delta)),
+          'type' => ($module == 'user' && $delta == 1) ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
+        );
+      }
+    }
+  }
+  //
+  $items['admin/build/block/add'] = array(
+    'title' => 'Add block',
+    'page arguments' => array('block_add_block_form'),
+    'type' => MENU_LOCAL_TASK,
+    'weight' => 2,
   );
   $items['admin/build/block/configure'] = array(
     'title' => 'Configure block',
@@ -92,21 +140,7 @@
     'page arguments' => array('block_box_delete'),
     'type' => MENU_CALLBACK,
   );
-  $items['admin/build/block/add'] = array(
-    'title' => 'Add block',
-    'page arguments' => array('block_add_block_form'),
-    'type' => MENU_LOCAL_TASK,
-  );
-  $default = variable_get('theme_default', 'garland');
-  foreach (list_themes() as $key => $theme) {
-    $items['admin/build/block/list/'. $key] = array(
-      'title' => '!key settings',
-      'title arguments' => array('!key' => $theme->info['name']),
-      'page arguments' => array('block_admin_display', $key),
-      'type' => $key == $default ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
-      'weight' => $key == $default ? -10 : 0,
-    );
-  }
+  
   return $items;
 }
 
@@ -153,12 +187,8 @@
  * @return
  *   Blocks currently exported by modules.
  */
-function _block_rehash() {
-  global $theme_key;
-
-  init_theme();
-
-  $result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $theme_key);
+function _block_rehash($theme) {
+  $result = db_query("SELECT * FROM {blocks} WHERE theme = '%s'", $theme);
   while ($old_block = db_fetch_object($result)) {
     $old_blocks[$old_block->module][$old_block->delta] = $old_block;
   }
@@ -199,7 +229,7 @@
 
   db_lock_table('blocks');
   // Remove all blocks from table.
-  db_query("DELETE FROM {blocks} WHERE theme = '%s'", $theme_key);
+  db_query("DELETE FROM {blocks} WHERE theme = '%s'", $theme);
 
   // Reinsert new set of blocks into table.
   foreach ($blocks as $block) {
@@ -207,7 +237,7 @@
       'visibility' => NULL,
       'throttle' => NULL,
     );
-    db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s')", $block['module'], $block['delta'], $theme_key, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title']);
+    db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s')", $block['module'], $block['delta'], $theme, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title']);
   }
   db_unlock_tables();
 
@@ -215,9 +245,9 @@
 }
 
 /**
- * Generate main block administration form.
+ * Generate 'by theme' block administration form.
  */
-function block_admin_display($theme = NULL) {
+function block_admin_theme($theme = NULL) {
   global $theme_key, $custom_theme;
 
   // Add CSS
@@ -233,14 +263,14 @@
   init_theme();
 
   // Fetch and sort blocks
-  $blocks = _block_rehash();
+  $blocks = _block_rehash($theme_key);
   usort($blocks, '_block_compare');
 
   $throttle = module_exists('throttle');
   $block_regions = array(BLOCK_REGION_NONE => '<'. t('none') .'>') + system_region_list($theme_key);
 
   // Build form tree
-  $form['#action'] = arg(3) ? url('admin/build/block/list/'. $theme_key) : url('admin/build/block');
+  $form['#action'] = arg(3) ? url('admin/build/block/theme/'. $theme_key) : url('admin/build/block');
   $form['#tree'] = TRUE;
   foreach ($blocks as $i => $block) {
     $form[$i]['module'] = array('#type' => 'value', '#value' => $block['module']);
@@ -256,7 +286,7 @@
     if ($throttle) {
       $form[$i]['throttle'] = array('#type' => 'checkbox', '#default_value' => isset($block['throttle']) ? $block['throttle'] : FALSE);
     }
-    $form[$i]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta']));
+    $form[$i]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $block['module'] .'/'. $block['delta'], array('query' => drupal_get_destination())));
     if ($block['module'] == 'block') {
       $form[$i]['delete'] = array('#value' => l(t('delete'), 'admin/build/block/delete/'. $block['delta']));
     }
@@ -290,11 +320,11 @@
 }
 
 /**
- * Process main block administration form submission.
+ * Process 'by theme' block administration form submission.
  */
-function block_admin_display_submit($form_values, $form, &$form_state) {
+function block_admin_theme_submit($form_values, $form, &$form_state) {
   foreach ($form_values as $block) {
-    $block['status'] = $block['region'] != BLOCK_REGION_NONE;
+    $block['status'] = ($block['region'] != BLOCK_REGION_NONE);
     $block['region'] = $block['status'] ? $block['region'] : '';
     db_query("UPDATE {blocks} SET status = %d, weight = %d, region = '%s', throttle = %d WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $block['status'], $block['weight'], $block['region'], isset($block['throttle']) ? $block['throttle'] : 0, $block['module'], $block['delta'], $block['theme']);
   }
@@ -303,12 +333,12 @@
 }
 
 /**
- * Theme main block administration form submission.
+ * Theme 'by theme' block administration form.
  *
  * Note: the blocks are already sorted in the right order,
  * grouped by status, region and weight.
  */
-function theme_block_admin_display($form) {
+function theme_block_admin_theme($form) {
   global $theme_key;
 
   $throttle = module_exists('throttle');
@@ -365,8 +395,149 @@
   }
   $header[] = array('data' => t('Operations'), 'colspan' => 2);
 
-  $output = theme('table', $header, $rows, array('id' => 'blocks'));
+  $output  = theme('table', $header, $rows, array('id' => 'blocks_theme'));
+  $output .= drupal_render($form);
+
+  return $output;
+}
 
+/**
+ * Generate 'by block' administration form.
+ */ 
+function block_admin_block($block = array('user', 1)) {
+  list ($module, $delta) = $block;
+  
+  // Fetch block status from db
+  $result = db_query("SELECT theme, status, region, weight, throttle FROM {blocks} WHERE module = '%s' AND delta = %d", $module, $delta);
+  while ($block_info = db_fetch_array($result)) {
+    $block_status[$block_info['theme']] = $block_info;
+  }
+  
+  // Build the form
+  $form['#tree'] = TRUE;
+  $form['module'] = array('#type' => 'value', '#value' => $module);
+  $form['delta'] = array('#type' => 'value', '#value' => $delta);
+  $form['configure'] = array('#value' => l(t('Configure block settings'), 'admin/build/block/configure/'. $module .'/'. $delta, array('query' => drupal_get_destination())));
+  
+  $themes = list_themes();
+  ksort($themes);
+  $common_regions = array();
+  foreach ($themes as $key => $theme) {
+    _block_rehash($key);    
+    $block_regions = array(BLOCK_REGION_NONE => '<'. t('none') .'>') + system_region_list($key);
+    $common_regions = count($common_regions) ? array_intersect($block_regions, $common_regions) : $block_regions;
+    $form['themes'][$key]['label'] = array('#value' => $theme->info['name']);
+    $form['themes'][$key]['region'] = array(
+      '#type' => 'select',
+      '#default_value' => $block_status[$key]['status'] ? $block_status[$key]['region'] : BLOCK_REGION_NONE,
+      '#options' => $block_regions,
+    );
+    $form['themes'][$key]['weight'] = array(
+      '#type' => 'weight',
+      '#default_value' => $block_status[$key]['weight']
+    );
+    if (module_exists('throttle')) {
+      $form['themes'][$key]['throttle'] = array('#type' => 'checkbox', '#default_value' => $block_status[$key]['throttle']);
+    }
+  }
+  
+  $common_regions = array(BLOCK_REGION_SELECT => '<'. t('select') .'>') + $common_regions;
+  $form['common_region'] = array(
+    '#type' => 'select',
+    '#default_value' => BLOCK_REGION_SELECT,
+    '#options' => $common_regions,
+  );
+  
+  $form['submit'] = array('#type' => 'submit', '#value' => t('Save block'));
+  
+  return $form;
+}
+
+/**
+ * Theme 'by block' administration form.
+ */ 
+function theme_block_admin_block($form) {
+  $throttle = module_exists('throttle');
+  
+  $rows = array();
+  // Format table header
+  $row = array();
+  $row[] = array('data' => drupal_render($form['configure']), 'class' => 'region');
+  $row[] = array('data' => drupal_render($form['common_region']), 'class' => 'region', 'colspan' => ($throttle ? 3 : 2));
+  $rows[] = array('data' => $row);
+  // Format table body
+  foreach (element_children($form['themes']) as $key) {
+    $row = array();
+    $row[] = drupal_render($form['themes'][$key]['label']);
+    $row[] = drupal_render($form['themes'][$key]['region']);
+    $row[] = drupal_render($form['themes'][$key]['weight']);
+    if (isset($form['themes'][$key]['throttle'])) {
+      $row[] = drupal_render($form['themes'][$key]['throttle']);
+    }
+    $rows[] = $row;
+  }
+  
+  $header = array(t('Theme'), t('Region'), t('Weight'));
+  if ($throttle) {
+    $header[] = t('Throttle');
+  }
+
+  $output  = theme('table', $header, $rows, array('id' => 'blocks_block'));
+  $output .= drupal_render($form);
+
+  return $output;
+}
+
+/**
+ * Process 'by block' administration form submission.
+ */
+function block_admin_block_submit($form_values, $form, &$form_state) {
+  foreach ($form_values['themes'] as $theme => $block) {
+    if ($form_values['common_region'] != BLOCK_REGION_SELECT) {
+      $block['region'] = $form_values['common_region'];
+    }
+    $block['status'] = ($block['region'] != BLOCK_REGION_NONE);
+    $block['region'] = $block['status'] ? $block['region'] : '';
+    db_query("UPDATE {blocks} SET status = %d, region = '%s', weight = %d WHERE module = '%s' AND delta = '%s' AND theme = '%s'", $block['status'], $block['region'], $block['weight'], $form_values['module'], $form_values['delta'], $theme);
+  }
+  drupal_set_message(t('The block settings have been updated.'));
+  cache_clear_all();
+}
+
+/**
+ * Generate 'by block' list form.
+ */
+function block_admin_block_list($modules = NULL) {
+  $modules = $modules ? array($modules) : module_list();
+  
+  foreach ($modules as $module) {
+    $module_blocks = module_invoke($module, 'block', 'list');
+    if ($module_blocks) {
+      foreach ($module_blocks as $delta => $block) {
+        $form['blocks'][$module][$delta]['block'] = array('#value' => l($block['info'], 'admin/build/block/block/'. $module .'/'. $delta));
+        $form['blocks'][$module][$delta]['configure'] = array('#value' => l(t('configure'), 'admin/build/block/configure/'. $module .'/'. $delta, array('query' => drupal_get_destination())));
+      }
+    }
+  }
+  
+  return $form;
+}
+
+/**
+ * Theme 'by block' list form.
+ */ 
+function theme_block_admin_block_list($form) {
+  $rows = array();
+  foreach (element_children($form['blocks']) as $module) {
+    foreach (element_children($form['blocks'][$module]) as $block) {
+      $row = array();
+      $row[] = drupal_render($form['blocks'][$module][$block]['block']);
+      $row[] = drupal_render($form['blocks'][$module][$block]['configure']);
+      $rows[] = $row;
+    }
+  }
+  
+  $output  = theme('table', array(t('Blocks'), t('Operations')), $rows, array('id' => 'blocks_block_list'));
   $output .= drupal_render($form);
 
   return $output;
@@ -516,7 +687,6 @@
     module_invoke($form_values['module'], 'block', 'save', $form_values['delta'], $form_values);
     drupal_set_message(t('The block configuration has been saved.'));
     cache_clear_all();
-    $form_state['redirect'] = 'admin/build/block';
     return;
   }
 }
