View source
<?php
namespace Drupal\webform\Twig;
use Drupal\Core\Entity\EntityInterface;
use Drupal\webform\Element\WebformHtmlEditor;
use Drupal\webform\Element\WebformMessage;
use Drupal\webform\Utility\WebformElementHelper;
use Drupal\webform\Utility\WebformHtmlHelper;
use Drupal\webform\Utility\WebformLogicHelper;
use Drupal\webform\Utility\WebformXss;
use Drupal\webform\Utility\WebformYaml;
use Drupal\webform\WebformSubmissionInterface;
class WebformTwigExtension extends \Twig_Extension {
protected static $options = [
'html' => 'webform_token_options_html',
'email' => 'webform_token_options_email',
];
public function getFunctions() {
return [
new \Twig_SimpleFunction('webform_html_editor_check_markup', [
$this,
'webformHtmlEditorCheckMarkup',
]),
new \Twig_SimpleFunction('webform_debug', [
$this,
'webformDebug',
]),
new \Twig_SimpleFunction('webform_token', [
$this,
'webformToken',
]),
];
}
public function getName() {
return 'webform';
}
public function webformHtmlEditorCheckMarkup($text, array $options = []) {
return WebformHtmlEditor::checkMarkup($text, $options);
}
public function webformDebug($data) {
try {
if (is_array($data)) {
WebformElementHelper::convertRenderMarkupToStrings($data);
return WebformYaml::encode($data);
}
else {
return $data;
}
} catch (\Exception $exception) {
return $exception
->getMessage();
}
}
public function webformToken($token, EntityInterface $entity = NULL, array $data = [], array $options = []) {
if (!$entity) {
return $token;
}
$original_token = $token;
if (WebformLogicHelper::startRecursionTracking($token) === FALSE) {
return '';
}
foreach (static::$options as $option_name => $option_setting) {
if (strpos($token, ":{$option_setting}")) {
$options[$option_name] = TRUE;
$token = str_replace(":{$option_setting}", '', $token);
}
}
$token_manager = \Drupal::service('webform.token_manager');
$value = $token_manager
->replace($token, $entity, $data, $options);
if (WebformLogicHelper::stopRecursionTracking($original_token) === FALSE) {
return '';
}
return WebformHtmlHelper::containsHtml($value) ? [
'#markup' => $value,
'#allowed_tags' => WebformXss::getAdminTagList(),
] : $value;
}
public static function buildTwigHelp(array $variables = []) {
$submission_storage = \Drupal::entityTypeManager()
->getStorage('webform_submission');
$field_definitions = $submission_storage
->getFieldDefinitions();
foreach ($variables as $index => $item) {
$variables[$index] = [
'#markup' => $item,
'#prefix' => '<strong>',
'#suffix' => '</strong>',
];
}
$variables = array_merge($variables, [
'{{ data.element_key }}',
'{{ data[\'element_key\'] }}',
'{{ data.element_key.delta }}',
'{{ data[\'element_key\'][\'delta\'] }}',
'{{ data.composite_element_key.subelement_key }}',
'{{ data.composite_element_key.delta.subelement_key }}',
'{{ original_data }}',
'{{ elements }}',
'{{ elements_flattened }}',
]);
foreach (array_keys($field_definitions) as $field_name) {
$variables[] = "{{ {$field_name} }}";
}
$variables = array_merge($variables, [
'{{ webform }}',
'{{ webform_submission }}',
]);
$t_args = [
':twig_href' => 'https://twig.sensiolabs.org/',
':drupal_href' => 'https://www.drupal.org/docs/8/theming/twig',
];
$output = [];
$output[] = [
'#markup' => '<p>' . t('Learn about <a href=":twig_href">Twig</a> and how it is used in <a href=":drupal_href">Drupal</a>.', $t_args) . '</p>',
];
$output[] = [
'#markup' => '<p>' . t("The following variables are available:") . '</p>',
];
$output[] = [
'#theme' => 'item_list',
'#items' => $variables,
];
$output[] = [
'#markup' => '<p>' . t("You can also output tokens using the <code>webform_token()</code> function.") . '</p>',
];
$output[] = [
'#markup' => "<pre>{{ webform_token('[webform_submission:values:element_value]', webform_submission, [], options) }}</pre>",
];
$output[] = [
'#markup' => '<p>' . t("You can debug data using the <code>webform_debug()</code> function.") . '</p>',
];
$output[] = [
'#markup' => "<pre>{{ webform_debug(data) }}</pre>",
];
if (\Drupal::currentUser()
->hasPermission('administer modules') && !\Drupal::moduleHandler()
->moduleExists('twig_tweak')) {
$t_args = [
':module_href' => 'https://www.drupal.org/project/twig_tweak',
':documentation_href' => 'https://www.drupal.org/docs/8/modules/twig-tweak/cheat-sheet-8x-2x',
];
$output[] = [
'#type' => 'webform_message',
'#message_type' => 'info',
'#message_message' => t('Install the <a href=":module_href">Twig tweak</a> module, which provides a Twig extension with some <a href=":documentation_href">useful functions and filters</a> that can improve development experience.', $t_args),
'#message_close' => TRUE,
'#storage' => WebformMessage::STORAGE_SESSION,
];
}
return [
'#type' => 'details',
'#title' => t('Help using Twig'),
'description' => $output,
];
}
public static function renderTwigTemplate(WebformSubmissionInterface $webform_submission, $template, array $options = [], array $context = []) {
try {
$build = static::buildTwigTemplate($webform_submission, $template, $options, $context);
return \Drupal::service('renderer')
->renderPlain($build);
} catch (\Exception $exception) {
if ($webform_submission
->getWebform()
->access('update')) {
\Drupal::messenger()
->addError($exception
->getMessage());
}
\Drupal::logger('webform')
->error($exception
->getMessage());
return '';
}
}
public static function buildTwigTemplate(WebformSubmissionInterface $webform_submission, $template, array $options = [], array $context = []) {
$options += [
'html' => FALSE,
'email' => FALSE,
];
foreach (static::$options as $option_name => $option_setting) {
if ($options[$option_name]) {
$template = preg_replace('/\\[(webform_submission:values:?[^]]*)\\]/', '[\\1:' . $option_setting . ']', $template);
}
}
if (strpos($template, 'webform_token(') === FALSE && strpos($template, '[webform') !== FALSE) {
$template = preg_replace('#([^"\']|^)(\\[[^]]+\\])([^"\']|$)#', '\\1{{ webform_token(\'\\2\', webform_submission) }}\\3', $template);
}
$context += [
'webform_submission' => $webform_submission,
'webform' => $webform_submission
->getWebform(),
'elements' => $webform_submission
->getWebform()
->getElementsDecoded(),
'elements_flattened' => $webform_submission
->getWebform()
->getElementsDecodedAndFlattened(),
'options' => $options,
'original_data' => $webform_submission
->getOriginalData(),
] + $webform_submission
->toArray(TRUE);
return [
'#type' => 'inline_template',
'#template' => $template,
'#context' => $context,
];
}
public static function hasEditTwigAccess() {
return \Drupal::currentUser()
->hasPermission('edit webform twig') || \Drupal::currentUser()
->hasPermission('administer webform');
}
}