You are here

public function BreadcrumbManagerBuilder::build in Breadcrumb Manager 8

Builds the breadcrumb.

Parameters

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

Return value

\Drupal\Core\Breadcrumb\Breadcrumb A breadcrumb.

Overrides PathBasedBreadcrumbBuilder::build

File

src/Breadcrumb/BreadcrumbManagerBuilder.php, line 107

Class

BreadcrumbManagerBuilder
Class BreadcrumbManagerBuilder.

Namespace

Drupal\breadcrumb_manager\Breadcrumb

Code

public function build(RouteMatchInterface $route_match) {
  $breadcrumb = new Breadcrumb();
  $breadcrumb
    ->addCacheContexts([
    'url',
  ]);
  $breadcrumb
    ->addCacheTags([
    'config:breadcrumb_manager.config',
  ]);
  $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',
  ]);

  // 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);

  // Hide current page from breadcrumb if necessary.
  if (!$this->breadcrumbConfig
    ->get('show_current')) {
    array_pop($path_elements);
  }
  $is_first = TRUE;
  while (count($path_elements) > 0) {
    $current_path = '/' . implode('/', $path_elements);
    array_pop($path_elements);

    // Check if we have to show last segment as link.
    $show_as_link = $is_first ? $this->breadcrumbConfig
      ->get('show_current_as_link') : TRUE;
    $is_first = FALSE;

    // Copy the path elements for up-casting.
    $route_request = $this
      ->getRequestForPath($current_path, $this
      ->getExcludedPaths());
    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()) {
        continue;
      }
      $title = FALSE;
      foreach ($this->titleResolvers as $titleResolver) {
        if (!$titleResolver
          ->isActive()) {
          continue;
        }
        $resolved_title = $titleResolver
          ->getTitle($current_path, $route_request, $route_match);
        if (!empty($resolved_title)) {
          $title = $resolved_title;
          break;
        }
      }
      if ($title) {
        $url = $show_as_link ? Url::fromRouteMatch($route_match) : Url::fromRoute('<none>');
        $links[] = new Link($title, $url);
      }
    }
    elseif ($this->breadcrumbConfig
      ->get('show_fake_segments')) {

      // Show fake segments if this option has been selected.
      try {
        $titleResolver = $this->titleResolverManager
          ->createInstance('raw_path_component');

        // We don't really need a valid Request, so creating a simple one
        // will be more than necessary to let the plugin resolving the title.
        $current_request = Request::create($current_path);
        $title = $titleResolver
          ->getTitle($current_path, $current_request, $route_match);
        $url = Url::fromRoute('<none>');

        // Let other modules alter the fake segment.
        $this->moduleHandler
          ->alter('breadcrumb_manager_fake_segments', $current_path, $title, $url);
        $links[] = new Link($title, $url);
      } catch (PluginException $e) {

        // Nothing to do here cause 'raw_path_component' will always exist.
      }
    }
  }

  // Add the Home link if necessary.
  if ($this->breadcrumbConfig
    ->get('show_home')) {
    $home = $this->breadcrumbConfig
      ->get('home') ?: $this
      ->t('Home');
    $links[] = Link::createFromRoute($home, '<front>');
  }
  return $breadcrumb
    ->setLinks(array_reverse($links));
}