visibility conditions are incorrectly combined - if one condition isn't applicable, no other conditions are considered

Created on 6 May 2025, 7 months ago

Problem/Motivation

The module's admin UI presents multiple conditions with the option to OR them. However, the code doesn't correctly carry this out, as it treats a missing context value the same as a context exception, and in both cases bails on the entire rule.

Steps to reproduce

1. Set up a rule with the following OR'ed conditions:
-- a particular node type
-- a particular path which is node a node, e.g. a view
2. Go to the path for the view.
3. The rule fails to apply.

Proposed resolution

The problem is this code:

            catch (MissingValueContextException | ContextException $e) {
              // MissingValueContextException: If any context is missing then
              // we might be missing cacheable metadata, and don't know based
              // on what conditions the block is accessible or not. Make sure
              // the result cannot be cached.
              //
              // ContextException: The contexts exist but have no value. Deny
              // access without disabling caching. For example the node type
              // condition will have a missing context on any non-node route
              // like the frontpage.
              continue 2;
            }

because the current path is not a node, a MissingValueContextException is thrown. The code bails on the whole rule, when instead the rule should be valid because another condition passes.

Compare with core's BlockAccessControlHandler, which treats two separate cases:

          try {
            $contexts = $this->contextRepository->getRuntimeContexts(array_values($condition->getContextMapping()));
            $this->contextHandler->applyContextMapping($condition, $contexts);
          }
          catch (MissingValueContextException $e) {
            $missing_value = TRUE;
          }
          catch (ContextException $e) {
            $missing_context = TRUE;
          }

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Active

Version

2.1

Component

Code

Created by

πŸ‡¬πŸ‡§United Kingdom joachim

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @joachim
  • πŸ‡ΊπŸ‡ΈUnited States fizcs3 Omaha, Nebraska; USA

    I'm confirming that I am also seeing an issue when the OR conjunction operator is chosen ("OR: at least one of the conditions should pass.").

    In our case, we've set two conditions, similar to above. For Request Path we've entered a url, and for Content Type we've chosen just one content type. It actually then mistakenly invokes the theme switcher themes for ALL pages. Not just if one of those two conditions passes. So, it seems to always pass, not always fail like mentioned above (?)...
    I peeked at the other conditions, which I didn't change, wondering if one of those is automatically always true, but don't think so...
    in the meantime, the AND conjunction operator appears to work fine, and have been trying to stick to using that.

    Am on Drupal 10.4.8, PHP 8.3.24, and theme_switcher 2.1.0.

Production build 0.71.5 2024