diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php index 060f1b1..dc10261 100644 --- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php +++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php @@ -15,6 +15,7 @@ use Drupal\Core\Routing\RequestContext; use Drupal\Core\Routing\RouteMatch; use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; @@ -59,13 +60,6 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { protected $pathProcessor; /** - * Site config object. - * - * @var \Drupal\Core\Config\Config - */ - protected $config; - - /** * The title resolver. * * @var \Drupal\Core\Controller\TitleResolverInterface @@ -80,6 +74,20 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { protected $currentUser; /** + * The site config object. + * + * @var \Drupal\Core\Config\Config + */ + protected $config; + + /** + * The URL generator. + * + * @var \Drupal\Core\Routing\UrlGeneratorInterface + */ + protected $urlGenerator; + + /** * Constructs the PathBasedBreadcrumbBuilder. * * @param \Drupal\Core\Routing\RequestContext $context @@ -91,7 +99,9 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { * @param \Drupal\Core\PathProcessor\InboundPathProcessorInterface $path_processor * The inbound path processor. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory - * The config factory service. + * The config factory. + * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator + * The URL generator. * @param \Drupal\Core\Controller\TitleResolverInterface $title_resolver * The title resolver service. * @param \Drupal\Core\Session\AccountInterface $current_user @@ -99,12 +109,13 @@ class PathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface { * @param \Drupal\Core\Path\CurrentPathStack $current_path * The current path. */ - public function __construct(RequestContext $context, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactoryInterface $config_factory, TitleResolverInterface $title_resolver, AccountInterface $current_user, CurrentPathStack $current_path) { + public function __construct(RequestContext $context, AccessManagerInterface $access_manager, RequestMatcherInterface $router, InboundPathProcessorInterface $path_processor, ConfigFactoryInterface $config_factory, UrlGeneratorInterface $url_generator, TitleResolverInterface $title_resolver, AccountInterface $current_user, CurrentPathStack $current_path) { $this->context = $context; $this->accessManager = $access_manager; $this->router = $router; $this->pathProcessor = $path_processor; $this->config = $config_factory->get('system.site'); + $this->urlGenerator = $url_generator; $this->titleResolver = $title_resolver; $this->currentUser = $current_user; $this->currentPath = $current_path; @@ -130,7 +141,10 @@ public function build(RouteMatchInterface $route_match) { $path = trim($this->context->getPathInfo(), '/'); $path_elements = explode('/', $path); $exclude = array(); - // Don't show a link to the front-page path. + // Don't show a link to the front-page path. This may either be the literal + // front page path as configured, or a path with a langauge prefix. + $front = $this->urlGenerator->generateFromRoute('', [], [], TRUE)->getGeneratedUrl(); + $exclude[$front] = TRUE; $front = $this->config->get('page.front'); $exclude[$front] = TRUE; // /user is just a redirect, so skip it. diff --git a/core/modules/system/system.services.yml b/core/modules/system/system.services.yml index c70889d..211fc59 100644 --- a/core/modules/system/system.services.yml +++ b/core/modules/system/system.services.yml @@ -12,7 +12,7 @@ services: arguments: ['@module_handler', '@entity.manager', '@request_stack', '@menu.link_tree', '@menu.active_trail'] system.breadcrumb.default: class: Drupal\system\PathBasedBreadcrumbBuilder - arguments: ['@router.request_context', '@access_manager', '@router', '@path_processor_manager', '@config.factory', '@title_resolver', '@current_user', '@path.current'] + arguments: ['@router.request_context', '@access_manager', '@router', '@path_processor_manager', '@config.factory', '@url_generator', '@title_resolver', '@current_user', '@path.current'] tags: - { name: breadcrumb_builder, priority: 0 } path_processor.files: diff --git a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php index 29f0cea..67a44bf 100644 --- a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php +++ b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php @@ -9,8 +9,10 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Cache\Cache; +use Drupal\Core\GeneratedUrl; use Drupal\Core\Link; use Drupal\Core\Access\AccessResultAllowed; +use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Url; use Drupal\Core\Utility\LinkGeneratorInterface; @@ -85,6 +87,13 @@ class PathBasedBreadcrumbBuilderTest extends UnitTestCase { protected $currentPath; /** + * The mocked URL generator. + * + * @var \Drupal\Core\Routing\UrlGeneratorInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $urlGenerator; + + /** * {@inheritdoc} * * @covers ::__construct @@ -95,6 +104,11 @@ protected function setUp() { $this->requestMatcher = $this->getMock('\Symfony\Component\Routing\Matcher\RequestMatcherInterface'); $config_factory = $this->getConfigFactoryStub(array('system.site' => array('front' => 'test_frontpage'))); + $this->urlGenerator = $this->getMock(UrlGeneratorInterface::class); + $this->urlGenerator->expects($this->any()) + ->method('generateFromRoute') + ->with('') + ->willReturn((new GeneratedUrl())->setGeneratedUrl('/test_frontpage')); $this->pathProcessor = $this->getMock('\Drupal\Core\PathProcessor\InboundPathProcessorInterface'); $this->context = $this->getMock('\Drupal\Core\Routing\RequestContext'); @@ -112,6 +126,7 @@ protected function setUp() { $this->requestMatcher, $this->pathProcessor, $config_factory, + $this->urlGenerator, $this->titleResolver, $this->currentUser, $this->currentPath