Loading modules/mustache_magic/src/Plugin/mustache/Magic/Sync.php +6 −3 Original line number Diff line number Diff line Loading @@ -410,9 +410,12 @@ class Sync extends MustacheMagic { $server_side_render['#with_tokens'] = $this->element['#with_tokens']; /** @var \Drupal\mustache\MustacheTokenProcessor $token_processor */ $token_processor = \Drupal::service('mustache.token_processor'); $tokenized = $token_processor->tokenizeTemplate($template_hash, $template_content); if (!empty($tokenized['tokens'])) { $values['token_options'] = !empty($this->element['#with_tokens']['options']) ? $this->element['#with_tokens']['options'] : []; $token_data = !empty($this->element['#with_tokens']['data']) ? $this->element['#with_tokens']['data'] : []; $token_processor->processData($token_data, 'view', $bubbleable_metadata); $token_processor->processData($token_data, $tokenized['tokens'], 'view', $bubbleable_metadata); } } $build->withPlaceholder($server_side_render); Loading src/MustacheTokenIterate.php +15 −13 Original line number Diff line number Diff line Loading @@ -118,14 +118,15 @@ class MustacheTokenIterate { */ protected function buildRecursive(array $data, array $options, BubbleableMetadata $bubbleable_metadata, array $token_keys, $check_access = 'view') { $target = IterableMarkup::create(); if (empty($data) || empty($token_keys)) { if (empty($data) && empty($token_keys)) { return $target; } $key = array_shift($token_keys); $property = reset($token_keys); if (!isset($data[$key]) && !empty($data)) { if (!isset($data[$key])) { if (!empty($data)) { if (strpos($key, '_') !== FALSE) { $key_hyphened = str_replace('_', '-', $key); if (isset($data[$key_hyphened])) { Loading @@ -140,6 +141,7 @@ class MustacheTokenIterate { return $this->buildRecursive($data, $options, $bubbleable_metadata, $token_keys, $check_access); } } } $data[$key] = NULL; } Loading src/MustacheTokenProcessor.php +66 −26 Original line number Diff line number Diff line Loading @@ -156,17 +156,6 @@ class MustacheTokenProcessor { $token_options['clear'] = TRUE; } if (!empty($element['#cache'])) { $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($element); } else { $bubbleable_metadata = new BubbleableMetadata(); } // Build up the token data. $token_data = isset($token_settings['data']) ? $token_settings['data'] : []; $this->processData($token_data, 'view', $bubbleable_metadata, $langcode); $template_hash = hash('md4', $template_content); $tokenized = $this->tokenizeTemplate($template_hash, $template_content); if (empty($tokenized['tokens'])) { Loading @@ -177,6 +166,17 @@ class MustacheTokenProcessor { $template_tokens = $tokenized['tokens']; $mustache_variables = $tokenized['variables']; if (!empty($element['#cache'])) { $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($element); } else { $bubbleable_metadata = new BubbleableMetadata(); } // Build up the token data. $token_data = isset($token_settings['data']) ? $token_settings['data'] : []; $this->processData($token_data, $template_tokens, 'view', $bubbleable_metadata, $langcode); // Determine cacheability of the Token data. $data_is_cacheable = TRUE; $data_cid = []; Loading Loading @@ -372,6 +372,10 @@ class MustacheTokenProcessor { * * @param array &$token_data * The token data to process. * @param array|null $tokens * (Optional) An array of tokens that are known to be used. Set to NULL if * they are not known beforehand. This should be set whenever possible, * otherwise cacheability may be not working properly. * @param string $check_access * (Optional) The access check to perform. Set NULL to skip access filter. * @param \Drupal\Core\Render\BubbleableMetadata|null $bubbleable_metadata Loading @@ -379,7 +383,11 @@ class MustacheTokenProcessor { * @param string|null $langcode * (Optional) The langcode to use. Leave NULL to use the current language. */ public function processData(array &$token_data, $check_access = 'view', $bubbleable_metadata = NULL, $langcode = NULL) { public function processData(array &$token_data, $tokens = NULL, $check_access = 'view', $bubbleable_metadata = NULL, $langcode = NULL) { if (isset($tokens) && empty($tokens)) { return; } if (!isset($bubbleable_metadata)) { $bubbleable_metadata = new BubbleableMetadata(); } Loading @@ -400,6 +408,7 @@ class MustacheTokenProcessor { // Merge the token data with any global context that provides a value. $context_repository = $this->contextRepository; $contexts = []; if (!isset(static::$contextIds)) { static::$contextIds = array_keys($context_repository->getAvailableContexts()); } Loading @@ -411,32 +420,24 @@ class MustacheTokenProcessor { // want to only use "node"). $type = end($context_data_type); $value = $context->getContextValue(); $bubbleable_metadata->addCacheableDependency($context); // We add the context to the array, even if the value is not being used. // That way cacheability metadata will include cache contexts that are // required for variations, especially when global context is being // used elsewhere. $contexts[$type] = $context; if (isset($value) && !isset($token_data[$type])) { $token_data[$type] = $value; } } } // Filter out any data that is not allowed to be viewed. // Switch to translations if necessary and available. // Also re-map entities that may have a different token type defined. foreach ($token_data as $type => $value) { if (($value instanceof TranslatableInterface) && ($value->language()->getId() !== $langcode) && ($value->hasTranslation($langcode))) { $value = $value->getTranslation($langcode); $token_data[$type] = $value; } if ($value instanceof CacheableDependencyInterface) { $bubbleable_metadata->addCacheableDependency($value); } if ($check_access && $value instanceof AccessibleInterface) { /** @var \Drupal\Core\Access\AccessResultInterface $access_result */ $access_result = $value->access($check_access, NULL, TRUE); $bubbleable_metadata->addCacheableDependency($access_result); if (!$access_result->isAllowed()) { unset($token_data[$type]); continue; } } if (!($value instanceof EntityInterface)) { continue; } Loading @@ -449,9 +450,48 @@ class MustacheTokenProcessor { $the_real_token_type = $definition->get('token_type') ?: $value->getEntityTypeId(); } if (!isset($token_data[$the_real_token_type])) { if (isset($contexts[$type])) { $contexts[$the_real_token_type] = $contexts[$type]; } $token_data[$the_real_token_type] = $value; } } // Filter out data that is not being used and is not allowed to be viewed. // Also add cacheability metadata of data that is being used. foreach ($token_data as $type => $value) { if (isset($tokens)) { $type_is_used = FALSE; foreach (array_keys($tokens) as $used_token_type) { if ($used_token_type === $type) { $type_is_used = TRUE; break; } } } else { $type_is_used = TRUE; } if (!$type_is_used) { unset($token_data[$type]); continue; } if ($value instanceof CacheableDependencyInterface) { $bubbleable_metadata->addCacheableDependency($value); } if (isset($contexts[$type])) { $bubbleable_metadata->addCacheableDependency($contexts[$type]); } if ($check_access && $value instanceof AccessibleInterface) { /** @var \Drupal\Core\Access\AccessResultInterface $access_result */ $access_result = $value->access($check_access, NULL, TRUE); $bubbleable_metadata->addCacheableDependency($access_result); if (!$access_result->isAllowed()) { unset($token_data[$type]); continue; } } } } /** Loading src/Plugin/mustache/Magic/Introspection.php +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ class Introspection extends MustacheMagic { $token_data = isset($token_settings['data']) ? $token_settings['data'] : []; /** @var \Drupal\mustache\MustacheTokenProcessor $token_processor */ $token_processor = \Drupal::service('mustache.token_processor'); $token_processor->processData($token_data, 'view'); $token_processor->processData($token_data); if (!empty($token_data)) { $token_info = \Drupal::token()->getInfo(); foreach ($token_info['tokens'] as $type => $tokens) { Loading Loading
modules/mustache_magic/src/Plugin/mustache/Magic/Sync.php +6 −3 Original line number Diff line number Diff line Loading @@ -410,9 +410,12 @@ class Sync extends MustacheMagic { $server_side_render['#with_tokens'] = $this->element['#with_tokens']; /** @var \Drupal\mustache\MustacheTokenProcessor $token_processor */ $token_processor = \Drupal::service('mustache.token_processor'); $tokenized = $token_processor->tokenizeTemplate($template_hash, $template_content); if (!empty($tokenized['tokens'])) { $values['token_options'] = !empty($this->element['#with_tokens']['options']) ? $this->element['#with_tokens']['options'] : []; $token_data = !empty($this->element['#with_tokens']['data']) ? $this->element['#with_tokens']['data'] : []; $token_processor->processData($token_data, 'view', $bubbleable_metadata); $token_processor->processData($token_data, $tokenized['tokens'], 'view', $bubbleable_metadata); } } $build->withPlaceholder($server_side_render); Loading
src/MustacheTokenIterate.php +15 −13 Original line number Diff line number Diff line Loading @@ -118,14 +118,15 @@ class MustacheTokenIterate { */ protected function buildRecursive(array $data, array $options, BubbleableMetadata $bubbleable_metadata, array $token_keys, $check_access = 'view') { $target = IterableMarkup::create(); if (empty($data) || empty($token_keys)) { if (empty($data) && empty($token_keys)) { return $target; } $key = array_shift($token_keys); $property = reset($token_keys); if (!isset($data[$key]) && !empty($data)) { if (!isset($data[$key])) { if (!empty($data)) { if (strpos($key, '_') !== FALSE) { $key_hyphened = str_replace('_', '-', $key); if (isset($data[$key_hyphened])) { Loading @@ -140,6 +141,7 @@ class MustacheTokenIterate { return $this->buildRecursive($data, $options, $bubbleable_metadata, $token_keys, $check_access); } } } $data[$key] = NULL; } Loading
src/MustacheTokenProcessor.php +66 −26 Original line number Diff line number Diff line Loading @@ -156,17 +156,6 @@ class MustacheTokenProcessor { $token_options['clear'] = TRUE; } if (!empty($element['#cache'])) { $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($element); } else { $bubbleable_metadata = new BubbleableMetadata(); } // Build up the token data. $token_data = isset($token_settings['data']) ? $token_settings['data'] : []; $this->processData($token_data, 'view', $bubbleable_metadata, $langcode); $template_hash = hash('md4', $template_content); $tokenized = $this->tokenizeTemplate($template_hash, $template_content); if (empty($tokenized['tokens'])) { Loading @@ -177,6 +166,17 @@ class MustacheTokenProcessor { $template_tokens = $tokenized['tokens']; $mustache_variables = $tokenized['variables']; if (!empty($element['#cache'])) { $bubbleable_metadata = BubbleableMetadata::createFromRenderArray($element); } else { $bubbleable_metadata = new BubbleableMetadata(); } // Build up the token data. $token_data = isset($token_settings['data']) ? $token_settings['data'] : []; $this->processData($token_data, $template_tokens, 'view', $bubbleable_metadata, $langcode); // Determine cacheability of the Token data. $data_is_cacheable = TRUE; $data_cid = []; Loading Loading @@ -372,6 +372,10 @@ class MustacheTokenProcessor { * * @param array &$token_data * The token data to process. * @param array|null $tokens * (Optional) An array of tokens that are known to be used. Set to NULL if * they are not known beforehand. This should be set whenever possible, * otherwise cacheability may be not working properly. * @param string $check_access * (Optional) The access check to perform. Set NULL to skip access filter. * @param \Drupal\Core\Render\BubbleableMetadata|null $bubbleable_metadata Loading @@ -379,7 +383,11 @@ class MustacheTokenProcessor { * @param string|null $langcode * (Optional) The langcode to use. Leave NULL to use the current language. */ public function processData(array &$token_data, $check_access = 'view', $bubbleable_metadata = NULL, $langcode = NULL) { public function processData(array &$token_data, $tokens = NULL, $check_access = 'view', $bubbleable_metadata = NULL, $langcode = NULL) { if (isset($tokens) && empty($tokens)) { return; } if (!isset($bubbleable_metadata)) { $bubbleable_metadata = new BubbleableMetadata(); } Loading @@ -400,6 +408,7 @@ class MustacheTokenProcessor { // Merge the token data with any global context that provides a value. $context_repository = $this->contextRepository; $contexts = []; if (!isset(static::$contextIds)) { static::$contextIds = array_keys($context_repository->getAvailableContexts()); } Loading @@ -411,32 +420,24 @@ class MustacheTokenProcessor { // want to only use "node"). $type = end($context_data_type); $value = $context->getContextValue(); $bubbleable_metadata->addCacheableDependency($context); // We add the context to the array, even if the value is not being used. // That way cacheability metadata will include cache contexts that are // required for variations, especially when global context is being // used elsewhere. $contexts[$type] = $context; if (isset($value) && !isset($token_data[$type])) { $token_data[$type] = $value; } } } // Filter out any data that is not allowed to be viewed. // Switch to translations if necessary and available. // Also re-map entities that may have a different token type defined. foreach ($token_data as $type => $value) { if (($value instanceof TranslatableInterface) && ($value->language()->getId() !== $langcode) && ($value->hasTranslation($langcode))) { $value = $value->getTranslation($langcode); $token_data[$type] = $value; } if ($value instanceof CacheableDependencyInterface) { $bubbleable_metadata->addCacheableDependency($value); } if ($check_access && $value instanceof AccessibleInterface) { /** @var \Drupal\Core\Access\AccessResultInterface $access_result */ $access_result = $value->access($check_access, NULL, TRUE); $bubbleable_metadata->addCacheableDependency($access_result); if (!$access_result->isAllowed()) { unset($token_data[$type]); continue; } } if (!($value instanceof EntityInterface)) { continue; } Loading @@ -449,9 +450,48 @@ class MustacheTokenProcessor { $the_real_token_type = $definition->get('token_type') ?: $value->getEntityTypeId(); } if (!isset($token_data[$the_real_token_type])) { if (isset($contexts[$type])) { $contexts[$the_real_token_type] = $contexts[$type]; } $token_data[$the_real_token_type] = $value; } } // Filter out data that is not being used and is not allowed to be viewed. // Also add cacheability metadata of data that is being used. foreach ($token_data as $type => $value) { if (isset($tokens)) { $type_is_used = FALSE; foreach (array_keys($tokens) as $used_token_type) { if ($used_token_type === $type) { $type_is_used = TRUE; break; } } } else { $type_is_used = TRUE; } if (!$type_is_used) { unset($token_data[$type]); continue; } if ($value instanceof CacheableDependencyInterface) { $bubbleable_metadata->addCacheableDependency($value); } if (isset($contexts[$type])) { $bubbleable_metadata->addCacheableDependency($contexts[$type]); } if ($check_access && $value instanceof AccessibleInterface) { /** @var \Drupal\Core\Access\AccessResultInterface $access_result */ $access_result = $value->access($check_access, NULL, TRUE); $bubbleable_metadata->addCacheableDependency($access_result); if (!$access_result->isAllowed()) { unset($token_data[$type]); continue; } } } } /** Loading
src/Plugin/mustache/Magic/Introspection.php +1 −1 Original line number Diff line number Diff line Loading @@ -135,7 +135,7 @@ class Introspection extends MustacheMagic { $token_data = isset($token_settings['data']) ? $token_settings['data'] : []; /** @var \Drupal\mustache\MustacheTokenProcessor $token_processor */ $token_processor = \Drupal::service('mustache.token_processor'); $token_processor->processData($token_data, 'view'); $token_processor->processData($token_data); if (!empty($token_data)) { $token_info = \Drupal::token()->getInfo(); foreach ($token_info['tokens'] as $type => $tokens) { Loading