From b190c705bc96119b7ce80e20e1ec700d7b8922b0 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Tue, 13 Mar 2018 13:14:24 +0000 Subject: [PATCH] Issue #2409435 by Jo Fitzgerald, phenaproxima, srjosh, edysmp, KarenS, svendecabooter, bdimaggio, hosef, Yogesh Pawar, heddn, quietone, alexpott, larowlan: Upgrade path for Book 6.x and 7.x --- core/modules/book/book.module | 13 ++ ...d6_book_settings.yml => book_settings.yml} | 3 +- core/modules/book/migrations/d6_book.yml | 2 +- core/modules/book/migrations/d7_book.yml | 24 +++ .../book/src/Plugin/migrate/source/Book.php | 63 ++++++++ .../src/Plugin/migrate/source/d6/Book.php | 59 +------- .../Migrate/d6/MigrateBookConfigsTest.php | 22 ++- .../Migrate/d7/MigrateBookConfigsTest.php | 41 +++++ .../src/Kernel/Migrate/d7/MigrateBookTest.php | 69 +++++++++ .../migrate/source/{d6 => }/BookTest.php | 20 ++- .../migrate_drupal/tests/fixtures/drupal7.php | 140 ++++++++++++++++++ .../d7/MigrateUpgrade7ReviewPageTest.php | 2 +- .../src/Functional/d7/MigrateUpgrade7Test.php | 2 +- 13 files changed, 398 insertions(+), 62 deletions(-) rename core/modules/book/migrations/{d6_book_settings.yml => book_settings.yml} (92%) create mode 100644 core/modules/book/migrations/d7_book.yml create mode 100644 core/modules/book/src/Plugin/migrate/source/Book.php create mode 100644 core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookConfigsTest.php create mode 100644 core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookTest.php rename core/modules/book/tests/src/Kernel/Plugin/migrate/source/{d6 => }/BookTest.php (68%) diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 4c62274271db..1b40475c1d25 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -539,3 +539,16 @@ function book_node_type_update(NodeTypeInterface $type) { $config->save(); } } + +/** + * Implements hook_migration_plugins_alter(). + */ +function book_migration_plugins_alter(array &$migrations) { + // Book settings are migrated identically for Drupal 6 and Drupal 7. However, + // a d6_book_settings migration already existed before the consolidated + // book_settings migration existed, so to maintain backwards compatibility, + // ensure that d6_book_settings is an alias of book_settings. + if (isset($migrations['book_settings'])) { + $migrations['d6_book_settings'] = &$migrations['book_settings']; + } +} diff --git a/core/modules/book/migrations/d6_book_settings.yml b/core/modules/book/migrations/book_settings.yml similarity index 92% rename from core/modules/book/migrations/d6_book_settings.yml rename to core/modules/book/migrations/book_settings.yml index 8abfc153debf..d7b93ffc7a8f 100644 --- a/core/modules/book/migrations/d6_book_settings.yml +++ b/core/modules/book/migrations/book_settings.yml @@ -1,7 +1,8 @@ -id: d6_book_settings +id: book_settings label: Book configuration migration_tags: - Drupal 6 + - Drupal 7 - Configuration source: plugin: variable diff --git a/core/modules/book/migrations/d6_book.yml b/core/modules/book/migrations/d6_book.yml index 8964ba0713d5..128dfb9a01ae 100644 --- a/core/modules/book/migrations/d6_book.yml +++ b/core/modules/book/migrations/d6_book.yml @@ -4,7 +4,7 @@ migration_tags: - Drupal 6 - Content source: - plugin: d6_book + plugin: book process: nid: nid 'book/bid': bid diff --git a/core/modules/book/migrations/d7_book.yml b/core/modules/book/migrations/d7_book.yml new file mode 100644 index 000000000000..30d8c72b574d --- /dev/null +++ b/core/modules/book/migrations/d7_book.yml @@ -0,0 +1,24 @@ +id: d7_book +label: Books +migration_tags: + - Drupal 7 + - Content +source: + plugin: book +process: + nid: nid + 'book/bid': bid + 'book/weight': weight + 'book/pid': + - + plugin: skip_on_empty + method: process + source: plid + - + plugin: migration_lookup + migration: d7_book +destination: + plugin: book +migration_dependencies: + required: + - d7_node diff --git a/core/modules/book/src/Plugin/migrate/source/Book.php b/core/modules/book/src/Plugin/migrate/source/Book.php new file mode 100644 index 000000000000..08977fbc83e2 --- /dev/null +++ b/core/modules/book/src/Plugin/migrate/source/Book.php @@ -0,0 +1,63 @@ +<?php + +namespace Drupal\book\Plugin\migrate\source; + +use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; + +/** + * Drupal 6 and 7 book source. + * + * @MigrateSource( + * id = "book", + * source_module = "book", + * ) + */ +class Book extends DrupalSqlBase { + + /** + * {@inheritdoc} + */ + public function query() { + $query = $this->select('book', 'b')->fields('b', ['nid', 'bid']); + $query->join('menu_links', 'ml', 'b.mlid = ml.mlid'); + $ml_fields = ['mlid', 'plid', 'weight', 'has_children', 'depth']; + foreach (range(1, 9) as $i) { + $field = "p$i"; + $ml_fields[] = $field; + $query->orderBy('ml.' . $field); + } + return $query->fields('ml', $ml_fields); + } + + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['mlid']['type'] = 'integer'; + $ids['mlid']['alias'] = 'ml'; + return $ids; + } + + /** + * {@inheritdoc} + */ + public function fields() { + return [ + 'nid' => $this->t('Node ID'), + 'bid' => $this->t('Book ID'), + 'mlid' => $this->t('Menu link ID'), + 'plid' => $this->t('Parent link ID'), + 'weight' => $this->t('Weight'), + 'p1' => $this->t('The first mlid in the materialized path. If N = depth, then pN must equal the mlid. If depth > 1 then p(N-1) must equal the parent link mlid. All pX where X > depth must equal zero. The columns p1 .. p9 are also called the parents.'), + 'p2' => $this->t('The second mlid in the materialized path. See p1.'), + 'p3' => $this->t('The third mlid in the materialized path. See p1.'), + 'p4' => $this->t('The fourth mlid in the materialized path. See p1.'), + 'p5' => $this->t('The fifth mlid in the materialized path. See p1.'), + 'p6' => $this->t('The sixth mlid in the materialized path. See p1.'), + 'p7' => $this->t('The seventh mlid in the materialized path. See p1.'), + 'p8' => $this->t('The eighth mlid in the materialized path. See p1.'), + 'p9' => $this->t('The ninth mlid in the materialized path. See p1.'), + ]; + } + +} diff --git a/core/modules/book/src/Plugin/migrate/source/d6/Book.php b/core/modules/book/src/Plugin/migrate/source/d6/Book.php index 87ae972140fd..58b6effb08d6 100644 --- a/core/modules/book/src/Plugin/migrate/source/d6/Book.php +++ b/core/modules/book/src/Plugin/migrate/source/d6/Book.php @@ -2,7 +2,9 @@ namespace Drupal\book\Plugin\migrate\source\d6; -use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase; +use Drupal\book\Plugin\migrate\source\Book as BookGeneral; + +@trigger_error('Book is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.x. Use \Drupal\book\Plugin\migrate\source\Book instead. See https://www.drupal.org/node/2947487 for more information.', E_USER_DEPRECATED); /** * Drupal 6 book source. @@ -11,54 +13,9 @@ * id = "d6_book", * source_module = "book" * ) + * + * @deprecated in Drupal 8.6.x, to be removed before Drupal 9.0.x. Use + * \Drupal\book\Plugin\migrate\source\Book instead. See + * https://www.drupal.org/node/2947487 for more information. */ -class Book extends DrupalSqlBase { - - /** - * {@inheritdoc} - */ - public function query() { - $query = $this->select('book', 'b')->fields('b', ['nid', 'bid']); - $query->join('menu_links', 'ml', 'b.mlid = ml.mlid'); - $ml_fields = ['mlid', 'plid', 'weight', 'has_children', 'depth']; - for ($i = 1; $i <= 9; $i++) { - $field = "p$i"; - $ml_fields[] = $field; - $query->orderBy('ml.' . $field); - } - $query->fields('ml', $ml_fields); - return $query; - } - - /** - * {@inheritdoc} - */ - public function getIds() { - $ids['mlid']['type'] = 'integer'; - $ids['mlid']['alias'] = 'ml'; - return $ids; - } - - /** - * {@inheritdoc} - */ - public function fields() { - return [ - 'nid' => $this->t('Node ID'), - 'bid' => $this->t('Book ID'), - 'mlid' => $this->t('Menu link ID'), - 'plid' => $this->t('Parent link ID'), - 'weight' => $this->t('Weight'), - 'p1' => $this->t('The first mlid in the materialized path. If N = depth, then pN must equal the mlid. If depth > 1 then p(N-1) must equal the parent link mlid. All pX where X > depth must equal zero. The columns p1 .. p9 are also called the parents.'), - 'p2' => $this->t('The second mlid in the materialized path. See p1.'), - 'p3' => $this->t('The third mlid in the materialized path. See p1.'), - 'p4' => $this->t('The fourth mlid in the materialized path. See p1.'), - 'p5' => $this->t('The fifth mlid in the materialized path. See p1.'), - 'p6' => $this->t('The sixth mlid in the materialized path. See p1.'), - 'p7' => $this->t('The seventh mlid in the materialized path. See p1.'), - 'p8' => $this->t('The eighth mlid in the materialized path. See p1.'), - 'p9' => $this->t('The ninth mlid in the materialized path. See p1.'), - ]; - } - -} +class Book extends BookGeneral {} diff --git a/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookConfigsTest.php b/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookConfigsTest.php index becf87d3c9e3..7498638455a5 100644 --- a/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookConfigsTest.php +++ b/core/modules/book/tests/src/Kernel/Migrate/d6/MigrateBookConfigsTest.php @@ -20,17 +20,29 @@ class MigrateBookConfigsTest extends MigrateDrupal6TestBase { public static $modules = ['book']; /** - * {@inheritdoc} + * Data provider for testBookSettings(). + * + * @return array + * The data for each test scenario. */ - protected function setUp() { - parent::setUp(); - $this->executeMigration('d6_book_settings'); + public function providerBookSettings() { + return [ + // d6_book_settings was renamed to book_settings, but use the old alias to + // prove that it works. + // @see book_migration_plugins_alter() + ['d6_book_settings'], + ['book_settings'], + ]; } /** * Tests migration of book variables to book.settings.yml. + * + * @dataProvider providerBookSettings */ - public function testBookSettings() { + public function testBookSettings($migration_id) { + $this->executeMigration($migration_id); + $config = $this->config('book.settings'); $this->assertIdentical('book', $config->get('child_type')); $this->assertSame('book pages', $config->get('block.navigation.mode')); diff --git a/core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookConfigsTest.php b/core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookConfigsTest.php new file mode 100644 index 000000000000..a5504c9104c2 --- /dev/null +++ b/core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookConfigsTest.php @@ -0,0 +1,41 @@ +<?php + +namespace Drupal\Tests\book\Kernel\Migrate\d7; + +use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; +use Drupal\Tests\SchemaCheckTestTrait; + +/** + * Tests the migration of Book settings. + * + * @group migrate_drupal_7 + */ +class MigrateBookConfigsTest extends MigrateDrupal7TestBase { + + use SchemaCheckTestTrait; + + /** + * {@inheritdoc} + */ + public static $modules = ['book', 'node']; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->executeMigration('book_settings'); + } + + /** + * Tests migration of book variables to book.settings.yml. + */ + public function testBookSettings() { + $config = $this->config('book.settings'); + $this->assertSame('book', $config->get('child_type')); + $this->assertSame('all pages', $config->get('block.navigation.mode')); + $this->assertSame(['book'], $config->get('allowed_types')); + $this->assertConfigSchema(\Drupal::service('config.typed'), 'book.settings', $config->get()); + } + +} diff --git a/core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookTest.php b/core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookTest.php new file mode 100644 index 000000000000..e8505212dc80 --- /dev/null +++ b/core/modules/book/tests/src/Kernel/Migrate/d7/MigrateBookTest.php @@ -0,0 +1,69 @@ +<?php + +namespace Drupal\Tests\book\Kernel\Migrate\d7; + +use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; +use Drupal\node\Entity\Node; + +/** + * Tests migration of book structures from Drupal 7. + * + * @group migrate_drupal_7 + */ +class MigrateBookTest extends MigrateDrupal7TestBase { + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'book', + 'menu_ui', + 'node', + 'taxonomy', + 'text', + ]; + + /** + * {@inheritdoc} + */ + protected function setUp() { + parent::setUp(); + $this->installEntitySchema('node'); + $this->installEntitySchema('taxonomy_term'); + $this->installConfig(['node']); + $this->installSchema('book', ['book']); + $this->installSchema('node', ['node_access']); + $this->executeMigrations([ + 'd7_user_role', + 'd7_user', + 'd7_node_type', + 'd7_node', + 'd7_book' + ]); + } + + /** + * Tests the Drupal 7 book structure to Drupal 8 migration. + */ + public function testBook() { + $nodes = Node::loadMultiple([1, 2, 4, 6]); + $this->assertSame('8', $nodes[1]->book['bid']); + $this->assertSame('6', $nodes[1]->book['pid']); + + $this->assertSame('4', $nodes[2]->book['bid']); + $this->assertSame('6', $nodes[2]->book['pid']); + + $this->assertSame('4', $nodes[4]->book['bid']); + $this->assertSame('0', $nodes[4]->book['pid']); + + $this->assertSame('4', $nodes[6]->book['bid']); + $this->assertSame('4', $nodes[6]->book['pid']); + + $tree = \Drupal::service('book.manager')->bookTreeAllData(4); + $this->assertSame('4', $tree['49990 is - The thing about Firefly 4']['link']['nid']); + $this->assertSame('6', $tree['49990 is - The thing about Firefly 4']['below']['50000 Comments are closed :-( 6']['link']['nid']); + $this->assertSame('2', $tree['49990 is - The thing about Firefly 4']['below']['50000 Comments are closed :-( 6']['below']['50000 The thing about Deep Space 9 2']['link']['nid']); + $this->assertSame([], $tree['49990 is - The thing about Firefly 4']['below']['50000 Comments are closed :-( 6']['below']['50000 The thing about Deep Space 9 2']['below']); + } + +} diff --git a/core/modules/book/tests/src/Kernel/Plugin/migrate/source/d6/BookTest.php b/core/modules/book/tests/src/Kernel/Plugin/migrate/source/BookTest.php similarity index 68% rename from core/modules/book/tests/src/Kernel/Plugin/migrate/source/d6/BookTest.php rename to core/modules/book/tests/src/Kernel/Plugin/migrate/source/BookTest.php index 25d0906a36c1..02594742591f 100644 --- a/core/modules/book/tests/src/Kernel/Plugin/migrate/source/d6/BookTest.php +++ b/core/modules/book/tests/src/Kernel/Plugin/migrate/source/BookTest.php @@ -1,12 +1,14 @@ <?php -namespace Drupal\Tests\book\Kernel\Plugin\migrate\source\d6; +namespace Drupal\Tests\book\Kernel\Plugin\migrate\source; use Drupal\Tests\migrate\Kernel\MigrateSqlSourceTestBase; +use Drupal\book\Plugin\migrate\source\d6\Book as D6Book; /** - * @covers \Drupal\book\Plugin\migrate\source\d6\Book + * @covers \Drupal\book\Plugin\migrate\source\Book * @group book + * @group legacy */ class BookTest extends MigrateSqlSourceTestBase { @@ -81,4 +83,18 @@ public function providerSource() { return $tests; } + /** + * @expectedDeprecation Book is deprecated in Drupal 8.6.x and will be removed before Drupal 9.0.x. Use \Drupal\book\Plugin\migrate\source\Book instead. See https://www.drupal.org/node/2947487 for more information. + */ + public function testDeprecatedPlugin() { + new D6Book( + [], + 'd6_book', + [], + $this->prophesize('Drupal\migrate\Plugin\MigrationInterface')->reveal(), + $this->prophesize('Drupal\Core\State\StateInterface')->reveal(), + $this->prophesize('Drupal\Core\Entity\EntityManagerInterface')->reveal() + ); + } + } diff --git a/core/modules/migrate_drupal/tests/fixtures/drupal7.php b/core/modules/migrate_drupal/tests/fixtures/drupal7.php index 27eb713ae11d..e3f025a72b35 100644 --- a/core/modules/migrate_drupal/tests/fixtures/drupal7.php +++ b/core/modules/migrate_drupal/tests/fixtures/drupal7.php @@ -1906,6 +1906,34 @@ 'mysql_character_set' => 'utf8', )); +$connection->insert('book') + ->fields(array( + 'mlid', + 'nid', + 'bid', + )) + ->values(array( + 'mlid' => '480', + 'nid' => '4', + 'bid' => '4', + )) + ->values(array( + 'mlid' => '481', + 'nid' => '6', + 'bid' => '4', + )) + ->values(array( + 'mlid' => '482', + 'nid' => '2', + 'bid' => '4', + )) + ->values(array( + 'mlid' => '483', + 'nid' => '1', + 'bid' => '8', + )) + ->execute(); + $connection->schema()->createTable('cache', array( 'fields' => array( 'cid' => array( @@ -22957,6 +22985,114 @@ 'p9' => '0', 'updated' => '0', )) + ->values(array( + 'menu_name' => 'book-toc-1', + 'mlid' => '480', + 'plid' => '0', + 'link_path' => 'node/4', + 'router_path' => 'node/%', + 'link_title' => 'Test top book title', + 'options' => 'a:0:{}', + 'module' => 'book', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '1', + 'expanded' => '0', + 'weight' => '-10', + 'depth' => '1', + 'customized' => '0', + 'p1' => '480', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + )) + ->values(array( + 'menu_name' => 'book-toc-1', + 'mlid' => '481', + 'plid' => '480', + 'link_path' => 'node/6', + 'router_path' => 'node/%', + 'link_title' => 'Test book title child 1', + 'options' => 'a:0:{}', + 'module' => 'book', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '1', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '2', + 'customized' => '0', + 'p1' => '480', + 'p2' => '481', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + )) + ->values(array( + 'menu_name' => 'book-toc-1', + 'mlid' => '482', + 'plid' => '481', + 'link_path' => 'node/2', + 'router_path' => 'node/%', + 'link_title' => 'Test book title child 1.1', + 'options' => 'a:0:{}', + 'module' => 'book', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '3', + 'customized' => '0', + 'p1' => '480', + 'p2' => '481', + 'p3' => '482', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + )) + ->values(array( + 'menu_name' => 'book-toc-2', + 'mlid' => '483', + 'plid' => '481', + 'link_path' => 'node/1', + 'router_path' => 'node/%', + 'link_title' => 'Test book title 2', + 'options' => 'a:0:{}', + 'module' => 'book', + 'hidden' => '0', + 'external' => '0', + 'has_children' => '0', + 'expanded' => '0', + 'weight' => '0', + 'depth' => '3', + 'customized' => '0', + 'p1' => '480', + 'p2' => '481', + 'p3' => '483', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + )) ->execute(); $connection->schema()->createTable('menu_router', array( @@ -46324,6 +46460,10 @@ 'name' => 'book_allowed_types', 'value' => 'a:1:{i:0;s:4:"book";}', )) +->values(array( + 'name' => 'book_block_mode', + 'value' => 's:9:"all pages";', +)) ->values(array( 'name' => 'book_child_type', 'value' => 's:4:"book";', diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php index b8ea52b43f7f..be048f952503 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php @@ -34,6 +34,7 @@ protected function getAvailablePaths() { return [ 'aggregator', 'block', + 'book', 'comment', 'contact', 'date', @@ -115,7 +116,6 @@ protected function getAvailablePaths() { */ protected function getMissingPaths() { return [ - 'book', 'color', 'rdf', 'views', diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php index 385a4e58040a..49e793cecbdc 100644 --- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php +++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php @@ -118,6 +118,7 @@ protected function getAvailablePaths() { return [ 'aggregator', 'block', + 'book', 'comment', 'contact', 'date', @@ -169,7 +170,6 @@ protected function getAvailablePaths() { */ protected function getMissingPaths() { return [ - 'book', 'color', 'rdf', // These modules are in the missing path list because they are installed -- GitLab