123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- <?php
- namespace Drupal\context;
- use Drupal\context\Entity\Context;
- use Drupal\context\Plugin\ContextReaction\Blocks;
- use Drupal\Core\Entity\Query\QueryFactory;
- use Drupal\Core\Entity\EntityManagerInterface;
- use Drupal\Core\Entity\EntityFormBuilderInterface;
- use Drupal\Core\Plugin\ContextAwarePluginInterface;
- use Drupal\Core\Condition\ConditionPluginCollection;
- use Drupal\Component\Plugin\Exception\ContextException;
- use Drupal\Core\Condition\ConditionAccessResolverTrait;
- use Drupal\Core\Plugin\Context\ContextHandlerInterface;
- use Drupal\Core\Plugin\Context\ContextRepositoryInterface;
- use Drupal\Core\StringTranslation\StringTranslationTrait;
- use Drupal\Core\Theme\ThemeManagerInterface;
- /**
- * This is the manager service for the context module and should not be
- * confused with the built in contexts in Drupal.
- */
- class ContextManager {
- use ConditionAccessResolverTrait;
- use StringTranslationTrait;
- /**
- * @var \Drupal\Core\Entity\Query\QueryFactory
- */
- protected $entityQuery;
- /**
- * @var \Drupal\Core\Entity\EntityManagerInterface
- */
- protected $entityManager;
- /**
- * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface
- */
- protected $contextRepository;
- /**
- * @var \Drupal\Core\Plugin\Context\ContextHandlerInterface
- */
- protected $contextHandler;
- /**
- * If the context conditions has been evaluated then this is set to TRUE
- * otherwise FALSE.
- *
- * @var bool
- */
- protected $contextConditionsEvaluated = FALSE;
- /**
- * An array of contexts that have been evaluated and are active.
- *
- * @var array
- */
- protected $activeContexts = [];
- /**
- * @var \Drupal\Core\Entity\EntityFormBuilderInterface
- */
- private $entityFormBuilder;
- /**
- * @var \Drupal\Core\Theme\ThemeManagerInterface;
- */
- protected $themeManager;
- /**
- * Construct.
- *
- * @param QueryFactory $entityQuery
- * The Drupal entity query service.
- *
- * @param EntityManagerInterface $entityManager
- * The Drupal entity manager service.
- *
- * @param ContextRepositoryInterface $contextRepository
- * The drupal context repository service.
- *
- * @param ContextHandlerInterface $contextHandler
- * The Drupal context handler service.
- *
- * @param ThemeManagerInterface $themeManager
- * The Drupal theme manager service.
- *
- * @param \Drupal\Core\Entity\EntityFormBuilderInterface $entityFormBuilder
- */
- function __construct(
- QueryFactory $entityQuery,
- EntityManagerInterface $entityManager,
- ContextRepositoryInterface $contextRepository,
- ContextHandlerInterface $contextHandler,
- EntityFormBuilderInterface $entityFormBuilder,
- ThemeManagerInterface $themeManager
- )
- {
- $this->entityQuery = $entityQuery;
- $this->entityManager = $entityManager;
- $this->contextRepository = $contextRepository;
- $this->contextHandler = $contextHandler;
- $this->entityFormBuilder = $entityFormBuilder;
- $this->themeManager = $themeManager;
- }
- /**
- * Get all contexts.
- *
- * @return Context[]
- */
- public function getContexts() {
- $contextIds = $this->entityQuery
- ->get('context')
- ->execute();
- $contexts = $this->entityManager
- ->getStorage('context')
- ->loadMultiple($contextIds);
- // Sort the contexts by their weight.
- uasort($contexts, [$this, 'sortContextsByWeight']);
- return $contexts;
- }
- /**
- * Get all contexts sorted by their group and sorted by their weight inside
- * of each group.
- *
- * @return array
- */
- public function getContextsByGroup() {
- $contexts = $this->getContexts();
- $groups = [];
- // Add each context to their respective groups.
- foreach ($contexts as $context_id => $context) {
- $group = $context->getGroup();
- if ($group === Context::CONTEXT_GROUP_NONE) {
- $group = 'not_grouped';
- }
- $groups[$group][$context_id] = $context;
- }
- return $groups;
- }
- /**
- * Check to validate that the context name does not already exist.
- *
- * @param string $name
- * The machine name of the context to validate.
- *
- * @return bool
- */
- public function contextExists($name) {
- $entity = $this->entityQuery->get('context')
- ->condition('name', $name)
- ->execute();
- return (bool) $entity;
- }
- /**
- * Check to see if context conditions has been evaluated.
- *
- * @return bool
- */
- public function conditionsHasBeenEvaluated() {
- return $this->contextConditionsEvaluated;
- }
- /**
- * Get the evaluated and active contexts.
- *
- * @return \Drupal\context\ContextInterface[]
- */
- public function getActiveContexts() {
- if ($this->conditionsHasBeenEvaluated()) {
- return $this->activeContexts;
- }
- $this->evaluateContexts();
- return $this->activeContexts;
- }
- /**
- * Evaluate all context conditions.
- */
- public function evaluateContexts() {
- /** @var \Drupal\context\ContextInterface $context */
- foreach ($this->getContexts() as $context) {
- if ($this->evaluateContextConditions($context) && !$context->disabled()) {
- $this->activeContexts[] = $context;
- }
- }
- $this->contextConditionsEvaluated = TRUE;
- }
- /**
- * Get all active reactions or reactions of a certain type.
- *
- * @param string $reactionType
- * Either the reaction class name or the id of the reaction type to get.
- *
- * @return ContextReactionInterface[]
- */
- public function getActiveReactions($reactionType = NULL) {
- $reactions = [];
- foreach ($this->getActiveContexts() as $context) {
- // If no reaction type has been specified then add all reactions and
- // continue to the next context.
- if (is_null($reactionType)) {
- foreach ($context->getReactions() as $reaction) {
- // Only return block reaction if there is a block applied to the current theme.
- if ($reaction instanceof Blocks) {
- $blocks = $reaction->getBlocks();
- $current_theme = $this->getCurrentTheme();
- foreach ($blocks as $block) {
- if ($block->getConfiguration()['theme'] == $current_theme) {
- $reactions[] = $reaction;
- break;
- }
- }
- }
- else {
- $reactions[] = $reaction;
- }
- }
- continue;
- }
- $contextReactions = $context->getReactions();
- // Filter the reactions based on the reaction type.
- foreach ($contextReactions as $reaction) {
- if (class_exists($reactionType) && $reaction instanceof $reactionType) {
- $reactions[] = $reaction;
- continue;
- }
- if ($reaction->getPluginId() === $reactionType) {
- $reactions[] = $reaction;
- continue;
- }
- }
- }
- return $reactions;
- }
- /**
- * Evaluate a contexts conditions.
- *
- * @param ContextInterface $context
- * The context to evaluate conditions for.
- *
- * @return bool
- */
- public function evaluateContextConditions(ContextInterface $context) {
- $conditions = $context->getConditions();
- // Apply context to any context aware conditions.
- $this->applyContexts($conditions);
- // Set the logic to use when validating the conditions.
- $logic = $context->requiresAllConditions()
- ? 'and'
- : 'or';
- // Of there are no conditions then the context will be
- // applied as a site wide context.
- if (!count($conditions)) {
- $logic = 'and';
- }
- return $this->resolveConditions($conditions, $logic);
- }
- /**
- * Apply context to all the context aware conditions in the collection.
- *
- * @param ConditionPluginCollection $conditions
- * A collection of conditions to apply context to.
- *
- * @return bool
- */
- protected function applyContexts(ConditionPluginCollection &$conditions) {
- foreach ($conditions as $condition) {
- if ($condition instanceof ContextAwarePluginInterface) {
- try {
- $contexts = $this->contextRepository->getRuntimeContexts(array_values($condition->getContextMapping()));
- $this->contextHandler->applyContextMapping($condition, $contexts);
- }
- catch (ContextException $e) {
- return FALSE;
- }
- }
- }
- return TRUE;
- }
- /**
- * Get a rendered form for the context.
- * @param \Drupal\context\ContextInterface $context
- * @param string $formType
- * @param array $form_state_additions
- * @return array
- */
- public function getForm(ContextInterface $context, $formType = 'edit', array $form_state_additions = array()) {
- return $this->entityFormBuilder->getForm($context, $formType, $form_state_additions);
- }
- /**
- * Sorts an array of context entities by their weight.
- *
- * Callback for uasort().
- *
- * @param ContextInterface $a
- * First item for comparison.
- *
- * @param ContextInterface $b
- * Second item for comparison.
- *
- * @return int
- * The comparison result for uasort().
- */
- public function sortContextsByWeight(ContextInterface $a, ContextInterface $b) {
- if ($a->getWeight() == $b->getWeight()) {
- return 0;
- }
- return ($a->getWeight() < $b->getWeight()) ? -1 : 1;
- }
- /**
- * Get current active theme.
- *
- * @return string
- * Current active theme name.
- */
- private function getCurrentTheme() {
- return $this->themeManager->getActiveTheme()->getName();
- }
- }
|