Skip to content

Instantly share code, notes, and snippets.

@lonalore
Last active November 21, 2021 23:58
Show Gist options
  • Save lonalore/6d3078b4f641aa8ffd7c397f271a8d5c to your computer and use it in GitHub Desktop.
Save lonalore/6d3078b4f641aa8ffd7c397f271a8d5c to your computer and use it in GitHub Desktop.
Drupal 8 Webform Redirect Handler supports tokens
<?php
namespace Drupal\CUSTOM_MODULE\Plugin\WebformHandler;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Url;
use Drupal\webform\Plugin\WebformHandlerBase;
use Drupal\webform\WebformSubmissionConditionsValidatorInterface;
use Drupal\webform\WebformSubmissionInterface;
use Drupal\webform\WebformTokenManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Webform submission redirect handler.
*
* @WebformHandler(
* id = "redirect",
* label = @Translation("Redirect"),
* category = @Translation("Development"),
* description = @Translation("Redirect after webform submission."),
* cardinality = \Drupal\webform\Plugin\WebformHandlerInterface::CARDINALITY_SINGLE,
* results = \Drupal\webform\Plugin\WebformHandlerInterface::RESULTS_PROCESSED,
* submission = \Drupal\webform\Plugin\WebformHandlerInterface::SUBMISSION_OPTIONAL,
* )
*/
class RedirectWebformHandler extends WebformHandlerBase {
/**
* The webform token manager.
*
* @var \Drupal\webform\WebformTokenManagerInterface
*/
protected $tokenManager;
/**
* RedirectWebformHandler constructor.
*
* @param array $configuration
* @param $plugin_id
* @param $plugin_definition
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* @param \Drupal\webform\WebformSubmissionConditionsValidatorInterface $conditions_validator
* @param \Drupal\webform\WebformTokenManagerInterface $token_manager
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, LoggerChannelFactoryInterface $logger_factory, ConfigFactoryInterface $config_factory, EntityTypeManagerInterface $entity_type_manager, WebformSubmissionConditionsValidatorInterface $conditions_validator, WebformTokenManagerInterface $token_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $logger_factory, $config_factory, $entity_type_manager, $conditions_validator);
$this->tokenManager = $token_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('logger.factory'),
$container->get('config.factory'),
$container->get('entity_type.manager'),
$container->get('webform_submission.conditions_validator'),
$container->get('webform.token_manager')
);
}
/**
* {@inheritdoc}
*/
public function getSummary() {
$configuration = $this->getConfiguration();
$settings = $configuration['settings'];
// Get state labels.
$states = [
WebformSubmissionInterface::STATE_DRAFT_CREATED => $this->t('Draft created'),
WebformSubmissionInterface::STATE_DRAFT_UPDATED => $this->t('Draft updated'),
WebformSubmissionInterface::STATE_CONVERTED => $this->t('Converted'),
WebformSubmissionInterface::STATE_COMPLETED => $this->t('Completed'),
WebformSubmissionInterface::STATE_UPDATED => $this->t('Updated'),
WebformSubmissionInterface::STATE_LOCKED => $this->t('Locked'),
];
$settings['states'] = array_intersect_key($states, array_combine($settings['states'], $settings['states']));
return [
'#settings' => $settings,
] + parent::getSummary();
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'states' => [WebformSubmissionInterface::STATE_COMPLETED],
'url' => '/webform/[webform:id]/submissions/[webform_submission:sid]',
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$results_disabled = $this->getWebform()->getSetting('results_disabled');
$form['trigger'] = [
'#type' => 'fieldset',
'#title' => $this->t('Trigger'),
];
$form['trigger']['states'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Execute'),
'#options' => [
WebformSubmissionInterface::STATE_DRAFT_CREATED => $this->t('…when <b>draft is created</b>.'),
WebformSubmissionInterface::STATE_DRAFT_UPDATED => $this->t('…when <b>draft is updated</b>.'),
WebformSubmissionInterface::STATE_CONVERTED => $this->t('…when anonymous <b>submission is converted</b> to authenticated.'),
WebformSubmissionInterface::STATE_COMPLETED => $this->t('…when <b>submission is completed</b>.'),
WebformSubmissionInterface::STATE_UPDATED => $this->t('…when <b>submission is updated</b>.'),
],
'#required' => TRUE,
'#access' => $results_disabled ? FALSE : TRUE,
'#default_value' => $results_disabled ? [WebformSubmissionInterface::STATE_COMPLETED] : $this->configuration['states'],
];
$form['redirect'] = [
'#type' => 'fieldset',
'#title' => $this->t('Redirect'),
];
$form['redirect']['url'] = [
'#type' => 'textfield',
'#title' => $this->t('URL'),
'#required' => TRUE,
'#access' => $results_disabled ? FALSE : TRUE,
'#default_value' => $results_disabled ? '' : $this->configuration['url'],
];
$form['redirect']['token_tree_link'] = $this->buildTokenTreeElement();
$this->elementTokenValidate($form);
return $this->setSettingsParents($form);
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
if ($form_state->hasAnyErrors()) {
return;
}
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
$this->applyFormStateToConfiguration($form_state);
// Cleanup states.
$this->configuration['states'] = array_values(array_filter($this->configuration['states']));
}
/**
* {@inheritdoc}
*/
public function alterForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
// Flag the button as submit button.
$form['actions']['submit']['#submit_button'] = TRUE;
// Append a custom callback function to handle redirect in it.
$form['actions']['submit']['#submit'][] = [$this, 'submitFormRedirect'];
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
$webform = $webform_submission->getWebform();
$results_disbled = $webform->getSetting('results_disabled');
$state = $results_disbled ? WebformSubmissionInterface::STATE_COMPLETED : $webform_submission->getState();
$element = $form_state->getTriggeringElement();
// If a draft has been submitted without any kind of errors, than the
// status is completed, not updated.
if ($state == 'updated' && !empty($element['#submit_button'])) {
$state = (!$webform_submission->isDraft() && !$webform_submission->isCompleted()) ? WebformSubmissionInterface::STATE_COMPLETED : $state;
}
if (in_array($state, $this->configuration['states'])) {
$url = $this->replaceTokens($this->configuration['url'], $webform_submission);
// Redirecting required.
$form_state->setValue('redirect', TRUE);
$form_state->setValue('redirect_url', $url);
}
}
/**
* Custom callback function to handle redirection.
*
* @param array $form
* @param \Drupal\Core\Form\FormStateInterface $form_state
*/
public function submitFormRedirect(array &$form, FormStateInterface $form_state) {
$url = $form_state->getValue('redirect_url');
if (!empty($form_state->getValue('redirect')) && !empty($url)) {
if (strpos($url, 'http') === 0) {
$url = Url::fromUri($url);
}
elseif (strpos($url, '/') === 0 || strpos($url, '?') === 0 || strpos($url, '#') === 0) {
$url = Url::fromUserInput($url);
}
if ($url instanceof Url) {
$form_state->setRedirectUrl($url);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment