diff --git a/core/modules/block/block.install b/core/modules/block/block.install index b1fc925..67114b5 100644 --- a/core/modules/block/block.install +++ b/core/modules/block/block.install @@ -49,6 +49,70 @@ function block_update_dependencies() { } /** + * Utility function: return an array map of Drupal 7 block to Drupal 8 blocks. + * This is ugly and hard-coded. Kill @mradcliffe. + * + * @return + * An associative array of Drupal 7 blocks keyed by the module name with + * Drupal 8 block plugin information. + * + * @ingroup update_api + */ +function _update_8009_get_block_info() { + $info = array( + 'book' => array( + 'navigation' => array( + 'plugin' => 'book_navigation', + ), + ), + 'comment' => array( + 'recent' => array( + 'plugin' => 'recent_comments', + ), + ), + 'shortcut' => array( + 'shortcuts' => array( + 'plugin' => 'shortcuts', + ), + ), + 'system' => array( + 'main' => array( + 'plugin' => 'system_main_block', + ), + 'help' => array( + 'plugin' => 'system_help_block', + ), + 'powered-by' => array( + 'plugin' => 'system_powered_by_block', + ), + 'navigation' => array( + 'plugin' => 'system_menu_block:menu-tools', + ), + 'management' => array( + 'plugin' => 'system_menu_block:menu-admin', + ), + 'user-menu' => array( + 'plugin' => 'system_menu_block:menu-account', + ), + 'main-menu' => array( + 'plugin' => 'system_menu_block:menu-main', + ), + ), + ); + +/* + $menus = menu_get_menus(FALSE); + foreach ($menus as $menu_name => $label) { + $info['menu'][$menu_name] = array( + 'plugin' => 'menu_menu_block:menu-' . $menu_name, + ); + } + */ + + return $info; +} + +/** * Block cache is always enabled in 8.x. * * @ingroup config_upgrade @@ -336,6 +400,99 @@ function block_update_8008() { } /** + * Migrate {block} records to configuration instances. + */ +function block_update_8009() { + $sandbox['#finished'] = 0; + + if (!isset($sandbox['total'])) { + // Initial invocation. + + $sandbox['last'] = 0; + $sandbox['count'] = 0; + + $query = db_select('block', 'b'); + $sandbox['total'] = $query + ->condition('b.module', array('block', 'profile', 'blog', 'poll', 'locale', 'language'), 'NOT IN') + ->countQuery() + ->execute() + ->fetchField(); + } + + // Subsequent invocations. + + $found = FALSE; + if ($sandbox['total']) { + // Operate on each block in turn. + + $block_info = _update_8009_get_block_info(); + + $batch_size = 200; + $query = db_select('block', 'b'); + $query + ->fields('b') + ->condition('b.module', array('block', 'profile', 'blog', 'poll', 'locale', 'language'), 'NOT IN') + ->condition('b.bid', $sandbox['last'], '>') + ->orderBy('b.bid', 'ASC') + ->range(0, $batch_size); + $blocks = $query->execute(); + + foreach ($blocks as $block) { + // Try to match a plugin to block. + $plugin_id = ''; + $found = TRUE; + + if (isset($block_info[$block->module])) { + // Block plugin id is not consistent with Drupal 7 block delta. + + foreach (array_keys($block_info[$block->module]) as $key) { + if ($key == $block->delta) { + $plugin_id = $block_info[$block->module][$key]['plugin']; + $settings = isset($block_info[$block->module][$key]['settings']) ? $block_info[$block->module][$key]['settings'] : array(); + break; + } + } + + if (empty($plugin_id)) { + $sandbox['count'] += 1; + $sandbox['last'] = $block->bid; + continue; + } + } + else { + // Fallback to consistent block plugin id: module, delta, block. + $plugin_id = $block->module . '_' . str_replace('-', '_', $block->delta) . '_block'; + $settings = array(); + } + + // @todo visibility + // Create the block configuration entity instance. + $id = $block->theme . '.' . $block->module . '.' . str_replace('-', '_', $block->delta); + $entity = config('block.block.' . $id); + $entity + ->set('id', $id) + ->set('plugin', $plugin_id) + ->set('theme', $block->theme) + ->set('region', $block->region) + ->set('weight', $block->weight) + ->set('status', $block->status) + ->set('settings', $settings); + $entity->save(); + + $sandbox['count'] += 1; + $sandbox['last'] = $block->bid; + } + + $sandbox['#finished'] = min(0.99, $sandbox['count'] / $sandbox['total']); + + if (!$found) { + // We're done. + $sandbox['#finished'] = 1; + } + } +} + +/** * @} End of "addtogroup updates-7.x-to-8.x". * The next series of updates should start at 9000. */ diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php index b9129e3..d48fa05 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/BlockUpgradePathTest.php @@ -8,9 +8,10 @@ namespace Drupal\system\Tests\Upgrade; /** - * Tests upgrading a bare database. + * Tests upgrading a filled database with blocks. * - * Loads a bare installation of Drupal 7 and runs the upgrade process on it. + * Loads a standard installation of Drupal 7 and runs the upgrade process on + * it. */ class BlockUpgradePathTest extends UpgradePathTestBase { @@ -24,7 +25,7 @@ public static function getInfo() { public function setUp() { $this->databaseDumpFiles = array( - drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.bare.minimal.database.php.gz', + drupal_get_path('module', 'system') . '/tests/upgrade/drupal-7.filled.standard_all.database.php.gz', ); parent::setUp(); } @@ -39,6 +40,9 @@ public function testBlockUpgradeTitleLength() { // output validation errors or success messages, so create the blocks from // the UI. + $this->drupalGet('admin/structure/block'); + $this->drupalGet('admin/structure/block/list/block_plugin_ui:seven'); + // Add a block instance with a 255-character title. // Confirm that the custom block has been created, and title matches input. $settings = array(