Skip to content
Snippets Groups Projects
Verified Commit 78bbe4db 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
parent e6b0b85e
No related branches found
No related tags found
12 merge requests!11197Issue #3506427 by eduardo morales alberti: Remove responsive_image.ajax from hook,!11131[10.4.x-only-DO-NOT-MERGE]: Issue ##2842525 Ajax attached to Views exposed filter form does not trigger callbacks,!10786Issue #3490579 by shalini_jha, mstrelan: Add void return to all views...,!5423Draft: Resolve #3329907 "Test2",!3878Removed unused condition head title for views,!3818Issue #2140179: $entity->original gets stale between updates,!3478Issue #3337882: Deleted menus are not removed from content type config,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!2062Issue #3246454: Add weekly granularity to views date sort,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation
Pipeline #377351 passed with warnings
Pipeline: drupal

#377358

    ......@@ -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