You are here

class ThemeSwitcherNegotiator in Theme Switcher Rules 8

Negotiate the current theme based on theme_switcher_rules rules.

Hierarchy

Expanded class hierarchy of ThemeSwitcherNegotiator

1 string reference to 'ThemeSwitcherNegotiator'
theme_switcher.services.yml in ./theme_switcher.services.yml
theme_switcher.services.yml
1 service uses ThemeSwitcherNegotiator
theme.negotiator.theme_switcher_negotiator in ./theme_switcher.services.yml
Drupal\theme_switcher\Theme\ThemeSwitcherNegotiator

File

src/Theme/ThemeSwitcherNegotiator.php, line 19

Namespace

Drupal\theme_switcher\Theme
View source
class ThemeSwitcherNegotiator implements ThemeNegotiatorInterface {
  use ConditionAccessResolverTrait;

  /**
   * The route admin context to determine whether a route is an admin one.
   *
   * @var \Drupal\Core\Routing\AdminContext
   */
  protected $adminContext;

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The plugin context handler.
   *
   * @var \Drupal\Core\Plugin\Context\ContextHandlerInterface
   */
  protected $contextHandler;

  /**
   * The context manager service.
   *
   * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
   */
  protected $contextRepository;

  /**
   * The theme to be applied.
   *
   * @var string
   */
  private $theme;

  /**
   * ThemeSwitcherNegotiator constructor.
   *
   * @param \Drupal\Core\Routing\AdminContext $admin_context
   *   The route admin context service.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Plugin\Context\ContextHandlerInterface $context_handler
   *   The ContextHandler for applying contexts to conditions properly.
   * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository
   *   The lazy context repository service.
   */
  public function __construct(AdminContext $admin_context, EntityTypeManagerInterface $entity_type_manager, ContextHandlerInterface $context_handler, ContextRepositoryInterface $context_repository) {
    $this->adminContext = $admin_context;
    $this->entityTypeManager = $entity_type_manager;
    $this->contextHandler = $context_handler;
    $this->contextRepository = $context_repository;
  }

  /**
   * {@inheritdoc}
   */
  public function applies(RouteMatchInterface $route_match) {
    $storage = $this->entityTypeManager
      ->getStorage('theme_switcher_rule');
    $configEntities = $storage
      ->getQuery()
      ->sort('weight', 'ASC')
      ->execute();
    $rules = $storage
      ->loadMultiple($configEntities);
    foreach ($rules as $rule) {

      /** @var \Drupal\theme_switcher\Entity\ThemeSwitcherRule $rule */

      // Check whether the rule is enabled and one of the themes is set.
      if ($rule
        ->status() && (!empty($rule
        ->getTheme()) || !empty($rule
        ->getAdminTheme()))) {
        $conditions = [];
        foreach ($rule
          ->getVisibilityConditions() as $condition_id => $condition) {
          if ($condition instanceof ContextAwarePluginInterface) {
            try {
              $contexts = $this->contextRepository
                ->getRuntimeContexts(array_values($condition
                ->getContextMapping()));
              $this->contextHandler
                ->applyContextMapping($condition, $contexts);
            } 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.
              return FALSE;
            }
          }
          $conditions[$condition_id] = $condition;
        }

        // Check whether the conditions are resolved positively.
        if ($this
          ->resolveConditions($conditions, 'and') !== FALSE) {

          // Are we in a admin route?
          $route = $route_match
            ->getRouteObject();
          $is_admin_route = $this->adminContext
            ->isAdminRoute($route);
          $this->theme = !$is_admin_route ? $rule
            ->getTheme() : $rule
            ->getAdminTheme();
          return !empty($this->theme) ? TRUE : FALSE;
        }
      }
    }
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function determineActiveTheme(RouteMatchInterface $route_match) {
    return $this->theme;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ConditionAccessResolverTrait::resolveConditions protected function Resolves the given conditions based on the condition logic ('and'/'or').
ThemeSwitcherNegotiator::$adminContext protected property The route admin context to determine whether a route is an admin one.
ThemeSwitcherNegotiator::$contextHandler protected property The plugin context handler.
ThemeSwitcherNegotiator::$contextRepository protected property The context manager service.
ThemeSwitcherNegotiator::$entityTypeManager protected property The entity type manager.
ThemeSwitcherNegotiator::$theme private property The theme to be applied.
ThemeSwitcherNegotiator::applies public function Whether this theme negotiator should be used to set the theme. Overrides ThemeNegotiatorInterface::applies
ThemeSwitcherNegotiator::determineActiveTheme public function Determine the active theme for the request. Overrides ThemeNegotiatorInterface::determineActiveTheme
ThemeSwitcherNegotiator::__construct public function ThemeSwitcherNegotiator constructor.