From 86cc10b630cb6a60db155de9d3f2a183e4ad5dab Mon Sep 17 00:00:00 2001 From: webchick Date: Wed, 16 Sep 2015 13:18:29 -0700 Subject: [PATCH] Issue #2408165 by phenaproxima, miguelc303, quietone, eliza411, tim.plunkett, bdone, benjy: Migration Files for Drupal 7 Blocks --- .../block/migration_templates/d6_block.yml | 24 ++- .../block/migration_templates/d7_block.yml | 100 +++++++++++ .../migrate/destination/EntityBlock.php | 33 ++++ .../process/{d6 => }/BlockPluginId.php | 57 +++--- .../migrate/process/{d6 => }/BlockRegion.php | 7 +- .../process/{d6 => }/BlockSettings.php | 6 +- .../migrate/process/{d6 => }/BlockTheme.php | 14 +- .../migrate/process/BlockVisibility.php | 142 +++++++++++++++ .../migrate/process/d6/BlockVisibility.php | 79 --------- .../Plugin/migrate/source/{d6 => }/Block.php | 78 ++++++--- .../src/Tests/Migrate/d6/MigrateBlockTest.php | 159 ++++++++--------- .../src/Tests/Migrate/d7/MigrateBlockTest.php | 162 ++++++++++++++++++ .../migrate/process/BlockVisibilityTest.php | 88 ++++++++++ .../migrate/source/{d6 => }/BlockTest.php | 30 ++-- .../src/Tests/Table/d6/Blocks.php | 8 +- .../src/Tests/Table/d7/Block.php | 6 +- .../src/Tests/Table/d7/BlockRole.php | 8 +- 17 files changed, 744 insertions(+), 257 deletions(-) create mode 100755 core/modules/block/migration_templates/d7_block.yml create mode 100644 core/modules/block/src/Plugin/migrate/destination/EntityBlock.php rename core/modules/block/src/Plugin/migrate/process/{d6 => }/BlockPluginId.php (60%) rename core/modules/block/src/Plugin/migrate/process/{d6 => }/BlockRegion.php (88%) rename core/modules/block/src/Plugin/migrate/process/{d6 => }/BlockSettings.php (91%) rename core/modules/block/src/Plugin/migrate/process/{d6 => }/BlockTheme.php (87%) create mode 100644 core/modules/block/src/Plugin/migrate/process/BlockVisibility.php delete mode 100644 core/modules/block/src/Plugin/migrate/process/d6/BlockVisibility.php rename core/modules/block/src/Plugin/migrate/source/{d6 => }/Block.php (74%) create mode 100644 core/modules/block/src/Tests/Migrate/d7/MigrateBlockTest.php create mode 100644 core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php rename core/modules/block/tests/src/Unit/Plugin/migrate/source/{d6 => }/BlockTest.php (66%) diff --git a/core/modules/block/migration_templates/d6_block.yml b/core/modules/block/migration_templates/d6_block.yml index 48f213049b26..6ab2a4cc36c7 100644 --- a/core/modules/block/migration_templates/d6_block.yml +++ b/core/modules/block/migration_templates/d6_block.yml @@ -3,10 +3,10 @@ label: Blocks migration_tags: - Drupal 6 source: - plugin: d6_block + plugin: block process: - # Drupal 8 does not have a status but it doesn't matter; this is here to - # skip disabled blocks. + # Block status is not a thing in Drupal 8, so this is how we skip over + # disabled blocks. status: plugin: skip_on_empty method: row @@ -50,15 +50,18 @@ process: 2: views_block:who_s_new-block_1 3: views_block:who_s_online-who_s_online_block - - plugin: d6_block_plugin_id + plugin: block_plugin_id + - + plugin: skip_on_empty + method: row theme: - plugin: d6_block_theme + plugin: block_theme source: - theme - default_theme - admin_theme region: - plugin: d6_block_region + plugin: block_region source: - region - theme @@ -74,17 +77,20 @@ process: label: title weight: weight settings: - plugin: d6_block_settings + plugin: block_settings source: - '@plugin' - delta - settings visibility: - plugin: d6_block_visibility + plugin: block_visibility source: + - visibility - pages - roles - - visibility + # If the block uses PHP visibility, don't migrate it unless the PHP module + # is enabled. + skip_php: true destination: plugin: entity:block migration_dependencies: diff --git a/core/modules/block/migration_templates/d7_block.yml b/core/modules/block/migration_templates/d7_block.yml new file mode 100755 index 000000000000..628bf71583b0 --- /dev/null +++ b/core/modules/block/migration_templates/d7_block.yml @@ -0,0 +1,100 @@ +id: d7_block +label: Blocks +migration_tags: + - Drupal 7 +source: + plugin: block +process: + # Block status is not a thing in Drupal 8, so this is how we skip over + # disabled blocks. + status: + plugin: skip_on_empty + method: row + source: status + id: + - + plugin: concat + source: + - theme + - module + - delta + delimiter: _ + plugin: + - + plugin: static_map + bypass: true + source: + - module + - delta + map: + book: + navigation: book_navigation + comment: + recent: views_block:comments_recent-block_1 + forum: + active: forum_active_block + new: forum_new_block + # locale: + # 0: language_block + node: + syndicate: node_syndicate_block + search: + form: search_form_block + statistics: + popular: statistics_popular_block + system: + main: system_main_block + 'powered-by': system_powered_by_block + user: + login: user_login_block + # 1: system_menu_block:tools + new: views_block:who_s_new-block_1 + online: views_block:who_s_online-who_s_online_block + - + plugin: block_plugin_id + - + plugin: skip_on_empty + method: row + theme: + plugin: block_theme + source: + - theme + - default_theme + - admin_theme + region: + plugin: block_region + source: + - region + - theme + - '@theme' + region_map: + left: sidebar_first + right: sidebar_second + sidebar_first: sidebar_first + sidebar_second: sidebar_second + help: help + header: header + footer: footer + label: title + weight: weight + settings: + plugin: block_settings + source: + - '@plugin' + - delta + - settings + visibility: + plugin: block_visibility + source: + - visibility + - pages + - roles + # If the block uses PHP visibility, don't migrate it unless the PHP module + # is enabled. + skip_php: true +destination: + plugin: entity:block +migration_dependencies: + optional: + - d7_custom_block + - d7_user_role diff --git a/core/modules/block/src/Plugin/migrate/destination/EntityBlock.php b/core/modules/block/src/Plugin/migrate/destination/EntityBlock.php new file mode 100644 index 000000000000..bb0c142a7dfd --- /dev/null +++ b/core/modules/block/src/Plugin/migrate/destination/EntityBlock.php @@ -0,0 +1,33 @@ + $row->getDestinationProperty('plugin'), + 'theme' => $row->getDestinationProperty('theme'), + ); + $blocks = array_keys($this->storage->loadByProperties($properties)); + return reset($blocks); + } + +} diff --git a/core/modules/block/src/Plugin/migrate/process/d6/BlockPluginId.php b/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php similarity index 60% rename from core/modules/block/src/Plugin/migrate/process/d6/BlockPluginId.php rename to core/modules/block/src/Plugin/migrate/process/BlockPluginId.php index 55cbd9686230..dd7980a424bd 100644 --- a/core/modules/block/src/Plugin/migrate/process/d6/BlockPluginId.php +++ b/core/modules/block/src/Plugin/migrate/process/BlockPluginId.php @@ -2,34 +2,38 @@ /** * @file - * Contains \Drupal\block\Plugin\migrate\process\d6\BlockPluginId. + * Contains \Drupal\block\Plugin\migrate\process\BlockPluginId. */ -namespace Drupal\block\Plugin\migrate\process\d6; +namespace Drupal\block\Plugin\migrate\process; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\MigrateExecutableInterface; -use Drupal\migrate\MigrateSkipRowException; -use Drupal\migrate\Plugin\MigratePluginManager; +use Drupal\migrate\Plugin\MigrateProcessInterface; use Drupal\migrate\ProcessPluginBase; use Drupal\migrate\Row; use Symfony\Component\DependencyInjection\ContainerInterface; /** * @MigrateProcessPlugin( - * id = "d6_block_plugin_id" + * id = "block_plugin_id" * ) */ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginInterface { /** - * @var \Drupal\migrate\Plugin\MigratePluginManager + * The migration process plugin, configured for lookups in d6_custom_block + * and d7_custom_block. + * + * @var \Drupal\migrate\Plugin\MigrateProcessInterface */ - protected $processPluginManager; + protected $migrationPlugin; /** + * The block_content entity storage handler. + * * @var \Drupal\Core\Entity\EntityStorageInterface */ protected $blockContentStorage; @@ -37,11 +41,10 @@ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginI /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, MigratePluginManager $process_plugin_manager) { + public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityStorageInterface $storage, MigrateProcessInterface $migration_plugin) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->blockContentStorage = $storage; - $this->migration = $migration; - $this->processPluginManager = $process_plugin_manager; + $this->migrationPlugin = $migration_plugin; } /** @@ -49,13 +52,18 @@ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginI */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { $entity_manager = $container->get('entity.manager'); + $migration_configuration = array( + 'migration' => array( + 'd6_custom_block', + 'd7_custom_block', + ), + ); return new static( $configuration, $plugin_id, $plugin_definition, - $migration, $entity_manager->getDefinition('block_content') ? $entity_manager->getStorage('block_content') : NULL, - $container->get('plugin.manager.migrate.process') + $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_configuration, $migration) ); } @@ -70,31 +78,28 @@ class BlockPluginId extends ProcessPluginBase implements ContainerFactoryPluginI switch ($module) { case 'aggregator': list($type, $id) = explode('-', $delta); - if ($type == 'category') { - // @TODO skip row. - // throw new MigrateSkipRowException(); + if ($type == 'feed') { + return 'aggregator_feed_block'; } - $value = 'aggregator_feed_block'; break; case 'menu': - $value = "system_menu_block:$delta"; - break; + return "system_menu_block:$delta"; case 'block': if ($this->blockContentStorage) { - $block_ids = $this->processPluginManager - ->createInstance('migration', array('migration' => 'd6_custom_block'), $this->migration) + $block_id = $this->migrationPlugin ->transform($delta, $migrate_executable, $row, $destination_property); - $value = 'block_content:' . $this->blockContentStorage->load($block_ids[0])->uuid(); - } - else { - throw new MigrateSkipRowException(); + if ($block_id) { + return 'block_content:' . $this->blockContentStorage->load($block_id)->uuid(); + } } break; default: - throw new MigrateSkipRowException(); + break; } } - return $value; + else { + return $value; + } } } diff --git a/core/modules/block/src/Plugin/migrate/process/d6/BlockRegion.php b/core/modules/block/src/Plugin/migrate/process/BlockRegion.php similarity index 88% rename from core/modules/block/src/Plugin/migrate/process/d6/BlockRegion.php rename to core/modules/block/src/Plugin/migrate/process/BlockRegion.php index 672645b3d462..d51dabd528a1 100644 --- a/core/modules/block/src/Plugin/migrate/process/d6/BlockRegion.php +++ b/core/modules/block/src/Plugin/migrate/process/BlockRegion.php @@ -2,10 +2,10 @@ /** * @file - * Contains \Drupal\block\Plugin\migrate\process\d6\BlockRegion. + * Contains \Drupal\block\Plugin\migrate\process\BlockRegion. */ -namespace Drupal\block\Plugin\migrate\process\d6; +namespace Drupal\block\Plugin\migrate\process; use Drupal\migrate\MigrateExecutableInterface; use Drupal\migrate\ProcessPluginBase; @@ -13,10 +13,11 @@ use Drupal\migrate\Row; /** * @MigrateProcessPlugin( - * id = "d6_block_region" + * id = "block_region" * ) */ class BlockRegion extends ProcessPluginBase { + /** * {@inheritdoc} * diff --git a/core/modules/block/src/Plugin/migrate/process/d6/BlockSettings.php b/core/modules/block/src/Plugin/migrate/process/BlockSettings.php similarity index 91% rename from core/modules/block/src/Plugin/migrate/process/d6/BlockSettings.php rename to core/modules/block/src/Plugin/migrate/process/BlockSettings.php index 2b410eb4e73c..ac36054dadb5 100644 --- a/core/modules/block/src/Plugin/migrate/process/d6/BlockSettings.php +++ b/core/modules/block/src/Plugin/migrate/process/BlockSettings.php @@ -2,10 +2,10 @@ /** * @file - * Contains \Drupal\block\Plugin\migrate\process\d6\BlockSettings. + * Contains \Drupal\block\Plugin\migrate\process\BlockSettings. */ -namespace Drupal\block\Plugin\migrate\process\d6; +namespace Drupal\block\Plugin\migrate\process; use Drupal\migrate\MigrateExecutableInterface; use Drupal\migrate\ProcessPluginBase; @@ -13,7 +13,7 @@ use Drupal\migrate\Row; /** * @MigrateProcessPlugin( - * id = "d6_block_settings" + * id = "block_settings" * ) */ class BlockSettings extends ProcessPluginBase { diff --git a/core/modules/block/src/Plugin/migrate/process/d6/BlockTheme.php b/core/modules/block/src/Plugin/migrate/process/BlockTheme.php similarity index 87% rename from core/modules/block/src/Plugin/migrate/process/d6/BlockTheme.php rename to core/modules/block/src/Plugin/migrate/process/BlockTheme.php index 16039331c264..c072b422cf45 100644 --- a/core/modules/block/src/Plugin/migrate/process/d6/BlockTheme.php +++ b/core/modules/block/src/Plugin/migrate/process/BlockTheme.php @@ -2,10 +2,10 @@ /** * @file - * Contains \Drupal\block\Plugin\migrate\process\d6\BlockTheme. + * Contains \Drupal\block\Plugin\migrate\process\BlockTheme. */ -namespace Drupal\block\Plugin\migrate\process\d6; +namespace Drupal\block\Plugin\migrate\process; use Drupal\migrate\Entity\MigrationInterface; use Drupal\migrate\MigrateExecutableInterface; @@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface; /** * @MigrateProcessPlugin( - * id = "d6_block_theme" + * id = "block_theme" * ) */ class BlockTheme extends ProcessPluginBase implements ContainerFactoryPluginInterface { @@ -74,11 +74,9 @@ class BlockTheme extends ProcessPluginBase implements ContainerFactoryPluginInte /** * {@inheritdoc} - * - * Set the block theme, based on the current default theme. */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - list($theme, $d6_default_theme, $d6_admin_theme) = $value; + list($theme, $default_theme, $admin_theme) = $value; // If the source theme exists on the destination, we're good. if (isset($this->themes[$theme])) { @@ -87,13 +85,13 @@ class BlockTheme extends ProcessPluginBase implements ContainerFactoryPluginInte // If the source block is assigned to a region in the source default theme, // then assign it to the destination default theme. - if (strtolower($theme) == strtolower($d6_default_theme)) { + if (strtolower($theme) == strtolower($default_theme)) { return $this->themeConfig->get('default'); } // If the source block is assigned to a region in the source admin theme, // then assign it to the destination admin theme. - if (strtolower($theme) == strtolower($d6_admin_theme)) { + if (strtolower($theme) == strtolower($admin_theme)) { return $this->themeConfig->get('admin'); } diff --git a/core/modules/block/src/Plugin/migrate/process/BlockVisibility.php b/core/modules/block/src/Plugin/migrate/process/BlockVisibility.php new file mode 100644 index 000000000000..be200976ccf2 --- /dev/null +++ b/core/modules/block/src/Plugin/migrate/process/BlockVisibility.php @@ -0,0 +1,142 @@ +moduleHandler = $module_handler; + $this->migrationPlugin = $migration_plugin; + + if (isset($configuration['skip_php'])) { + $this->skipPHP = $configuration['skip_php']; + } + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + $migration_configuration = array( + 'migration' => array( + 'd6_user_role', + 'd7_user_role', + ), + ); + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('module_handler'), + $container->get('plugin.manager.migrate.process')->createInstance('migration', $migration_configuration, $migration) + ); + } + + /** + * {@inheritdoc} + */ + public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { + list($old_visibility, $pages, $roles) = $value; + + $visibility = array(); + + // If the block is assigned to specific roles, add the user_role condition. + if ($roles) { + $visibility['user_role'] = array( + 'id' => 'user_role', + 'roles' => array(), + 'context_mapping' => array( + 'user' => '@user.current_user_context:current_user', + ), + 'negate' => FALSE, + ); + + foreach ($roles as $key => $role_id) { + $roles[$key] = $this->migrationPlugin->transform($role_id, $migrate_executable, $row, $destination_property); + } + $visibility['user_role']['roles'] = array_combine($roles, $roles); + } + + if ($pages) { + // 2 == BLOCK_VISIBILITY_PHP in Drupal 6 and 7. + if ($old_visibility == 2) { + // If the PHP module is present, migrate the visibility code unaltered. + if ($this->moduleHandler->moduleExists('php')) { + $visibility['php'] = array( + 'id' => 'php', + // PHP code visibility could not be negated in Drupal 6 or 7. + 'negate' => FALSE, + 'php' => $pages, + ); + } + // Skip the row if we're configured to. If not, we don't need to do + // anything else -- the block will simply have no PHP or request_path + // visibility configuration. + elseif ($this->skipPHP) { + throw new MigrateSkipRowException(); + } + } + else { + $paths = preg_split("(\r\n?|\n)", $pages); + foreach ($paths as $key => $path) { + $paths[$key] = $path === '' ? $path : '/' . ltrim($path, '/'); + } + $visibility['request_path'] = array( + 'id' => 'request_path', + 'negate' => !$old_visibility, + 'pages' => implode("\n", $paths), + ); + } + } + + return $visibility; + } + +} diff --git a/core/modules/block/src/Plugin/migrate/process/d6/BlockVisibility.php b/core/modules/block/src/Plugin/migrate/process/d6/BlockVisibility.php deleted file mode 100644 index 9afd1800f47e..000000000000 --- a/core/modules/block/src/Plugin/migrate/process/d6/BlockVisibility.php +++ /dev/null @@ -1,79 +0,0 @@ -migration = $migration; - $this->migrationPlugin = $migration_plugin; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $migration, - $container->get('plugin.manager.migrate.process')->createInstance('migration', array('migration' => 'd6_user_role'), $migration) - ); - } - /** - * {@inheritdoc} - * - * Set the block visibility settings. - */ - public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { - list($pages, $roles, $old_visibility) = $value; - $visibility = array(); - - if (!empty($pages)) { - $visibility['request_path']['pages'] = $pages; - $visibility['request_path']['id'] = 'request_path'; - $visibility['request_path']['negate'] = !$old_visibility; - } - - if (!empty($roles)) { - foreach ($roles as $key => $role_id) { - $new_role = $this->migrationPlugin->transform($role_id, $migrate_executable, $row, $destination_property); - $visibility['user_role']['roles'][$new_role] = $new_role; - } - $visibility['user_role']['id'] = 'user_role'; - $visibility['user_role']['context_mapping']['user'] = 'user.current_user'; - } - return $visibility; - } - -} diff --git a/core/modules/block/src/Plugin/migrate/source/d6/Block.php b/core/modules/block/src/Plugin/migrate/source/Block.php similarity index 74% rename from core/modules/block/src/Plugin/migrate/source/d6/Block.php rename to core/modules/block/src/Plugin/migrate/source/Block.php index ba13254b2cf3..26725cd26f71 100644 --- a/core/modules/block/src/Plugin/migrate/source/d6/Block.php +++ b/core/modules/block/src/Plugin/migrate/source/Block.php @@ -2,22 +2,24 @@ /** * @file - * Contains \Drupal\block\Plugin\migrate\source\d6\Block. + * Contains \Drupal\block\Plugin\migrate\source\Block. */ -namespace Drupal\block\Plugin\migrate\source\d6; +namespace Drupal\block\Plugin\migrate\source; use Drupal\migrate\Row; use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; /** - * Drupal 6 block source from database. + * Drupal block source from database. * * @MigrateSource( - * id = "d6_block" + * id = "block", + * source_provider = "block" * ) */ class Block extends DrupalSqlBase { + /** * The default theme name. * @@ -32,14 +34,33 @@ class Block extends DrupalSqlBase { */ protected $adminTheme; + /** + * Table containing block configuration. + * + * @var string + */ + protected $blockTable; + + /** + * Table mapping blocks to user roles. + * + * @var string + */ + protected $blockRoleTable; + /** * {@inheritdoc} */ public function query() { - $query = $this->select('blocks', 'b') - ->fields('b', array('bid', 'module', 'delta', 'theme', 'status', 'weight', 'region', 'visibility', 'pages', 'title', 'cache')) - ->orderBy('bid'); - return $query; + if ($this->getModuleSchemaVersion('system') >= 7000) { + $this->blockTable = 'block'; + $this->blockRoleTable = 'block_role'; + } + else { + $this->blockTable = 'blocks'; + $this->blockRoleTable = 'blocks_roles'; + } + return $this->select($this->blockTable, 'b')->fields('b'); } /** @@ -67,36 +88,54 @@ class Block extends DrupalSqlBase { 'pages' => $this->t('Pages list.'), 'title' => $this->t('Block title.'), 'cache' => $this->t('Cache rule.'), - ); } + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['module']['type'] = 'string'; + $ids['delta']['type'] = 'string'; + $ids['theme']['type'] = 'string'; + return $ids; + } + /** * {@inheritdoc} */ public function prepareRow(Row $row) { $row->setSourceProperty('default_theme', $this->defaultTheme); $row->setSourceProperty('admin_theme', $this->adminTheme); + $module = $row->getSourceProperty('module'); $delta = $row->getSourceProperty('delta'); - $roles = $this->select('blocks_roles', 'br') + + $roles = $this->select($this->blockRoleTable, 'br') ->fields('br', array('rid')) ->condition('module', $module) ->condition('delta', $delta) ->execute() ->fetchCol(); $row->setSourceProperty('roles', $roles); + $settings = array(); - // Contrib can use hook_migration_d6_block_prepare_row() to add similar - // variables via $migration->getSource()->variableGet(). switch ($module) { case 'aggregator': list($type, $id) = explode('-', $delta); if ($type == 'feed') { - $item_count = $this->database->query('SELECT block FROM {aggregator_feed} WHERE fid = :fid', array(':fid' => $id))->fetchField(); + $item_count = $this->select('aggregator_feed', 'af') + ->fields('af', ['block']) + ->condition('fid', $id) + ->execute() + ->fetchField(); } else { - $item_count = $this->database->query('SELECT block FROM {aggregator_category} WHERE cid = :cid', array(':cid' => $id))->fetchField(); + $item_count = $this->select('aggregator_category', 'ac') + ->fields('ac', ['block']) + ->condition('cid', $id) + ->execute() + ->fetchField(); } $settings['aggregator']['item_count'] = $item_count; break; @@ -114,9 +153,11 @@ class Block extends DrupalSqlBase { case 'user': switch ($delta) { case 2: + case 'new': $settings['user']['block_whois_new_count'] = $this->variableGet('user_block_whois_new_count', 5); break; case 3: + case 'online': $settings['user']['block_seconds_online'] = $this->variableGet('user_block_seconds_online', 900); $settings['user']['max_list_count'] = $this->variableGet('user_block_max_list_count', 10); break; @@ -126,14 +167,5 @@ class Block extends DrupalSqlBase { $row->setSourceProperty('settings', $settings); return parent::prepareRow($row); } - /** - * {@inheritdoc} - */ - public function getIds() { - $ids['module']['type'] = 'string'; - $ids['delta']['type'] = 'string'; - $ids['theme']['type'] = 'string'; - return $ids; - } } diff --git a/core/modules/block/src/Tests/Migrate/d6/MigrateBlockTest.php b/core/modules/block/src/Tests/Migrate/d6/MigrateBlockTest.php index 49d40d79fe8a..214c6d3d3838 100644 --- a/core/modules/block/src/Tests/Migrate/d6/MigrateBlockTest.php +++ b/core/modules/block/src/Tests/Migrate/d6/MigrateBlockTest.php @@ -11,7 +11,7 @@ use Drupal\block\Entity\Block; use Drupal\migrate_drupal\Tests\d6\MigrateDrupal6TestBase; /** - * Upgrade block settings to block.block.*.yml. + * Tests migration of blocks to configuration entities. * * @group migrate_drupal_6 */ @@ -49,7 +49,7 @@ class MigrateBlockTest extends MigrateDrupal6TestBase { $entity->save(); } $this->prepareMigrations(array( - 'd6_custom_block' => array( + 'd6_custom_block' => array( array(array(1), array(1)), array(array(2), array(2)), ), @@ -75,108 +75,93 @@ class MigrateBlockTest extends MigrateDrupal6TestBase { } /** - * Test the block settings migration. + * Asserts various aspects of a block. + * + * @param string $id + * The block ID. + * @param string $module + * The module. + * @param array $visibility + * The block visibility settings. + * @param string $region + * The display region. + * @param string $theme + * The theme. + * @param string $weight + * The block weight. + */ + public function assertEntity($id, $visibility, $region, $theme, $weight) { + $block = Block::load($id); + $this->assertTrue($block instanceof Block); + $this->assertIdentical($visibility, $block->getVisibility()); + $this->assertIdentical($region, $block->getRegion()); + $this->assertIdentical($theme, $block->getTheme()); + $this->assertIdentical($weight, $block->getWeight()); + } + + /** + * Tests the block migration. */ public function testBlockMigration() { $blocks = Block::loadMultiple(); - $this->assertIdentical(count($blocks), 10); + $this->assertIdentical(9, count($blocks)); // User blocks - $test_block_user = $blocks['user']; - $this->assertNotNull($test_block_user); - $this->assertIdentical('sidebar_first', $test_block_user->getRegion()); - $this->assertIdentical('bartik', $test_block_user->getTheme()); - $visibility = $test_block_user->getVisibility(); - $this->assertTrue(empty($visibility)); - $this->assertIdentical(0, $test_block_user->getWeight()); + $visibility = []; + $visibility['request_path']['id'] = 'request_path'; + $visibility['request_path']['negate'] = TRUE; + $visibility['request_path']['pages'] = "\n/node/1\n/blog/*"; + $this->assertEntity('user', $visibility, 'sidebar_first', 'bartik', 0); - $test_block_user_1 = $blocks['user_1']; - $this->assertNotNull($test_block_user_1); - $this->assertIdentical('sidebar_first', $test_block_user_1->getRegion()); - $this->assertIdentical('bartik', $test_block_user_1->getTheme()); - $visibility = $test_block_user_1->getVisibility(); - $this->assertTrue(empty($visibility)); - $this->assertIdentical(0, $test_block_user_1->getWeight()); + $visibility = []; + $this->assertEntity('user_1', $visibility, 'sidebar_first', 'bartik', 0); - $test_block_user_2 = $blocks['user_2']; - $this->assertNotNull($test_block_user_2); - $this->assertIdentical('sidebar_second', $test_block_user_2->getRegion()); - $this->assertIdentical('bartik', $test_block_user_2->getTheme()); - $visibility = $test_block_user_2->getVisibility(); - $this->assertIdentical($visibility['user_role']['id'], 'user_role'); - $roles = array(); + $visibility['user_role']['id'] = 'user_role'; $roles['authenticated'] = 'authenticated'; - $this->assertIdentical($visibility['user_role']['roles'], $roles); - $this->assertFalse($visibility['user_role']['negate']); - $this->assertIdentical(-9, $test_block_user_2->getWeight()); + $visibility['user_role']['roles'] = $roles; + $context_mapping['user'] = '@user.current_user_context:current_user'; + $visibility['user_role']['context_mapping'] = $context_mapping; + $visibility['user_role']['negate'] = FALSE; + $this->assertEntity('user_2', $visibility, 'sidebar_second', 'bartik', -9); - $test_block_user_3 = $blocks['user_3']; - $this->assertNotNull($test_block_user_3); - $this->assertIdentical('sidebar_second', $test_block_user_3->getRegion()); - $this->assertIdentical('bartik', $test_block_user_3->getTheme()); - $visibility = $test_block_user_3->getVisibility(); - $this->assertIdentical($visibility['user_role']['id'], 'user_role'); - $roles = array(); - $roles['migrate_test_role_1'] = 'migrate_test_role_1'; - $this->assertIdentical($visibility['user_role']['roles'], $roles); - $this->assertFalse($visibility['user_role']['negate']); - $this->assertIdentical(-6, $test_block_user_3->getWeight()); + $visibility = []; + $visibility['user_role']['id'] = 'user_role'; + $visibility['user_role']['roles'] = [ + 'migrate_test_role_1' => 'migrate_test_role_1' + ]; + $context_mapping['user'] = '@user.current_user_context:current_user'; + $visibility['user_role']['context_mapping'] = $context_mapping; + $visibility['user_role']['negate'] = FALSE; + $this->assertEntity('user_3', $visibility, 'sidebar_second', 'bartik', -6); // Check system block - $test_block_system = $blocks['system']; - $this->assertNotNull($test_block_system); - $this->assertIdentical('footer', $test_block_system->getRegion()); - $this->assertIdentical('bartik', $test_block_system->getTheme()); - $visibility = $test_block_system->getVisibility(); - $this->assertIdentical('request_path', $visibility['request_path']['id']); - $this->assertIdentical('node/1', $visibility['request_path']['pages']); - $this->assertTrue($visibility['request_path']['negate']); - $this->assertIdentical(-5, $test_block_system->getWeight()); + $visibility = []; + $visibility['request_path']['id'] = 'request_path'; + $visibility['request_path']['negate'] = TRUE; + $visibility['request_path']['pages'] = '/node/1'; + $this->assertEntity('system', $visibility, 'footer', 'bartik', -5); // Check menu blocks - $test_block_menu = $blocks['menu']; - $this->assertNotNull($test_block_menu); - $this->assertIdentical('header', $test_block_menu->getRegion()); - $this->assertIdentical('bartik', $test_block_menu->getTheme()); - $visibility = $test_block_menu->getVisibility(); - $this->assertTrue(empty($visibility)); - $this->assertIdentical(-5, $test_block_menu->getWeight()); + $visibility = []; + $this->assertEntity('menu', $visibility, 'header', 'bartik', -5); // Check custom blocks - $test_block_block = $blocks['block']; - $this->assertNotNull($test_block_block); - $this->assertIdentical('content', $test_block_block->getRegion()); - $this->assertIdentical('bartik', $test_block_block->getTheme()); - $visibility = $test_block_block->getVisibility(); - $this->assertIdentical('request_path', $visibility['request_path']['id']); - $this->assertIdentical('', $visibility['request_path']['pages']); - $this->assertFalse($visibility['request_path']['negate']); - $this->assertIdentical(0, $test_block_block->getWeight()); + $visibility['request_path']['id'] = 'request_path'; + $visibility['request_path']['negate'] = FALSE; + $visibility['request_path']['pages'] = ''; + $this->assertEntity('block', $visibility, 'content', 'bartik', 0); - $test_block_block_1 = $blocks['block_1']; - $this->assertNotNull($test_block_block_1); - $this->assertIdentical('right', $test_block_block_1->getRegion()); - $this->assertIdentical('bluemarine', $test_block_block_1->getTheme()); - $visibility = $test_block_block_1->getVisibility(); - $this->assertIdentical('request_path', $visibility['request_path']['id']); - $this->assertIdentical('node', $visibility['request_path']['pages']); - $this->assertFalse($visibility['request_path']['negate']); - $this->assertIdentical(-4, $test_block_block_1->getWeight()); + $visibility['request_path']['id'] = 'request_path'; + $visibility['request_path']['negate'] = FALSE; + $visibility['request_path']['pages'] = '/node'; + $this->assertEntity('block_1', $visibility, 'right', 'bluemarine', -4); - $test_block_block_2 = $blocks['block_2']; - $this->assertNotNull($test_block_block_2); - $this->assertIdentical('right', $test_block_block_2->getRegion()); - $this->assertIdentical('test_theme', $test_block_block_2->getTheme()); - $visibility = $test_block_block_2->getVisibility(); - $this->assertTrue(empty($visibility)); - $this->assertIdentical(-7, $test_block_block_2->getWeight()); + $visibility = []; + $this->assertEntity('block_2', $visibility, 'right', 'test_theme', -7); - $test_block_block_3 = $blocks['block_3']; - $this->assertNotNull($test_block_block_3); - $this->assertIdentical('left', $test_block_block_3->getRegion()); - $this->assertIdentical('test_theme', $test_block_block_3->getTheme()); - $visibility = $test_block_block_3->getVisibility(); - $this->assertTrue(empty($visibility)); - $this->assertIdentical(-2, $test_block_block_3->getWeight()); + // Custom block with php code is not migrated. + $block = Block::load('block_3'); + $this->assertFalse($block instanceof Block); } + } diff --git a/core/modules/block/src/Tests/Migrate/d7/MigrateBlockTest.php b/core/modules/block/src/Tests/Migrate/d7/MigrateBlockTest.php new file mode 100644 index 000000000000..75f00cef49b3 --- /dev/null +++ b/core/modules/block/src/Tests/Migrate/d7/MigrateBlockTest.php @@ -0,0 +1,162 @@ +installConfig(static::$modules); + $this->installEntitySchema('block_content'); + + // Set Bartik and Seven as the default public and admin theme. + $config = $this->config('system.theme'); + $config->set('default', 'bartik'); + $config->set('admin', 'seven'); + $config->save(); + + // Install one of D8's test themes. + \Drupal::service('theme_handler')->install(array('test_theme')); + + $this->executeMigration('d7_filter_format'); + $this->executeMigration('d7_user_role'); + $this->executeMigration('block_content_type'); + $this->executeMigration('block_content_body_field'); + $this->executeMigration('d7_custom_block'); + $this->executeMigration('d7_block'); + } + + /** + * Asserts various aspects of a block. + * + * @param string $id + * The block ID. + * @param string $plugin_id + * The block's plugin ID. + * @param array $roles + * Role IDs the block is expected to have. + * @param string $pages + * The list of pages on which the block should appear. + * @param string $region + * The display region. + * @param string $theme + * The theme. + * @param string $weight + * The block weight. + */ + public function assertEntity($id, $plugin_id, array $roles, $pages, $region, $theme, $weight) { + $block = Block::load($id); + $this->assertTrue($block instanceof Block); + /** @var \Drupal\block\BlockInterface $block */ + $this->assertIdentical($plugin_id, $block->getPluginId()); + + $visibility = $block->getVisibility(); + if ($roles) { + $this->assertIdentical($roles, array_values($visibility['user_role']['roles'])); + $this->assertIdentical('@user.current_user_context:current_user', $visibility['user_role']['context_mapping']['user']); + } + if ($pages) { + $this->assertIdentical($pages, $visibility['request_path']['pages']); + } + + $this->assertIdentical($region, $block->getRegion()); + $this->assertIdentical($theme, $block->getTheme()); + $this->assertIdentical($weight, $block->getWeight()); + } + + /** + * Tests the block migration. + */ + public function testBlockMigration() { + $this->assertEntity('bartik_system_main', 'system_main_block', [], '', 'content', 'bartik', 0); + $this->assertEntity('bartik_search_form', 'search_form_block', [], '', 'sidebar_first', 'bartik', -1); + $this->assertEntity('bartik_user_login', 'user_login_block', [], '', 'sidebar_first', 'bartik', 0); + $this->assertEntity('bartik_system_powered-by', 'system_powered_by_block', [], '', 'footer', 'bartik', 10); + $this->assertEntity('seven_system_main', 'system_main_block', [], '', 'content', 'seven', 0); + $this->assertEntity('seven_user_login', 'user_login_block', [], '', 'content', 'seven', 10); + + // The d7_custom_block migration should have migrated a block containing a + // mildly amusing limerick. We'll need its UUID to determine + // bartik_block_1's plugin ID. + $uuid = BlockContent::load(1)->uuid(); + $this->assertEntity('bartik_block_1', 'block_content:' . $uuid, ['authenticated'], '', 'highlighted', 'bartik', 0); + + // Assert that disabled blocks (or enabled blocks whose plugin IDs could + // be resolved) did not migrate. + $non_existent_blocks = array( + 'bartik_system_navigation', + 'bartik_system_help', + 'seven_user_new', + 'seven_search_form', + 'bartik_comment_recent', + 'bartik_node_syndicate', + 'bartik_node_recent', + 'bartik_shortcut_shortcuts', + 'bartik_system_management', + 'bartik_system_user-menu', + 'bartik_system_main-menu', + 'bartik_user_new', + 'bartik_user_online', + 'seven_comment_recent', + 'seven_node_syndicate', + 'seven_shortcut_shortcuts', + 'seven_system_powered-by', + 'seven_system_navigation', + 'seven_system_management', + 'seven_system_user-menu', + 'seven_system_main-menu', + 'seven_user_online', + 'bartik_blog_recent', + 'bartik_book_navigation', + 'bartik_locale_language', + 'bartik_forum_active', + 'bartik_forum_new', + 'seven_blog_recent', + 'seven_book_navigation', + 'seven_locale_language', + 'seven_forum_active', + 'seven_forum_new', + 'bartik_menu_menu-test-menu', + 'bartik_statistics_popular', + 'seven_menu_menu-test-menu', + 'seven_statistics_popular', + 'seven_block_1', + ); + $this->assertTrue(empty(Block::loadMultiple($non_existent_blocks))); + } + +} diff --git a/core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php b/core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php new file mode 100644 index 000000000000..37efa46aa290 --- /dev/null +++ b/core/modules/block/tests/src/Unit/Plugin/migrate/process/BlockVisibilityTest.php @@ -0,0 +1,88 @@ +moduleHandler = $this->prophesize(ModuleHandlerInterface::class); + $migration_plugin = $this->prophesize(MigrateProcessInterface::class); + $this->plugin = new BlockVisibility([], 'block_visibility_pages', [], $this->moduleHandler->reveal(), $migration_plugin->reveal()); + } + + /** + * @covers ::transform + */ + public function testTransformNoData() { + $transformed_value = $this->plugin->transform([0, '', []], $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertEmpty($transformed_value); + } + + /** + * @covers ::transform + */ + public function testTransformSinglePageWithFront() { + $visibility = $this->plugin->transform([0, '', []], $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame('request_path', $visibility['request_path']['id']); + $this->assertTrue($visibility['request_path']['negate']); + $this->assertSame('', $visibility['request_path']['pages']); + } + + /** + * @covers ::transform + */ + public function testTransformMultiplePagesWithFront() { + $visibility = $this->plugin->transform([1, "foo\n/bar\rbaz\r\n", []], $this->migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame('request_path', $visibility['request_path']['id']); + $this->assertFalse($visibility['request_path']['negate']); + $this->assertSame("/foo\n/bar\n/baz\n", $visibility['request_path']['pages']); + } + + /** + * @covers ::transform + */ + public function testTransformPhpEnabled() { + $this->moduleHandler->moduleExists('php')->willReturn(TRUE); + $visibility = $this->plugin->transform([2, 'migrateExecutable, $this->row, 'destinationproperty'); + $this->assertSame('php', $visibility['php']['id']); + $this->assertFalse($visibility['php']['negate']); + $this->assertSame('moduleHandler->moduleExists('php')->willReturn(FALSE); + $transformed_value = $this->plugin->transform([2, 'migrateExecutable, $this->row, 'destinationproperty'); + $this->assertEmpty($transformed_value); + } + +} diff --git a/core/modules/block/tests/src/Unit/Plugin/migrate/source/d6/BlockTest.php b/core/modules/block/tests/src/Unit/Plugin/migrate/source/BlockTest.php similarity index 66% rename from core/modules/block/tests/src/Unit/Plugin/migrate/source/d6/BlockTest.php rename to core/modules/block/tests/src/Unit/Plugin/migrate/source/BlockTest.php index f4587beb45d4..881b311a72b7 100644 --- a/core/modules/block/tests/src/Unit/Plugin/migrate/source/d6/BlockTest.php +++ b/core/modules/block/tests/src/Unit/Plugin/migrate/source/BlockTest.php @@ -2,31 +2,27 @@ /** * @file - * Contains \Drupal\Tests\block\Unit\Plugin\migrate\source\d6\BlockTest. + * Contains \Drupal\Tests\block\Unit\Plugin\migrate\source\BlockTest. */ -namespace Drupal\Tests\block\Unit\Plugin\migrate\source\d6; +namespace Drupal\Tests\block\Unit\Plugin\migrate\source; use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase; /** - * Tests D6 block source plugin. + * Tests block source plugin. * - * @coversDefaultClass \Drupal\block\Plugin\migrate\source\d6\Block + * @coversDefaultClass \Drupal\block\Plugin\migrate\source\Block * @group block */ class BlockTest extends MigrateSqlSourceTestCase { - // The plugin system is not working during unit testing so the source plugin - // class needs to be manually specified. - const PLUGIN_CLASS = 'Drupal\block\Plugin\migrate\source\d6\Block'; + const PLUGIN_CLASS = 'Drupal\block\Plugin\migrate\source\Block'; - // The fake Migration configuration entity. protected $migrationConfiguration = array( - // The ID of the entity, can be any string. 'id' => 'test', 'source' => array( - 'plugin' => 'd6_block', + 'plugin' => 'block', ), ); @@ -79,6 +75,20 @@ class BlockTest extends MigrateSqlSourceTestCase { protected function setUp() { $this->databaseContents['blocks'] = $this->expectedResults; $this->databaseContents['blocks_roles'] = $this->expectedBlocksRoles; + $this->databaseContents['system'] = array( + array( + 'filename' => 'modules/system/system.module', + 'name' => 'system', + 'type' => 'module', + 'owner' => '', + 'status' => '1', + 'throttle' => '0', + 'bootstrap' => '0', + 'schema_version' => '6055', + 'weight' => '0', + 'info' => 'a:0:{}', + ) + ); parent::setUp(); } diff --git a/core/modules/migrate_drupal/src/Tests/Table/d6/Blocks.php b/core/modules/migrate_drupal/src/Tests/Table/d6/Blocks.php index ca9d72c1b5ec..16f8f2e00988 100644 --- a/core/modules/migrate_drupal/src/Tests/Table/d6/Blocks.php +++ b/core/modules/migrate_drupal/src/Tests/Table/d6/Blocks.php @@ -130,7 +130,7 @@ class Blocks extends DrupalDumpBase { 'custom' => '0', 'throttle' => '0', 'visibility' => '0', - 'pages' => '', + 'pages' => "\r\nnode/1\nblog/*", 'title' => '', 'cache' => '-1', ))->values(array( @@ -297,8 +297,8 @@ class Blocks extends DrupalDumpBase { 'region' => 'left', 'custom' => '0', 'throttle' => '0', - 'visibility' => '0', - 'pages' => '', + 'visibility' => '2', + 'pages' => " '', 'cache' => '-1', ))->values(array( @@ -403,4 +403,4 @@ class Blocks extends DrupalDumpBase { } } -#aecc8e1067d73824c43bfaf26f9ebf8c +#471b4ac718c0db89c0f48f4051b2583d diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/Block.php b/core/modules/migrate_drupal/src/Tests/Table/d7/Block.php index 09c01099480c..8daee8e3f071 100644 --- a/core/modules/migrate_drupal/src/Tests/Table/d7/Block.php +++ b/core/modules/migrate_drupal/src/Tests/Table/d7/Block.php @@ -689,9 +689,9 @@ class Block extends DrupalDumpBase { 'module' => 'block', 'delta' => '1', 'theme' => 'bartik', - 'status' => '0', + 'status' => '1', 'weight' => '0', - 'region' => '-1', + 'region' => 'highlighted', 'custom' => '0', 'visibility' => '0', 'pages' => '', @@ -714,4 +714,4 @@ class Block extends DrupalDumpBase { } } -#1c70ba712296177505a2e00cfca073eb +#be0543597cafbd2f12cadf1beacb04fc diff --git a/core/modules/migrate_drupal/src/Tests/Table/d7/BlockRole.php b/core/modules/migrate_drupal/src/Tests/Table/d7/BlockRole.php index 55c531cb7da4..21edb22d2745 100644 --- a/core/modules/migrate_drupal/src/Tests/Table/d7/BlockRole.php +++ b/core/modules/migrate_drupal/src/Tests/Table/d7/BlockRole.php @@ -51,8 +51,12 @@ class BlockRole extends DrupalDumpBase { 'delta', 'rid', )) - ->execute(); + ->values(array( + 'module' => 'block', + 'delta' => '1', + 'rid' => '2', + ))->execute(); } } -#3ac5281aec06873398b6cde3ca21d461 +#0280c4568cc18ce4b7e173c046a61a05