You are here

public function PathBasedBreadcrumbBuilder::build in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/system/src/PathBasedBreadcrumbBuilder.php \Drupal\system\PathBasedBreadcrumbBuilder::build()

Builds the breadcrumb.

Parameters

\Drupal\Core\Routing\RouteMatchInterface $route_match: The current route match.

Return value

\Drupal\Core\Breadcrumb\Breadcrumb A breadcrumb.

Overrides BreadcrumbBuilderInterface::build

File

core/modules/system/src/PathBasedBreadcrumbBuilder.php, line 141

Class

PathBasedBreadcrumbBuilder
Class to define the menu_link breadcrumb builder.

Namespace

Drupal\system

Code

public function build(RouteMatchInterface $route_match) {
  $breadcrumb = new Breadcrumb();
  $links = [];

  // Add the url.path.parent cache context. This code ignores the last path
  // part so the result only depends on the path parents.
  $breadcrumb
    ->addCacheContexts([
    'url.path.parent',
    'url.path.is_front',
  ]);

  // Do not display a breadcrumb on the frontpage.
  if ($this->pathMatcher
    ->isFrontPage()) {
    return $breadcrumb;
  }

  // General path-based breadcrumbs. Use the actual request path, prior to
  // resolving path aliases, so the breadcrumb can be defined by simply
  // creating a hierarchy of path aliases.
  $path = trim($this->context
    ->getPathInfo(), '/');
  $path_elements = explode('/', $path);
  $exclude = [];

  // Don't show a link to the front-page path.
  $front = $this->config
    ->get('page.front');
  $exclude[$front] = TRUE;

  // /user is just a redirect, so skip it.
  // @todo Find a better way to deal with /user.
  $exclude['/user'] = TRUE;
  while (count($path_elements) > 1) {
    array_pop($path_elements);

    // Copy the path elements for up-casting.
    $route_request = $this
      ->getRequestForPath('/' . implode('/', $path_elements), $exclude);
    if ($route_request) {
      $route_match = RouteMatch::createFromRequest($route_request);
      $access = $this->accessManager
        ->check($route_match, $this->currentUser, NULL, TRUE);

      // The set of breadcrumb links depends on the access result, so merge
      // the access result's cacheability metadata.
      $breadcrumb = $breadcrumb
        ->addCacheableDependency($access);
      if ($access
        ->isAllowed()) {
        $title = $this->titleResolver
          ->getTitle($route_request, $route_match
          ->getRouteObject());
        if (!isset($title)) {

          // Fallback to using the raw path component as the title if the
          // route is missing a _title or _title_callback attribute.
          $title = str_replace([
            '-',
            '_',
          ], ' ', Unicode::ucfirst(end($path_elements)));
        }
        $url = Url::fromRouteMatch($route_match);
        $links[] = new Link($title, $url);
      }
    }
  }

  // Add the Home link.
  $links[] = Link::createFromRoute($this
    ->t('Home'), '<front>');
  return $breadcrumb
    ->setLinks(array_reverse($links));
}