diff --git a/core/lib/Drupal/Core/Path/PathValidator.php b/core/lib/Drupal/Core/Path/PathValidator.php index e6ebf5d..6f5a28d 100644 --- a/core/lib/Drupal/Core/Path/PathValidator.php +++ b/core/lib/Drupal/Core/Path/PathValidator.php @@ -81,7 +81,28 @@ public function isValid($path) { /** * {@inheritdoc} */ + public function isValidWithoutAccessCheck($path) { + return (bool) $this->getUrlIfValidWithoutAccessCheck($path); + } + + /** + * {@inheritdoc} + */ public function getUrlIfValid($path) { + return $this->getUrl($path, TRUE); + } + + /** + * {@inheritdoc} + */ + public function getUrlIfValidWithoutAccessCheck($path) { + return $this->getUrl($path, FALSE); + } + + /** + * Helper for getUrlIfValid() and getUrlIfValidWithoutAccessCheck(). + */ + protected function getUrl($path, $access_check) { $parsed_url = UrlHelper::parse($path); $options = []; @@ -104,7 +125,7 @@ public function getUrlIfValid($path) { $path = ltrim($path, '/'); $request = Request::create('/' . $path); - $attributes = $this->getPathAttributes($path, $request); + $attributes = $this->getPathAttributes($path, $request, $access_check); if (!$attributes) { return FALSE; @@ -123,12 +144,15 @@ public function getUrlIfValid($path) { * The path to check. * @param \Symfony\Component\HttpFoundation\Request $request * A request object with the given path. + * @param bool $access_check + * If FALSE then skip access check and check only whether the path is + * valid. * * @return array|bool * An array of request attributes of FALSE if an exception was thrown. */ - protected function getPathAttributes($path, Request $request) { - if ($this->account->hasPermission('link to any page')) { + protected function getPathAttributes($path, Request $request, $access_check) { + if (!$access_check || $this->account->hasPermission('link to any page')) { $router = $this->accessUnawareRouter; } else { diff --git a/core/lib/Drupal/Core/Path/PathValidatorInterface.php b/core/lib/Drupal/Core/Path/PathValidatorInterface.php index e0bcf04..311b644 100644 --- a/core/lib/Drupal/Core/Path/PathValidatorInterface.php +++ b/core/lib/Drupal/Core/Path/PathValidatorInterface.php @@ -24,6 +24,19 @@ public function getUrlIfValid($path); /** + * Returns an URL object, if the path is valid. + * + * Unlike getUrlIfValid(), access check is not performed. + * + * @param string $path + * The path to check. + * + * @return \Drupal\Core\Url|false + * The url object, or FALSE if the path is not valid. + */ + public function getUrlIfValidWithoutAccessCheck($path); + + /** * Checks if the URL path is valid and accessible by the current user. * * @param string $path @@ -34,4 +47,17 @@ public function getUrlIfValid($path); */ public function isValid($path); + /** + * Checks if the URL path is valid. + * + * Unlike isValid(), access check is not performed. + * + * @param string $path + * The path to check. + * + * @return bool + * TRUE if the path is valid. + */ + public function isValidWithoutAccessCheck($path); + } diff --git a/core/modules/migrate/src/Plugin/migrate/process/RouteName.php b/core/modules/migrate/src/Plugin/migrate/process/RouteName.php new file mode 100644 index 0000000..26ea9e1 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/RouteName.php @@ -0,0 +1,53 @@ +getPathValidator()->getUrlIfValidWithoutAccessCheck($value); + + if ($extracted) { + if (!$extracted->isExternal()) { + return $extracted->getRouteName(); + } + } + + return null; + } + + /** + * @return \Drupal\Core\Path\PathValidatorInterface + */ + protected function getPathValidator() { + if (!isset($this->pathValidator)) { + $this->pathValidator = \Drupal::service('path.validator'); + } + return $this->pathValidator; + } + +} + diff --git a/core/modules/migrate/src/Plugin/migrate/process/RouteParameters.php b/core/modules/migrate/src/Plugin/migrate/process/RouteParameters.php new file mode 100644 index 0000000..21005d8 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/RouteParameters.php @@ -0,0 +1,53 @@ +getPathValidator()->getUrlIfValidWithoutAccessCheck($value); + + if ($extracted) { + if (!$extracted->isExternal()) { + return $extracted->getRouteParameters(); + } + } + + return array(); + } + + /** + * @return \Drupal\Core\Path\PathValidatorInterface + */ + protected function getPathValidator() { + if (!isset($this->pathValidator)) { + $this->pathValidator = \Drupal::service('path.validator'); + } + return $this->pathValidator; + } + +} + diff --git a/core/modules/migrate_drupal/config/install/migrate.migration.d6_menu_links.yml b/core/modules/migrate_drupal/config/install/migrate.migration.d6_menu_links.yml new file mode 100644 index 0000000..e6b76ba --- /dev/null +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_menu_links.yml @@ -0,0 +1,49 @@ +id: d6_menu_links +label: Drupal 6 menu links +migration_groups: + - Drupal 6 +source: + plugin: d6_menu_link + constants: + bundle: menu_link_content +process: + id: mlid + bundle: 'constants/bundle' + title: link_title + description: + plugin: extract + source: + - options + index: + - 0 + - attributes + - title + menu_name: + plugin: migration + migration: d6_menu + source: menu_name + route_name: + plugin: route_name + source: link_path + route_parameters: + plugin: route_parameters + source: link_path + url: link_path + options: options + external: external + weight: weight + expanded: expanded + enabled: enabled + parent: + - + plugin: skip_process_on_empty + source: plid + - + plugin: migration + migration: d6_menu_links + changed: updated +destination: + plugin: entity:menu_link_content +migration_dependencies: + required: + - d6_menu diff --git a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml index fe65db2..e28173f 100644 --- a/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml +++ b/core/modules/migrate_drupal/config/schema/migrate_drupal.source.schema.yml @@ -64,6 +64,14 @@ migrate.source.d6_comment_entity_form_display_subject: type: migrate_entity_constant label: 'Constants' +migrate.source.d6_menu_link: + type: migrate_source_sql + label: 'Drupal 6 menu link' + mapping: + constants: + type: migrate_entity_constant + label: 'Constants' + migrate.source.d6_box: type: migrate_source_sql label: 'Drupal 6 box' diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/MenuLink.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/MenuLink.php new file mode 100644 index 0000000..a442d6b --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/MenuLink.php @@ -0,0 +1,107 @@ +select('menu_links', 'ml') + ->fields('ml', array( + 'menu_name', + 'mlid', + 'plid', + 'link_path', + 'router_path', + 'link_title', + 'options', + 'module', + 'hidden', + 'external', + 'has_children', + 'expanded', + 'weight', + 'depth', + 'customized', + 'p1', + 'p2', + 'p3', + 'p4', + 'p5', + 'p6', + 'p7', + 'p8', + 'p9', + 'updated' + )) + ->condition('module', 'menu') + ->condition('customized', 1); + return $query; + } + + /** + * {@inheritdoc} + */ + public function fields() { + return array( + 'menu_name' => t("The menu name. All links with the same menu name (such as 'navigation') are part of the same menu."), + 'mlid' => t('The menu link ID (mlid) is the integer primary key.'), + 'plid' => t('The parent link ID (plid) is the mlid of the link above in the hierarchy, or zero if the link is at the top level in its menu.'), + 'link_path' => t('The Drupal path or external path this link points to.'), + 'router_path' => t('For links corresponding to a Drupal path (external = 0), this connects the link to a {menu_router}.path for joins.'), + 'link_title' => t('The text displayed for the link, which may be modified by a title callback stored in {menu_router}.'), + 'options' => t('A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.'), + 'module' => t('The name of the module that generated this link.'), + 'hidden' => t('A flag for whether the link should be rendered in menus. (1 = a disabled menu item that may be shown on admin screens, -1 = a menu callback, 0 = a normal, visible link)'), + 'external' => t('A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).'), + 'has_children' => t('Flag indicating whether any links have this link as a parent (1 = children exist, 0 = no children).'), + 'expanded' => t('Flag for whether this link should be rendered as expanded in menus - expanded links always have their child links displayed, instead of only when the link is in the active trail (1 = expanded, 0 = not expanded)'), + 'weight' => t('Link weight among links in the same menu at the same depth.'), + 'depth' => t('The depth relative to the top level. A link with plid == 0 will have depth == 1.'), + 'customized' => t('A flag to indicate that the user has manually created or edited the link (1 = customized, 0 = not customized).'), + 'p1' => 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 plid. All pX where X > depth must equal zero. The columns p1 .. p9 are also called the parents.'), + 'p2' => t('The second mlid in the materialized path. See p1.'), + 'p3' => t('The third mlid in the materialized path. See p1.'), + 'p4' => t('The fourth mlid in the materialized path. See p1.'), + 'p5' => t('The fifth mlid in the materialized path. See p1.'), + 'p6' => t('The sixth mlid in the materialized path. See p1.'), + 'p7' => t('The seventh mlid in the materialized path. See p1.'), + 'p8' => t('The eighth mlid in the materialized path. See p1.'), + 'p9' => t('The ninth mlid in the materialized path. See p1.'), + 'updated' => t('Flag that indicates that this link was generated during the update from Drupal 5.'), + ); + } + + public function prepareRow(Row $row) { + $row->setSourceProperty('options', unserialize($row->getSourceProperty('options'))); + $row->setSourceProperty('enabled', !$row->getSourceProperty('hidden')); + + return parent::prepareRow($row); + } + + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['mlid']['type'] = 'integer'; + return $ids; + } + +} diff --git a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6MenuLink.php b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6MenuLink.php new file mode 100644 index 0000000..0205aa6 --- /dev/null +++ b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6MenuLink.php @@ -0,0 +1,289 @@ +createTable('menu_links', array( + 'description' => 'Contains the individual links within a menu.', + 'fields' => array( + 'menu_name' => array( + 'description' => "The menu name. All links with the same menu name (such as 'navigation') are part of the same menu.", + 'type' => 'varchar', + 'length' => 32, + 'not null' => TRUE, + 'default' => ''), + 'mlid' => array( + 'description' => 'The menu link ID (mlid) is the integer primary key.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE), + 'plid' => array( + 'description' => 'The parent link ID (plid) is the mlid of the link above in the hierarchy, or zero if the link is at the top level in its menu.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'link_path' => array( + 'description' => 'The Drupal path or external path this link points to.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => ''), + 'router_path' => array( + 'description' => 'For links corresponding to a Drupal path (external = 0), this connects the link to a {menu_router}.path for joins.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => ''), + 'link_title' => array( + 'description' => 'The text displayed for the link, which may be modified by a title callback stored in {menu_router}.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => ''), + 'options' => array( + 'description' => 'A serialized array of options to be passed to the url() or l() function, such as a query string or HTML attributes.', + 'type' => 'text', + 'not null' => FALSE), + 'module' => array( + 'description' => 'The name of the module that generated this link.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => 'system'), + 'hidden' => array( + 'description' => 'A flag for whether the link should be rendered in menus. (1 = a disabled menu item that may be shown on admin screens, -1 = a menu callback, 0 = a normal, visible link)', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small'), + 'external' => array( + 'description' => 'A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small'), + 'has_children' => array( + 'description' => 'Flag indicating whether any links have this link as a parent (1 = children exist, 0 = no children).', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small'), + 'expanded' => array( + 'description' => 'Flag for whether this link should be rendered as expanded in menus - expanded links always have their child links displayed, instead of only when the link is in the active trail (1 = expanded, 0 = not expanded)', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small'), + 'weight' => array( + 'description' => 'Link weight among links in the same menu at the same depth.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0), + 'depth' => array( + 'description' => 'The depth relative to the top level. A link with plid == 0 will have depth == 1.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small'), + 'customized' => array( + 'description' => 'A flag to indicate that the user has manually created or edited the link (1 = customized, 0 = not customized).', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small'), + 'p1' => array( + 'description' => '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 plid. All pX where X > depth must equal zero. The columns p1 .. p9 are also called the parents.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p2' => array( + 'description' => 'The second mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p3' => array( + 'description' => 'The third mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p4' => array( + 'description' => 'The fourth mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p5' => array( + 'description' => 'The fifth mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p6' => array( + 'description' => 'The sixth mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p7' => array( + 'description' => 'The seventh mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p8' => array( + 'description' => 'The eighth mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'p9' => array( + 'description' => 'The ninth mlid in the materialized path. See p1.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0), + 'updated' => array( + 'description' => 'Flag that indicates that this link was generated during the update from Drupal 5.', + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'size' => 'small'), + ), + 'indexes' => array( + 'path_menu' => array(array('link_path', 128), 'menu_name'), + 'menu_plid_expand_child' => array( + 'menu_name', 'plid', 'expanded', 'has_children'), + 'menu_parents' => array( + 'menu_name', 'p1', 'p2', 'p3', 'p4', 'p5', 'p6', 'p7', 'p8', 'p9'), + 'router_path' => array(array('router_path', 128)), + ), + 'primary key' => array('mlid'), + )); + $this->database->insert('menu_links')->fields(array( + 'menu_name', + 'mlid', + 'plid', + 'link_path', + 'router_path', + 'link_title', + 'options', + 'module', + 'hidden', + 'external', + 'has_children', + 'expanded', + 'weight', + 'depth', + 'customized', + 'p1', + 'p2', + 'p3', + 'p4', + 'p5', + 'p6', + 'p7', + 'p8', + 'p9', + 'updated', + )) + ->values(array( + 'menu_name' => 'secondary-links', + 'mlid' => 138, + 'plid' => 0, + 'link_path' => 'user/login', + 'router_path' => 'user/login', + 'link_title' => 'Test 1', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:16:"Test menu link 1";}}', + 'module' => 'menu', + 'hidden' => 0, + 'external' => 0, + 'has_children' => 1, + 'expanded' => 0, + 'weight' => 15, + 'depth' => 1, + 'customized' => 1, + 'p1' => '138', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + )) + ->values(array( + 'menu_name' => 'secondary-links', + 'mlid' => 139, + 'plid' => 138, + 'link_path' => 'admin', + 'router_path' => 'admin', + 'link_title' => 'Test 2', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:16:"Test menu link 2";}}', + 'module' => 'menu', + 'hidden' => 0, + 'external' => 0, + 'has_children' => 0, + 'expanded' => 1, + 'weight' => 12, + 'depth' => 2, + 'customized' => 1, + 'p1' => '138', + 'p2' => '139', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + )) + ->values(array( + 'menu_name' => 'secondary-links', + 'mlid' => 140, + 'plid' => 0, + 'link_path' => 'http://drupal.org', + 'router_path' => '', + 'link_title' => 'Drupal.org', + 'options' => 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:0:"";}}', + 'module' => 'menu', + 'hidden' => 0, + 'external' => 1, + 'has_children' => 0, + 'expanded' => 0, + 'weight' => 0, + 'depth' => 1, + 'customized' => 1, + 'p1' => '0', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + )) + ->execute(); + } +} diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php index e8e3445..4dd02c4 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateDrupal6Test.php @@ -87,6 +87,7 @@ class MigrateDrupal6Test extends MigrateFullDrupalTestBase { 'd6_locale_settings', 'd6_menu_settings', 'd6_menu', + 'd6_menu_links', 'd6_node_revision', 'd6_node', 'd6_node_settings', @@ -176,6 +177,7 @@ protected function getDumps() { $tests_path . '/Drupal6ForumSettings.php', $tests_path . '/Drupal6LocaleSettings.php', $tests_path . '/Drupal6Menu.php', + $tests_path . '/Drupal6MenuLink.php', $tests_path . '/Drupal6MenuSettings.php', $tests_path . '/Drupal6NodeBodyInstance.php', $tests_path . '/Drupal6Node.php', @@ -253,6 +255,7 @@ protected function getTestClassesList() { __NAMESPACE__ . '\MigrateForumConfigsTest', __NAMESPACE__ . '\MigrateLocaleConfigsTest', __NAMESPACE__ . '\MigrateMenuConfigsTest', + __NAMESPACE__ . '\MigrateMenuLinkTest', __NAMESPACE__ . '\MigrateMenuTest', __NAMESPACE__ . '\MigrateNodeConfigsTest', __NAMESPACE__ . '\MigrateNodeRevisionTest', diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateMenuLinkTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateMenuLinkTest.php new file mode 100644 index 0000000..4b1b2cf --- /dev/null +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateMenuLinkTest.php @@ -0,0 +1,90 @@ + 'secondary-links')); + $menu->enforceIsNew(TRUE); + $menu->save(); + + $this->prepareMigrations(array( + 'd6_menu' => array( + array(array('secondary-links'), array('secondary-links')), + ), + )); + + $migration = entity_load('migration', 'd6_menu_links'); + $dumps = array( + $this->getDumpDirectory() . '/Drupal6MenuLink.php', + ); + $this->prepare($migration, $dumps); + $executable = new MigrateExecutable($migration, $this); + $executable->import(); + } + + public function testMenuLinks() { + $menu_link = entity_load('menu_link_content', 138); + $this->assertIdentical($menu_link->getTitle(), 'Test 1'); + $this->assertIdentical($menu_link->getMenuName(), 'secondary-links'); + $this->assertIdentical($menu_link->getDescription(), 'Test menu link 1'); + $this->assertIdentical($menu_link->getURL(), 'user/login'); + $this->assertIdentical($menu_link->isEnabled(), TRUE); + $this->assertIdentical($menu_link->isExpanded(), FALSE); + $this->assertIdentical(serialize($menu_link->getOptions()), 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:16:"Test menu link 1";}}'); + $this->assertIdentical($menu_link->getRouteName(), 'user.login'); + $this->assertIdentical($menu_link->getRouteParameters(), array()); + $this->assertIdentical($menu_link->getWeight(), 15); + + $menu_link = entity_load('menu_link_content', 139); + $this->assertIdentical($menu_link->getTitle(), 'Test 2'); + $this->assertIdentical($menu_link->getMenuName(), 'secondary-links'); + $this->assertIdentical($menu_link->getDescription(), 'Test menu link 2'); + $this->assertIdentical($menu_link->getURL(), 'admin'); + $this->assertIdentical($menu_link->isEnabled(), TRUE); + $this->assertIdentical($menu_link->isExpanded(), TRUE); + $this->assertIdentical(serialize($menu_link->getOptions()), 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:16:"Test menu link 2";}}'); + $this->assertIdentical($menu_link->getRouteName(), 'system.admin'); + $this->assertIdentical($menu_link->getRouteParameters(), array()); + $this->assertIdentical($menu_link->getWeight(), 12); + + $menu_link = entity_load('menu_link_content', 140); + $this->assertIdentical($menu_link->getTitle(), 'Drupal.org'); + $this->assertIdentical($menu_link->getMenuName(), 'secondary-links'); + $this->assertIdentical($menu_link->getDescription(), ''); + $this->assertIdentical($menu_link->getURL(), 'http://drupal.org'); + $this->assertIdentical($menu_link->isEnabled(), TRUE); + $this->assertIdentical($menu_link->isExpanded(), FALSE); + $this->assertIdentical(serialize($menu_link->getOptions()), 'a:1:{s:10:"attributes";a:1:{s:5:"title";s:0:"";}}'); + $this->assertIdentical($menu_link->getRouteName(), NULL); + $this->assertIdentical($menu_link->getRouteParameters(), array()); + $this->assertIdentical($menu_link->getWeight(), 0); + } + +} diff --git a/core/modules/migrate_drupal/tests/src/Unit/source/d6/MenuLinkSourceTest.php b/core/modules/migrate_drupal/tests/src/Unit/source/d6/MenuLinkSourceTest.php new file mode 100644 index 0000000..3b12f3c --- /dev/null +++ b/core/modules/migrate_drupal/tests/src/Unit/source/d6/MenuLinkSourceTest.php @@ -0,0 +1,133 @@ + 'mlid', + // Leave it empty for now. + 'idlist' => array(), + // This needs to be the identifier of the actual key: cid for comment, nid + // for node and so on. + 'source' => array( + 'plugin' => 'drupal6_menu_link', + ), + 'sourceIds' => array( + 'mlid' => array( + // This is where the field schema would go but for now we need to + // specify the table alias for the key. Most likely this will be the + // same as BASE_ALIAS. + 'alias' => 'ml', + ), + ), + 'destinationIds' => array( + 'mlid' => array( + // This is where the field schema would go. + ), + ), + ); + + protected $expectedResults = array( + array( + 'menu_name' => 'menu-test-menu', + 'mlid' => 138, + 'plid' => 0, + 'link_path' => 'admin', + 'router_path' => 'admin', + 'link_title' => 'Test 1', + 'options' => array('attributes' => array('title' => 'Test menu link 1')), + 'module' => 'menu', + 'hidden' => 0, + 'external' => 0, + 'has_children' => 1, + 'expanded' => 0, + 'weight' => 15, + 'depth' => 1, + 'customized' => 1, + 'p1' => '138', + 'p2' => '0', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + ), + array( + 'menu_name' => 'menu-test-menu', + 'mlid' => 139, + 'plid' => 138, + 'link_path' => 'admin/modules', + 'router_path' => 'admin/modules', + 'link_title' => 'Test 2', + 'options' => array('attributes' => array('title' => 'Test menu link 2')), + 'module' => 'menu', + 'hidden' => 0, + 'external' => 0, + 'has_children' => 0, + 'expanded' => 0, + 'weight' => 12, + 'depth' => 2, + 'customized' => 1, + 'p1' => '138', + 'p2' => '139', + 'p3' => '0', + 'p4' => '0', + 'p5' => '0', + 'p6' => '0', + 'p7' => '0', + 'p8' => '0', + 'p9' => '0', + 'updated' => '0', + ), + ); + + /** + * {@inheritdoc} + */ + public function setUp() { + // This array stores the database. + foreach ($this->expectedResults as $k => $row) { + $this->databaseContents['menu_links'][$k] = $row; + $this->databaseContents['menu_links'][$k]['options'] = serialize($this->databaseContents['menu_links'][$k]['options']); + } + parent::setUp(); + } + +} + +namespace Drupal\Tests\migrate_drupal\Unit\source\d6; + +use Drupal\Core\Database\Connection; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\migrate_drupal\Plugin\migrate\source\d6\MenuLink; + +class TestMenuLink extends MenuLink { + public function setDatabase(Connection $database) { + $this->database = $database; + } + public function setModuleHandler(ModuleHandlerInterface $module_handler) { + $this->moduleHandler = $module_handler; + } +}