$providers */ public function __construct( private iterable $providers, private LoggerInterface $logger, ) {} /** * Generates breadcrumb nodes from a breadcrumb context. * * @param ServerRequestInterface|null $request The current request for module detection * @param BreadcrumbContext|null $context The breadcrumb context containing main entity and suffix nodes * @return BreadcrumbNode[] Array of breadcrumb nodes */ public function getBreadcrumb(?ServerRequestInterface $request, ?BreadcrumbContext $context): array { // Generate nodes from providers (works for both null and non-null context) $nodes = $this->generateNodesFromContext($context, $request); // Append suffix nodes only if context is not null if ($context !== null && $context->hasSuffixNodes()) { foreach ($context->suffixNodes as $suffixNode) { $nodes[] = $suffixNode; } } return $nodes; } /** * Generates breadcrumb nodes from a context using providers. * * @return BreadcrumbNode[] */ private function generateNodesFromContext(?BreadcrumbContext $context, ?ServerRequestInterface $request): array { $provider = $this->findProvider($context); if ($provider === null) { $this->logger->warning( 'No breadcrumb provider found for context', ['context_type' => get_debug_type($context)] ); return []; } try { return $provider->generate($context, $request); } catch (\Exception $e) { $this->logger->error( 'Failed to generate breadcrumb from provider', [ 'provider' => get_class($provider), 'context_type' => get_debug_type($context), 'exception' => $e->getMessage(), ] ); return []; } } /** * Finds the most suitable provider for the given context. * * Providers are checked in priority order (highest first). */ private function findProvider(?BreadcrumbContext $context): ?BreadcrumbProviderInterface { $providers = iterator_to_array($this->providers); // Sort by priority (highest first) usort($providers, static fn($a, $b) => $b->getPriority() <=> $a->getPriority()); foreach ($providers as $provider) { if ($provider->supports($context)) { return $provider; } } return null; } }