Chris@0: entityTypeManager = $entity_type_manager; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { Chris@0: return new static( Chris@0: $configuration, Chris@0: $plugin_id, Chris@0: $plugin_definition, Chris@0: $container->get('entity_type.manager') Chris@0: ); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getCacheMaxAge() { Chris@0: // The calculation of which URL (if any) gets put on which tour depends Chris@0: // on a route access check. This can have a lot of inputs, including user Chris@0: // permissions and other factors. Rather than doing a complicated Chris@0: // accounting of the cache metadata for all of these possible factors, set Chris@0: // the max age of the cache to zero to prevent using incorrect cached Chris@0: // information. Chris@0: return 0; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function listTopics() { Chris@0: /** @var \Drupal\tour\TourInterface[] $tours */ Chris@0: $tours = $this->entityTypeManager->getStorage('tour')->loadMultiple(); Chris@0: // Sort in the manner defined by Tour. Chris@0: uasort($tours, ['Drupal\tour\Entity\Tour', 'sort']); Chris@0: Chris@0: // Make a link to each tour, using the first of its routes that can Chris@0: // be linked to by this user, if any. Chris@0: $topics = []; Chris@0: foreach ($tours as $tour) { Chris@0: $title = $tour->label(); Chris@0: $id = $tour->id(); Chris@0: $routes = $tour->getRoutes(); Chris@0: $made_link = FALSE; Chris@0: foreach ($routes as $route) { Chris@0: // Some tours are for routes with parameters. For instance, there is Chris@0: // currently a tour in the Language module for the language edit page, Chris@0: // which appears on all pages with URLs like: Chris@0: // /admin/config/regional/language/edit/LANGCODE. Chris@0: // There is no way to make a link to the page that displays the tour, Chris@0: // because it is a set of pages. The easiest way to detect this is to Chris@0: // use a try/catch exception -- try to make a link, and it will error Chris@0: // out with a missing parameter exception if the route leads to a set Chris@0: // of pages instead of a single page. Chris@0: try { Chris@0: $params = isset($route['route_params']) ? $route['route_params'] : []; Chris@0: $url = Url::fromRoute($route['route_name'], $params); Chris@0: // Skip this route if the current user cannot access it. Chris@0: if (!$url->access()) { Chris@0: continue; Chris@0: } Chris@0: Chris@0: // Generate the link HTML directly, using toString(), to catch Chris@0: // missing parameter exceptions now instead of at render time. Chris@0: $topics[$id] = Link::fromTextAndUrl($title, $url)->toString(); Chris@0: // If the line above didn't generate an exception, we have a good Chris@0: // link that the user can access. Chris@0: $made_link = TRUE; Chris@0: break; Chris@0: } Chris@0: catch (\Exception $e) { Chris@0: // Exceptions are normally due to routes that need parameters. If Chris@0: // there is an exception, just try the next route and see if we can Chris@0: // find one that will work for us. Chris@0: } Chris@0: } Chris@0: if (!$made_link) { Chris@0: // None of the routes worked to make a link, so at least display the Chris@0: // tour title. Chris@0: $topics[$id] = $title; Chris@0: } Chris@0: } Chris@0: Chris@0: return $topics; Chris@0: } Chris@0: Chris@0: }