Loading context_stack.tokens.inc +19 −4 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ */ use Drupal\context_stack\ContextStackRepository; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Render\BubbleableMetadata; /** Loading Loading @@ -67,17 +68,18 @@ function context_stack_tokens($type, $tokens, array $data, array $options, Bubbl // Cannot proceeed without further parts. continue; } if ($purpose === 'account' && reset($parts) !== 'user') { if ($purpose === 'account' && !in_array(reset($parts), ['user', 'entity'])) { $chained_token_type = $entity_type_id = 'user'; } else { $chained_token_type = $entity_type_id = array_shift($parts); _context_stack_map_token_type($chained_token_type, $entity_type_id); } if (!is_string($entity_type_id) || !is_string($chained_token_type) || empty($parts)) { if (!is_string($chained_token_type) || empty($parts)) { continue; } $context_id = '@' . $service_ids[$type] . ':' . $purpose . '.' . $entity_type_id; $id = is_string($entity_type_id) ? $entity_type_id : $chained_token_type; $context_id = '@' . $service_ids[$type] . ':' . $purpose . '.' . $id; /** @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository */ $context_repository = \Drupal::service('context.repository'); $contexts = $context_repository->getRuntimeContexts([$context_id]); Loading @@ -91,9 +93,22 @@ function context_stack_tokens($type, $tokens, array $data, array $options, Bubbl } continue; } $value = $context->getContextValue(); if (!is_string($entity_type_id)) { // Last chance to get the correct token type. if ($value instanceof EntityInterface) { $chained_token_type = $entity_type_id = $value->getEntityTypeId(); } else { $type_parts = explode(':', $context->getContextData()->getDataDefinition()->getDataType()); $chained_token_type = end($type_parts); } _context_stack_map_token_type($chained_token_type, $entity_type_id); } $bubbleable_metadata->addCacheableDependency($context); $chained_token = implode(':', $parts); $replacements += \Drupal::token()->generate($chained_token_type, [$chained_token => $original], [$chained_token_type => $context->getContextValue()], $options, $bubbleable_metadata); $replacements += \Drupal::token()->generate($chained_token_type, [$chained_token => $original], [$chained_token_type => $value], $options, $bubbleable_metadata); } } Loading src/ContextProvider/CurrentContent.php +11 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,15 @@ class CurrentContent extends CurrentContentBase { return $context_stack->validate(GenericEntityContext::fromEntityType($entity_type), FALSE) ? $context : NULL; } /** * {@inheritdoc} */ protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext { $context = CurrentEntityContext::fromNothing($this->t('@name entity in "@purpose" scope', [ '@name' => $this->t("Current"), '@purpose' => $this->t($context_stack->getPurpose()), ]), $context_stack, 'entity'); return $context_stack->validate(GenericEntityContext::fromNothing(), FALSE) ? $context : NULL; } } src/ContextProvider/CurrentContentBase.php +25 −9 Original line number Diff line number Diff line Loading @@ -51,26 +51,31 @@ abstract class CurrentContentBase implements ContextProviderInterface { } $purpose = $context_stack->getPurpose(); $by_stack[$purpose] = $entity_type_ids; $by_stack[$purpose][] = 'entity'; } } else { foreach ($unqualified_context_ids as $context_id) { list($purpose, $entity_type_id) = explode('.', $context_id, 2); list($purpose, $key) = explode('.', $context_id, 2); if (!($context_stack = $this->getContextStack($purpose))) { continue; } $by_stack[$purpose][] = $entity_type_id; $by_stack[$purpose][] = $key; } } foreach ($by_stack as $purpose => $entity_type_ids) { foreach ($by_stack as $purpose => $keys) { $context_stack = $this->getContextStack($purpose); foreach ($entity_type_ids as $entity_type_id) { if (!($entity_type = $this->entityTypeManager->getDefinition($entity_type_id, FALSE))) { continue; foreach ($keys as $key) { if ($key === 'entity') { if ($context = $this->getGenericRuntimeContext($context_stack)) { $result[$purpose . '.' . $key] = $context; } } elseif ($entity_type = $this->entityTypeManager->getDefinition($key, FALSE)) { if ($entity_type->entityClassImplements(ContentEntityInterface::class)) { if ($context = $this->getRuntimeContext($entity_type, $context_stack)) { $result[$purpose . '.' . $entity_type_id] = $context; $result[$purpose . '.' . $key] = $context; } } } } Loading @@ -91,6 +96,17 @@ abstract class CurrentContentBase implements ContextProviderInterface { */ abstract protected function getRuntimeContext(EntityTypeInterface $entity_type, ContextStackInterface $context_stack): ?CurrentEntityContext; /** * Get the runtime context for a generic entity. * * @param \Drupal\context_stack\ContextStackInterface $context_stack * The context stack to define the context for. * * @return \Drupal\context_stack\Plugin\Context\CurrentEntityContext|null * An instance of CurrentEntityContext, or NULL if no context is defined. */ abstract protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext; /** * {@inheritdoc} */ Loading src/ContextProvider/CurrentParentContent.php +11 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,15 @@ class CurrentParentContent extends CurrentContentBase { return $context_stack->validate(GenericEntityContext::fromEntityType($entity_type), FALSE) ? $context : NULL; } /** * {@inheritdoc} */ protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext { $context = CurrentParentEntityContext::fromNothing($this->t('@name entity in "@purpose" scope', [ '@name' => $this->t("Parent"), '@purpose' => $this->t($context_stack->getPurpose()), ]), $context_stack, 'entity'); return $context_stack->validate(GenericEntityContext::fromNothing(), FALSE) ? $context : NULL; } } src/ContextProvider/CurrentRootContent.php +11 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,15 @@ class CurrentRootContent extends CurrentContentBase { return $context_stack->validate(GenericEntityContext::fromEntityType($entity_type), FALSE) ? $context : NULL; } /** * {@inheritdoc} */ protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext { $context = CurrentRootEntityContext::fromNothing($this->t('@name entity in "@purpose" scope', [ '@name' => $this->t("Root"), '@purpose' => $this->t($context_stack->getPurpose()), ]), $context_stack, 'entity'); return $context_stack->validate(GenericEntityContext::fromNothing(), FALSE) ? $context : NULL; } } Loading
context_stack.tokens.inc +19 −4 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ */ use Drupal\context_stack\ContextStackRepository; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Render\BubbleableMetadata; /** Loading Loading @@ -67,17 +68,18 @@ function context_stack_tokens($type, $tokens, array $data, array $options, Bubbl // Cannot proceeed without further parts. continue; } if ($purpose === 'account' && reset($parts) !== 'user') { if ($purpose === 'account' && !in_array(reset($parts), ['user', 'entity'])) { $chained_token_type = $entity_type_id = 'user'; } else { $chained_token_type = $entity_type_id = array_shift($parts); _context_stack_map_token_type($chained_token_type, $entity_type_id); } if (!is_string($entity_type_id) || !is_string($chained_token_type) || empty($parts)) { if (!is_string($chained_token_type) || empty($parts)) { continue; } $context_id = '@' . $service_ids[$type] . ':' . $purpose . '.' . $entity_type_id; $id = is_string($entity_type_id) ? $entity_type_id : $chained_token_type; $context_id = '@' . $service_ids[$type] . ':' . $purpose . '.' . $id; /** @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository */ $context_repository = \Drupal::service('context.repository'); $contexts = $context_repository->getRuntimeContexts([$context_id]); Loading @@ -91,9 +93,22 @@ function context_stack_tokens($type, $tokens, array $data, array $options, Bubbl } continue; } $value = $context->getContextValue(); if (!is_string($entity_type_id)) { // Last chance to get the correct token type. if ($value instanceof EntityInterface) { $chained_token_type = $entity_type_id = $value->getEntityTypeId(); } else { $type_parts = explode(':', $context->getContextData()->getDataDefinition()->getDataType()); $chained_token_type = end($type_parts); } _context_stack_map_token_type($chained_token_type, $entity_type_id); } $bubbleable_metadata->addCacheableDependency($context); $chained_token = implode(':', $parts); $replacements += \Drupal::token()->generate($chained_token_type, [$chained_token => $original], [$chained_token_type => $context->getContextValue()], $options, $bubbleable_metadata); $replacements += \Drupal::token()->generate($chained_token_type, [$chained_token => $original], [$chained_token_type => $value], $options, $bubbleable_metadata); } } Loading
src/ContextProvider/CurrentContent.php +11 −0 Original line number Diff line number Diff line Loading @@ -24,4 +24,15 @@ class CurrentContent extends CurrentContentBase { return $context_stack->validate(GenericEntityContext::fromEntityType($entity_type), FALSE) ? $context : NULL; } /** * {@inheritdoc} */ protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext { $context = CurrentEntityContext::fromNothing($this->t('@name entity in "@purpose" scope', [ '@name' => $this->t("Current"), '@purpose' => $this->t($context_stack->getPurpose()), ]), $context_stack, 'entity'); return $context_stack->validate(GenericEntityContext::fromNothing(), FALSE) ? $context : NULL; } }
src/ContextProvider/CurrentContentBase.php +25 −9 Original line number Diff line number Diff line Loading @@ -51,26 +51,31 @@ abstract class CurrentContentBase implements ContextProviderInterface { } $purpose = $context_stack->getPurpose(); $by_stack[$purpose] = $entity_type_ids; $by_stack[$purpose][] = 'entity'; } } else { foreach ($unqualified_context_ids as $context_id) { list($purpose, $entity_type_id) = explode('.', $context_id, 2); list($purpose, $key) = explode('.', $context_id, 2); if (!($context_stack = $this->getContextStack($purpose))) { continue; } $by_stack[$purpose][] = $entity_type_id; $by_stack[$purpose][] = $key; } } foreach ($by_stack as $purpose => $entity_type_ids) { foreach ($by_stack as $purpose => $keys) { $context_stack = $this->getContextStack($purpose); foreach ($entity_type_ids as $entity_type_id) { if (!($entity_type = $this->entityTypeManager->getDefinition($entity_type_id, FALSE))) { continue; foreach ($keys as $key) { if ($key === 'entity') { if ($context = $this->getGenericRuntimeContext($context_stack)) { $result[$purpose . '.' . $key] = $context; } } elseif ($entity_type = $this->entityTypeManager->getDefinition($key, FALSE)) { if ($entity_type->entityClassImplements(ContentEntityInterface::class)) { if ($context = $this->getRuntimeContext($entity_type, $context_stack)) { $result[$purpose . '.' . $entity_type_id] = $context; $result[$purpose . '.' . $key] = $context; } } } } Loading @@ -91,6 +96,17 @@ abstract class CurrentContentBase implements ContextProviderInterface { */ abstract protected function getRuntimeContext(EntityTypeInterface $entity_type, ContextStackInterface $context_stack): ?CurrentEntityContext; /** * Get the runtime context for a generic entity. * * @param \Drupal\context_stack\ContextStackInterface $context_stack * The context stack to define the context for. * * @return \Drupal\context_stack\Plugin\Context\CurrentEntityContext|null * An instance of CurrentEntityContext, or NULL if no context is defined. */ abstract protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext; /** * {@inheritdoc} */ Loading
src/ContextProvider/CurrentParentContent.php +11 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,15 @@ class CurrentParentContent extends CurrentContentBase { return $context_stack->validate(GenericEntityContext::fromEntityType($entity_type), FALSE) ? $context : NULL; } /** * {@inheritdoc} */ protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext { $context = CurrentParentEntityContext::fromNothing($this->t('@name entity in "@purpose" scope', [ '@name' => $this->t("Parent"), '@purpose' => $this->t($context_stack->getPurpose()), ]), $context_stack, 'entity'); return $context_stack->validate(GenericEntityContext::fromNothing(), FALSE) ? $context : NULL; } }
src/ContextProvider/CurrentRootContent.php +11 −0 Original line number Diff line number Diff line Loading @@ -25,4 +25,15 @@ class CurrentRootContent extends CurrentContentBase { return $context_stack->validate(GenericEntityContext::fromEntityType($entity_type), FALSE) ? $context : NULL; } /** * {@inheritdoc} */ protected function getGenericRuntimeContext(ContextStackInterface $context_stack): ?CurrentEntityContext { $context = CurrentRootEntityContext::fromNothing($this->t('@name entity in "@purpose" scope', [ '@name' => $this->t("Root"), '@purpose' => $this->t($context_stack->getPurpose()), ]), $context_stack, 'entity'); return $context_stack->validate(GenericEntityContext::fromNothing(), FALSE) ? $context : NULL; } }