Skip to content
Snippets Groups Projects
Verified Commit 677bd5a1 authored by Lee Rowlands's avatar Lee Rowlands
Browse files

Issue #3482691 by james.williams, arunkumark, kristiaanvandeneynde,...

Issue #3482691 by james.williams, arunkumark, kristiaanvandeneynde, smustgrave: BreadcrumbManager ignores cacheability when no builders apply

(cherry picked from commit 78bbe4db)
parent 6f4f3a88
Branches
Tags
21 merge requests!12227Issue #3181946 by jonmcl, mglaman,!12079Issue #3523476 by matthiasm11: Add empty check on operator,!12024Fix: DocBlock comment for return value of Drupal\Core\Database\Connection::transactionManager(),!11974Draft: Issue #3495165 by catch, joeyroth, berdir, texas-bronius: Better warning...,!11934Issue #3520997: DefaultLazyPluginCollection unnecessarily instantiates plugins when sorting collection,!11887Issue #3520065: The migrate Row class API is incomplete,!11636Draft: Issue #3515643 by macsim: fieldNameExists method is inconsistent,!11515Issue #3480419 by mondrake, smustgrave, catch: Method...,!11380Issue #3490698 by catch, spokje: Bump MINIMUM_STABILITY back to 'stable' when...,!11281Use Drupal Core Leadership terminology in MAINTAINERS.txt,!11239Issue #3507548: Allow workspace changes listing to show all items, without a pager,!11238Fix issue #3051797,!11213Issue #3506743 by tomislav.matokovic: Increasing the color contrast for the navigation block title against the background of the navigation sidebar to at least 4.5:1,!11147Draft: Try to avoid manually setting required cache contexts,!11108Issue #3490298 by nicxvan: Profiles can be missed in OOP hooks,!11093Drupal on MongoDB 11.1.x,!11017Issue #3502540: Add date filter for moderated content.,!11009Issue #3486972 migrate feed icon,!10999Cleaning up Taxonomy hooks and updating baseline.,!10977Issue #3501457: Fix path used in a A11y Test Admin,!10881Issue #3489329 by mfb, casey: symfony/http-foundation commit 32310ff breaks PathValidator
Pipeline #377353 canceled
Pipeline: drupal

#377354

    ......@@ -83,16 +83,18 @@ public function build(RouteMatchInterface $route_match) {
    }
    $breadcrumb = $builder->build($route_match);
    if ($breadcrumb instanceof Breadcrumb) {
    $context['builder'] = $builder;
    $breadcrumb->addCacheableDependency($cacheable_metadata);
    break;
    }
    else {
    throw new \UnexpectedValueException('Invalid breadcrumb returned by ' . get_class($builder) . '::build().');
    }
    }
    // Ensure all collected cacheability is applied.
    $breadcrumb->addCacheableDependency($cacheable_metadata);
    // Allow modules to alter the breadcrumb.
    $this->moduleHandler->alter('system_breadcrumb', $breadcrumb, $route_match, $context);
    ......
    ......@@ -577,3 +577,11 @@ menu_test.breadcrumb3:
    _title: 'Normal title'
    requirements:
    _access: 'TRUE'
    menu_test.skippable-breadcrumb:
    path: '/menu-test/skippable-breadcrumb'
    defaults:
    _controller: '\Drupal\menu_test\Controller\MenuTestController::menuTestCallback'
    _title: 'Normal title'
    requirements:
    _access: 'TRUE'
    <?php
    declare(strict_types=1);
    namespace Drupal\menu_test;
    use Drupal\Core\DependencyInjection\ContainerBuilder;
    use Drupal\Core\DependencyInjection\ServiceModifierInterface;
    use Symfony\Component\DependencyInjection\Reference;
    /**
    * Decorate core's default path-based breadcrumb builder when it is available.
    */
    class MenuTestServiceProvider implements ServiceModifierInterface {
    /**
    * {@inheritdoc}
    */
    public function alter(ContainerBuilder $container): void {
    if ($container->has('system.breadcrumb.default')) {
    $container->register('menu_test.breadcrumb.default', SkippablePathBasedBreadcrumbBuilder::class)
    ->setDecoratedService('system.breadcrumb.default')
    ->addArgument(new Reference('menu_test.breadcrumb.default.inner'))
    ->addArgument(new Reference('request_stack'));
    }
    }
    }
    <?php
    declare(strict_types=1);
    namespace Drupal\menu_test;
    use Drupal\Core\Breadcrumb\Breadcrumb;
    use Drupal\Core\Breadcrumb\BreadcrumbBuilderInterface;
    use Drupal\Core\Cache\CacheableMetadata;
    use Drupal\Core\Routing\RouteMatchInterface;
    use Symfony\Component\HttpFoundation\RequestStack;
    /**
    * A path-based breadcrumb builder can be skipped from applying.
    */
    class SkippablePathBasedBreadcrumbBuilder implements BreadcrumbBuilderInterface {
    public function __construct(
    protected BreadcrumbBuilderInterface $pathBasedBreadcrumbBuilder,
    protected RequestStack $requestStack,
    ) {}
    /**
    * {@inheritdoc}
    */
    public function applies(RouteMatchInterface $route_match, ?CacheableMetadata $cacheable_metadata = NULL): bool {
    $query_arg = 'menu_test_skip_breadcrumbs';
    $cacheable_metadata?->addCacheContexts(['url.query_args:' . $query_arg]);
    // Apply unless the query argument is present.
    return !$this->requestStack->getCurrentRequest()->query->has($query_arg);
    }
    /**
    * {@inheritdoc}
    */
    public function build(RouteMatchInterface $route_match): Breadcrumb {
    return $this->pathBasedBreadcrumbBuilder->build($route_match);
    }
    }
    ......@@ -388,6 +388,15 @@ public function testBreadCrumbs(): void {
    $this->drupalGet('menu-test/breadcrumb1/breadcrumb2/breadcrumb3');
    $this->assertSession()->responseContains('<script>alert(12);</script>');
    $this->assertSession()->assertEscaped('<script>alert(123);</script>');
    // Assert that the breadcrumb cacheability is respected after not applying.
    $this->assertBreadcrumb(Url::fromRoute('menu_test.skippable-breadcrumb', [], [
    'query' => [
    'menu_test_skip_breadcrumbs' => 'yes',
    ],
    ]), []);
    $trail = $home + ['menu-test' => 'Menu test root'];
    $this->assertBreadcrumb(Url::fromRoute('menu_test.skippable-breadcrumb'), $trail);
    }
    /**
    ......
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment