diff --git a/core/lib/Drupal/Core/Path/PathValidator.php b/core/lib/Drupal/Core/Path/PathValidator.php index e6ebf5d4ef5..51cdc2fd6f4 100644 --- a/core/lib/Drupal/Core/Path/PathValidator.php +++ b/core/lib/Drupal/Core/Path/PathValidator.php @@ -82,6 +82,20 @@ class PathValidator implements PathValidatorInterface { * {@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 +118,7 @@ class PathValidator implements PathValidatorInterface { $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 +137,15 @@ class PathValidator implements PathValidatorInterface { * 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 e0bcf0415b9..a600207cc4d 100644 --- a/core/lib/Drupal/Core/Path/PathValidatorInterface.php +++ b/core/lib/Drupal/Core/Path/PathValidatorInterface.php @@ -23,6 +23,20 @@ interface PathValidatorInterface { */ public function getUrlIfValid($path); + /** + * Returns an URL object, if the path is valid. + * + * Unlike getUrlIfValid(), access check is not performed. Do not use this + * method if the $path is about to be presented to a user. + * + * @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. * diff --git a/core/modules/migrate/src/Plugin/migrate/process/Route.php b/core/modules/migrate/src/Plugin/migrate/process/Route.php new file mode 100644 index 00000000000..1e76def1fd8 --- /dev/null +++ b/core/modules/migrate/src/Plugin/migrate/process/Route.php @@ -0,0 +1,93 @@ +migration = $migration; + $this->pathValidator = $pathValidator; + } + + /** + * {@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('path.validator') + ); + } + /** + * {@inheritdoc} + * + * Set the destination route information based on the source link_path. + */ + public function transform($value, MigrateExecutable $migrate_executable, Row $row, $destination_property) { + list($link_path, $options) = $value; + $extracted = $this->pathValidator->getUrlIfValidWithoutAccessCheck($link_path); + $route = array(); + + if ($extracted) { + if ($extracted->isExternal()) { + $route['route_name'] = null; + $route['route_parameters'] = array(); + $route['options'] = $options; + $route['url'] = $extracted->getUri(); + } + else { + $route['route_name'] = $extracted->getRouteName(); + $route['route_parameters'] = $extracted->getRouteParameters(); + $route['options'] = $extracted->getOptions(); + + if (isset($options['query'])) { + // If the querystring is stored as a string (as in D6), convert it + // into an array. + if (is_string($options['query'])) { + parse_str($options['query'], $old_query); + } + else { + $old_query = $options['query']; + } + $options['query'] = $route['options']['query'] + $old_query; + unset($route['options']['query']); + } + $route['options'] = $route['options'] + $options; + $route['url'] = null; + } + } + + return $route; + } + +} + 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 00000000000..1cafbe90222 --- /dev/null +++ b/core/modules/migrate_drupal/config/install/migrate.migration.d6_menu_links.yml @@ -0,0 +1,50 @@ +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: + plugin: route + source: + - link_path + - options + route_name: @route/route_name + route_parameters: @route/route_parameters + url: @route/url + options: @route/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 fe65db235a6..e28173fc0ce 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 00000000000..4711477d3c4 --- /dev/null +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/MenuLink.php @@ -0,0 +1,110 @@ +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.'), + ); + } + + /** + * {@inheritdoc} + */ + 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 00000000000..57bcdb41293 --- /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:2:{s:5:"query";s:7:"foo=bar";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 e8e34455a0a..4dd02c41f74 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 @@ class MigrateDrupal6Test extends MigrateFullDrupalTestBase { $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 @@ class MigrateDrupal6Test extends MigrateFullDrupalTestBase { __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 00000000000..495f4876ab4 --- /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(), null); + $this->assertIdentical($menu_link->isEnabled(), TRUE); + $this->assertIdentical($menu_link->isExpanded(), FALSE); + $this->assertIdentical(serialize($menu_link->getOptions()), 'a:2:{s:5:"query";a:0:{}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(), null); + $this->assertIdentical($menu_link->isEnabled(), TRUE); + $this->assertIdentical($menu_link->isExpanded(), TRUE); + $this->assertIdentical(serialize($menu_link->getOptions()), 'a:2:{s:5:"query";a:1:{s:3:"foo";s:3:"bar";}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 00000000000..3b12f3c23a3 --- /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; + } +} diff --git a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php index 0722680847e..0e2471c7de8 100644 --- a/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php +++ b/core/tests/Drupal/Tests/Core/Path/PathValidatorTest.php @@ -329,5 +329,31 @@ class PathValidatorTest extends UnitTestCase { $this->assertEquals('berg', $url->getOptions()['fragment']); } + /** + * Tests the getUrlIfValidWithoutAccessCheck() method. + * + * @covers ::getUrlIfValidWithoutAccessCheck + */ + public function testGetUrlIfValidWithoutAccessCheck() { + $this->account->expects($this->never()) + ->method('hasPermission') + ->with('link to any page'); + $this->accessAwareRouter->expects($this->never()) + ->method('match'); + $this->accessUnawareRouter->expects($this->once()) + ->method('match') + ->with('/test-path') + ->willReturn([RouteObjectInterface::ROUTE_NAME => 'test_route', '_raw_variables' => new ParameterBag(['key' => 'value'])]); + $this->pathProcessor->expects($this->once()) + ->method('processInbound') + ->willReturnArgument(0); + + $url = $this->pathValidator->getUrlIfValidWithoutAccessCheck('test-path'); + $this->assertInstanceOf('Drupal\Core\Url', $url); + + $this->assertEquals('test_route', $url->getRouteName()); + $this->assertEquals(['key' => 'value'], $url->getRouteParameters()); + } + }