diff --git modules/block/block.admin.inc modules/block/block.admin.inc index 27f9669..d90c689 100644 --- modules/block/block.admin.inc +++ modules/block/block.admin.inc @@ -100,7 +100,7 @@ function block_admin_display_form(&$form_state, $blocks, $theme = NULL) { ); $form[$key]['configure'] = array( '#markup' => l(t('configure'), - 'admin/structure/block/configure/' . $block['module'] . '/' . $block['delta']), + 'admin/structure/block/configure/' . $block['module'] . '_' . $block['delta']), ); if ($block['module'] == 'block') { $form[$key]['delete'] = array( @@ -179,7 +179,13 @@ function _block_compare($a, $b) { /** * Menu callback; displays the block configuration form. */ -function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { +function block_admin_configure(&$form_state, $args = NULL) { + $module = NULL; + $delta = 0; + if ($args) { + list($module, $delta) = explode('_', $args); + } + $form['module'] = array( '#type' => 'value', '#value' => $module, @@ -189,22 +195,28 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { '#value' => $delta, ); - $edit = db_query("SELECT pages, visibility, custom, title FROM {block} WHERE module = :module AND delta = :delta", array( + $block = db_query("SELECT block_id, pages, visibility, custom, title FROM {block} WHERE module = :module AND delta = :delta", array( ':module' => $module, ':delta' => $delta, - ))->fetchAssoc(); + ))->fetchObject(); + + $form['block_id'] = array( + '#type' => 'value', + '#value' => $block->block_id, + ); $form['block_settings'] = array( '#type' => 'fieldset', '#title' => t('Block specific settings'), '#collapsible' => TRUE, + '#weight' => -10, ); $form['block_settings']['title'] = array( '#type' => 'textfield', '#title' => t('Block title'), '#maxlength' => 64, '#description' => $module == 'block' ? t('The title of the block as shown to the user.') : t('Override the default title for the block. Use <none> to display no title, or leave blank to use the default block title.'), - '#default_value' => $edit['title'], + '#default_value' => $block->title, '#weight' => -18, ); @@ -216,6 +228,7 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { '#collapsed' => TRUE, '#description' => t('Specify in which region this block is displayed.'), '#tree' => TRUE, + '#weight' => 30, ); $theme_default = variable_get('theme_default', 'garland'); @@ -254,18 +267,26 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { drupal_set_title(t("'%name' block", array('%name' => $info[$delta]['info'])), PASS_THROUGH); } + // Attach fields. + if ($block->block_id) { + $block->block_machine_name = $module . '_' . $delta; + field_attach_load('block', array($block->block_id => $block)); + field_attach_form('block', $block, $form, $form_state); + } + $form['page_vis_settings'] = array( '#type' => 'fieldset', '#title' => t('Page specific visibility settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, + '#weight' => 31, ); $access = user_access('use PHP for settings'); - if ($edit['visibility'] == 2 && !$access) { + if ($block->visibility == 2 && !$access) { $form['page_vis_settings'] = array(); $form['page_vis_settings']['visibility'] = array('#type' => 'value', '#value' => 2); - $form['page_vis_settings']['pages'] = array('#type' => 'value', '#value' => $edit['pages']); + $form['page_vis_settings']['pages'] = array('#type' => 'value', '#value' => $block->pages); } else { $options = array(t('Every page except those specified below.'), t('Only the pages specified below.')); @@ -279,12 +300,12 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { '#type' => 'radios', '#title' => t('Show block on specific pages'), '#options' => $options, - '#default_value' => $edit['visibility'], + '#default_value' => $block->visibility, ); $form['page_vis_settings']['pages'] = array( '#type' => 'textarea', '#title' => t('Pages'), - '#default_value' => $edit['pages'], + '#default_value' => $block->pages, '#description' => $description, ); } @@ -300,6 +321,7 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { '#title' => t('Role specific visibility settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, + '#weight' => 32, ); $form['role_vis_settings']['roles'] = array( '#type' => 'checkboxes', @@ -319,6 +341,7 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { '#title' => t('Content type specific visibility settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, + '#weight' => 33, ); $form['content_type_vis_settings']['types'] = array( '#type' => 'checkboxes', @@ -334,6 +357,7 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { '#title' => t('User specific visibility settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, + '#weight' => 34, ); $form['user_vis_settings']['custom'] = array( '#type' => 'radios', @@ -344,12 +368,13 @@ function block_admin_configure(&$form_state, $module = NULL, $delta = 0) { t('Hide this block by default but let individual users show it.') ), '#description' => t('Allow individual users to customize the visibility of this block in their account settings.'), - '#default_value' => $edit['custom'], + '#default_value' => $block->custom, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Save block'), + '#weight' => 40, ); return $form; @@ -365,10 +390,18 @@ function block_admin_configure_validate($form, &$form_state) { form_set_error('info', t('Please ensure that each block description is unique.')); } } + $block = (object) $form_state['values']; + $block->block_machine_name = $block->module . '_' . $block->delta; + field_attach_form_validate('block', $block, $form, $form_state); } function block_admin_configure_submit($form, &$form_state) { if (!form_get_errors()) { + $block = (object) $form_state['values']; + $block->block_machine_name = $block->module . '_' . $block->delta; + field_attach_submit('block', $block, $form, $form_state); + field_attach_presave('block', $block); + db_update('block') ->fields(array( 'visibility' => (int) $form_state['values']['visibility'], @@ -420,6 +453,8 @@ function block_admin_configure_submit($form, &$form_state) { ->execute(); } + field_attach_update('block', $block); + module_invoke($form_state['values']['module'], 'block_save', $form_state['values']['delta'], $form_state['values']); drupal_set_message(t('The block configuration has been saved.')); cache_clear_all(); @@ -431,7 +466,10 @@ function block_admin_configure_submit($form, &$form_state) { * Menu callback: display the custom block addition form. */ function block_add_block_form(&$form_state) { - return block_admin_configure($form_state, 'block', NULL); + // Use argument 'block_' so that block_admin_configure() assigns the $module + // varialble but not the $delta variable. Needed when creating a new block + // since we do not know what the $delta is yet. + return block_admin_configure($form_state, 'block_'); } function block_add_block_form_validate($form, &$form_state) { @@ -448,30 +486,30 @@ function block_add_block_form_validate($form, &$form_state) { function block_add_block_form_submit($form, &$form_state) { $delta = db_insert('box') ->fields(array( - 'body' => $form_state['values']['body'], 'info' => $form_state['values']['info'], - 'format' => $form_state['values']['body_format'], )) ->execute(); - $query = db_insert('block')->fields(array('visibility', 'pages', 'custom', 'title', 'module', 'theme', 'status', 'weight', 'delta', 'cache')); + $block = array( + 'visibility' => (int) $form_state['values']['visibility'], + 'pages' => trim($form_state['values']['pages']), + 'custom' => (int) $form_state['values']['custom'], + 'title' => $form_state['values']['title'], + 'module' => $form_state['values']['module'], + 'status' => 0, + 'weight' => 0, + 'delta' => $delta, + 'cache' => BLOCK_NO_CACHE, + ); + foreach (list_themes() as $key => $theme) { if ($theme->status) { - $query->values(array( - 'visibility' => (int) $form_state['values']['visibility'], - 'pages' => trim($form_state['values']['pages']), - 'custom' => (int) $form_state['values']['custom'], - 'title' => $form_state['values']['title'], - 'module' => $form_state['values']['module'], - 'theme' => $theme->name, - 'status' => 0, - 'weight' => 0, - 'delta' => $delta, - 'cache' => BLOCK_NO_CACHE, - )); + // Make sure we are creating a new instance of the block for each theme. + unset($block['bid']); + $block['theme'] = $theme->name; + $block = block_save($block); } } - $query->execute(); $query = db_insert('block_role')->fields(array('rid', 'module', 'delta')); foreach (array_filter($form_state['values']['roles']) as $rid) { @@ -493,6 +531,34 @@ function block_add_block_form_submit($form, &$form_state) { } $query->execute(); + // Create the 'block_body' field if it doesn't already exist. + $field = field_info_field('block_body'); + if (empty($field)) { + $field = array( + 'field_name' => 'block_body', + 'type' => 'text_long', + ); + field_create_field($field); + } + + // Attach an instance of the 'block_body' field to the new block bundle. + $instance = array( + 'field_name' => 'block_body', + 'bundle' => 'block_' . $delta, + 'label' => t('Block body'), + 'description' => t('The content of the block as shown to the user.'), + 'required' => TRUE, + 'settings' => array('text_processing' => 1), + 'widget' => array( + 'type' => 'text_textarea', + 'label' => t('Block body'), + ), + 'display' => array( + 'full' => array('label' => 'hidden'), + ), + ); + field_create_instance($instance); + drupal_set_message(t('The block has been created.')); cache_clear_all(); $form_state['redirect'] = 'admin/structure/block'; diff --git modules/block/block.install modules/block/block.install index 28252ed..938283b 100644 --- modules/block/block.install +++ modules/block/block.install @@ -18,6 +18,12 @@ function block_schema() { 'not null' => TRUE, 'description' => 'Primary Key: Unique block ID.', ), + 'block_id' => array( + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Entity ID for block', + ), 'module' => array( 'type' => 'varchar', 'length' => 64, @@ -168,12 +174,6 @@ function block_schema() { 'not null' => TRUE, 'description' => "The block's {block}.bid.", ), - 'body' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'big', - 'description' => 'Block contents.', - ), 'info' => array( 'type' => 'varchar', 'length' => 128, @@ -181,13 +181,6 @@ function block_schema() { 'default' => '', 'description' => 'Block description.', ), - 'format' => array( - 'type' => 'int', - 'size' => 'small', - 'not null' => TRUE, - 'default' => 0, - 'description' => "Block body's {filter_format}.format; for example, 1 = Filtered HTML.", - ) ), 'unique keys' => array( 'info' => array('info'), @@ -274,3 +267,87 @@ function block_update_7001() { db_create_table($ret, 'block_node_type', $schema['block_node_type']); return $ret; } + +/** + * Convert custom block body to a field. + */ +function block_update_7002() { + $ret = array(); + + // Add a block_id column that stores a theme independent entity ID for each + // block. + $block_id_field = array( + 'type' => 'int', + 'not null' => TRUE, + 'description' => 'Entity ID for block', + ); + + // Check that the field hasn't been updated in an aborted run of this + // update. + if (!db_column_exists('block', 'block_id')) { + // Add a new field for the block_id. + db_add_field($ret, 'block', 'block_id', $block_id_field); + } + + $blocks = db_query('SELECT * FROM {block} ORDER BY module, delta')->execute(); + $next_id = 1; + $updated_blocks = array(); + foreach ($blocks as $block) { + if (!in_array($block->module . '_' . $block->delta, $updated_blocks)) { + db_update('block') + ->fields(array('block_id' => $next_id)) + ->condition('module', $block->module) + ->condition('delta', $block->delta) + ->execute(); + $next_id++; + } + } + + // Create the 'block_body' field if it doesn't already exist. + $field = field_info_field('block_body'); + if (empty($field)) { + $field = array( + 'field_name' => 'block_body', + 'type' => 'text_long', + ); + field_create_field($field); + } + + // Attach an instance of the 'block_body' field to all custom blocks. + $boxes = db_query('SELECT * FROM {box}')->execute(); + foreach ($boxes as $box) { + // Create a new bundle for the block + field_attach_create_bundle('block_' . $box->bid); + + $instance = array( + 'field_name' => 'block_body', + 'bundle' => 'block_' . $box->bid, + 'label' => t('Block body'), + 'description' => t('The content of the block as shown to the user.'), + 'required' => TRUE, + 'settings' => array('text_processing' => 1), + 'widget' => array( + 'type' => 'text_textarea', + 'label' => t('Block body'), + ), + 'display' => array( + 'full' => array('label' => 'hidden'), + ), + ); + field_create_instance($instance); + + // Move the block body to the new 'block_body' field. + $box->block_machine_name = 'block_' . $box->bid; + $box->block_body[0]['value'] = $box->body; + $box->block_body[0]['format'] = $box->format; + // This is a core update and no contrib modules are enabled yet, so we can + // assume default field storage for a faster update. + field_sql_storage_field_storage_write('block', $box, FIELD_STORAGE_INSERT, array()); + } + + // Remove the now-obsolete body info from box. + db_drop_field($ret, 'box', 'body'); + db_drop_field($ret, 'box', 'format'); + + return $ret; +} diff --git modules/block/block.module modules/block/block.module index f8b9af8..ebd6719 100644 --- modules/block/block.module +++ modules/block/block.module @@ -67,7 +67,7 @@ function block_help($path, $arg) { switch ($path) { case 'admin/help#block': $output = '

' . t('Blocks are boxes of content rendered into an area, or region, of a web page. The default theme Garland, for example, implements the regions "left sidebar", "right sidebar", "content", "header", and "footer", and a block may appear in any one of these areas. The blocks administration page provides a drag-and-drop interface for assigning a block to a region, and for controlling the order of blocks within regions.', array('@blocks' => url('admin/structure/block'))) . '

'; - $output .= '

' . t('Although blocks are usually generated automatically by modules (like the User login block, for example), administrators can also define custom blocks. Custom blocks have a title, description, and body. The body of the block can be as long as necessary, and can contain content supported by any available text format.', array('@text-format' => url('admin/settings/filter'))) . '

'; + $output .= '

' . t('Although blocks are usually generated automatically by modules (like the User login block, for example), administrators can also define custom blocks. Custom blocks have a title, description, and a body field by default with the option to add additional fields. The body of the block can be as long as necessary, and can contain content supported by any available text format.', array('@text-format' => url('admin/settings/filter'))) . '

'; $output .= '

' . t('When working with blocks, remember that:') . '

'; $output .= '