Skip to content
Snippets Groups Projects
Commit 9af4fd50 authored by jrockowitz's avatar jrockowitz
Browse files

Issue #3076750: Add Webform Options Limit Handler. Add validation.

parent ca406cb8
No related branches found
No related tags found
1 merge request!660Issue #3431852: When a Webform is loaded on a 404 page: [PHP 8.1] Deprecated...
...@@ -2,7 +2,7 @@ webform.handler.options_limit: ...@@ -2,7 +2,7 @@ webform.handler.options_limit:
type: mapping type: mapping
label: Example label: Example
mapping: mapping:
element: element_key:
type: string type: string
label: 'Element' label: 'Element'
limits: limits:
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Drupal\webform_options_limit\Plugin\WebformHandler; namespace Drupal\webform_options_limit\Plugin\WebformHandler;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\NestedArray; use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Database\Connection; use Drupal\Core\Database\Connection;
use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Config\ConfigFactoryInterface;
...@@ -56,6 +57,11 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -56,6 +57,11 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
*/ */
const LIMIT_STATUS_UNLIMITED = 'unlimited'; const LIMIT_STATUS_UNLIMITED = 'unlimited';
/**
* Option limit eror.
*/
const LIMIT_STATUS_ERROR = 'error';
/** /**
* Option limit action disable. * Option limit action disable.
*/ */
...@@ -86,6 +92,13 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -86,6 +92,13 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
*/ */
const MESSAGE_DISPLAY_NONE = 'none'; const MESSAGE_DISPLAY_NONE = 'none';
/**
* The element (cached) label.
*
* @var string
*/
protected $elementLabel;
/** /**
* The database object. * The database object.
* *
...@@ -140,7 +153,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -140,7 +153,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
*/ */
public function defaultConfiguration() { public function defaultConfiguration() {
return [ return [
'element' => '', 'element_key' => '',
'limits' => [], 'limits' => [],
'limit_reached_action' => 'disable', 'limit_reached_action' => 'disable',
'limit_source_entity' => TRUE, 'limit_source_entity' => TRUE,
...@@ -149,7 +162,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -149,7 +162,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
'option_single_message' => '[@remaining remaining]', 'option_single_message' => '[@remaining remaining]',
'option_unlimited_message' => '[unlimited]', 'option_unlimited_message' => '[unlimited]',
'option_none_message' => '[@remaining remaining]', 'option_none_message' => '[@remaining remaining]',
'option_error_message' => '@label is unavailable', 'option_error_message' => '@name: @label is unavailable.',
'debug' => FALSE, 'debug' => FALSE,
]; ];
} }
...@@ -161,14 +174,14 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -161,14 +174,14 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
$configuration = $this->getConfiguration(); $configuration = $this->getConfiguration();
$settings = $configuration['settings']; $settings = $configuration['settings'];
$element = $this->getWebform()->getElement($settings['element']); $element = $this->getWebform()->getElement($settings['element_key']);
if ($element) { if ($element) {
$webform_element = $this->elementManager->getElementInstance($element); $webform_element = $this->elementManager->getElementInstance($element);
$t_args = [ $t_args = [
'@title' => $webform_element->getAdminLabel($element), '@title' => $webform_element->getAdminLabel($element),
'@type' => $webform_element->getPluginLabel(), '@type' => $webform_element->getPluginLabel(),
]; ];
$settings['element'] = $this->t('@title (@type)', $t_args); $settings['element_key'] = $this->t('@title (@type)', $t_args);
} }
return [ return [
...@@ -192,11 +205,11 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -192,11 +205,11 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
'#title' => $this->t('Element settings'), '#title' => $this->t('Element settings'),
'#open' => TRUE, '#open' => TRUE,
]; ];
$form['element_settings']['element'] = [ $form['element_settings']['element_key'] = [
'#type' => 'select', '#type' => 'select',
'#title' => $this->t('Element'), '#title' => $this->t('Element'),
'#options' => $this->getElementsWithOptions(), '#options' => $this->getElementsWithOptions(),
'#default_value' => $this->configuration['element'], '#default_value' => $this->configuration['element_key'],
'#required' => TRUE, '#required' => TRUE,
'#empty_option' => $this->t('- Select -') , '#empty_option' => $this->t('- Select -') ,
'#attributes' => [ '#attributes' => [
...@@ -326,6 +339,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -326,6 +339,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
'#type' => 'textfield', '#type' => 'textfield',
'#title' => $this->t('Option validation error message'), '#title' => $this->t('Option validation error message'),
'#default_value' => $this->configuration['option_error_message'], '#default_value' => $this->configuration['option_error_message'],
'#required' => TRUE,
]; ];
$form['option_settings']['placeholders'] = [ $form['option_settings']['placeholders'] = [
'#type' => 'details', '#type' => 'details',
...@@ -337,12 +351,12 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -337,12 +351,12 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
$this->t('@limit - The total number of submissions allowed for the option.'), $this->t('@limit - The total number of submissions allowed for the option.'),
$this->t('@total - The current number of submissions for the option.'), $this->t('@total - The current number of submissions for the option.'),
$this->t('@remaining - The remaining number of submissions for the option.'), $this->t('@remaining - The remaining number of submissions for the option.'),
$this->t("@labal - The option's label."), $this->t("@label - The element option's label."),
$this->t("@name - The element's title."),
], ],
], ],
]; ];
// Development. // Development.
$form['development'] = [ $form['development'] = [
'#type' => 'details', '#type' => 'details',
...@@ -369,6 +383,10 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -369,6 +383,10 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
foreach ($this->configuration['limits'] as $key => $value) { foreach ($this->configuration['limits'] as $key => $value) {
$this->configuration['limits'][$key] = (int) $value; $this->configuration['limits'][$key] = (int) $value;
} }
// Clear cached element label.
// @see \Drupal\webform_options_limit\Plugin\WebformHandler\OptionsLimitWebformHandler::getElementLabel
$this->elementLabel = NULL;
} }
/** /**
...@@ -406,10 +424,14 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -406,10 +424,14 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
function alterElement(array &$element, FormStateInterface $form_state, array $context) { function alterElement(array &$element, FormStateInterface $form_state, array $context) {
if ($element['#webform_key'] !== $this->configuration['element']) { if ($element['#webform_key'] !== $this->configuration['element_key']) {
return; return;
} }
/** @var \Drupal\webform\WebformSubmissionForm $form_object */
$form_object = $form_state->getFormObject();
$this->setWebformSubmission($form_object->getEntity());
$limits = $this->getLimits(); $limits = $this->getLimits();
if (isset($element['#options'])) { if (isset($element['#options'])) {
...@@ -417,10 +439,20 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -417,10 +439,20 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
$this->alterElementOptions($options, $limits); $this->alterElementOptions($options, $limits);
} }
if ($this->getWebform()->access('update')) { // Add validate callback.
$element['#element_validate'][] = [get_called_class(), 'validateWebformOptionsLimit'];
$element['#webform_option_limit_handler_id'] = $this->getHandlerId();
// Append option limit summary to edit form for admin only.
$is_operation_edit = in_array($form_object->getOperation(), ['edit', 'edit_all']);
$has_update_any = $this->getWebform()->access('submission_update_any');
if ($is_operation_edit && $has_update_any) {
$t_args = [
'@options' => (isset($element['#options'])) ? $this->t('Options') : $this->t('Images'),
];
$build = [ $build = [
'#type' => 'details', '#type' => 'details',
'#title' => (isset($element['#options'])) ? $this->t('Options limit summary') : $this->t('Images limit summary'), '#title' => $this->t('@options limit summary (For submission administors only)', $t_args),
'limits' => [ 'limits' => [
'#type' => 'table', '#type' => 'table',
'#header' => [ '#header' => [
...@@ -437,10 +469,17 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -437,10 +469,17 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
$property = $webform_element->hasProperty('field_suffix') ? '#field_suffix' : '#suffix'; $property = $webform_element->hasProperty('field_suffix') ? '#field_suffix' : '#suffix';
$element += [$property => '']; $element += [$property => ''];
$element[$property] = \Drupal::service('renderer')->render($build); $element[$property] = \Drupal::service('renderer')->render($build);
} }
} }
/**
* Alter an element's options recursively.
*
* @param array $options
* An array of options.
* @param array $limits
* An element's option limits.
*/
protected function alterElementOptions(array &$options, array $limits) { protected function alterElementOptions(array &$options, array $limits) {
foreach ($options as $option_value => $option_text) { foreach ($options as $option_value => $option_text) {
if (is_array($option_text)) { if (is_array($option_text)) {
...@@ -448,7 +487,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -448,7 +487,7 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
} }
elseif (isset($limits[$option_value])) { elseif (isset($limits[$option_value])) {
// @todo Handler removing option. // @todo Handler removing option.
$options[$option_value] = $this->getElementOptionLabel( $options[$option_value] = $this->getLimitLabel(
$option_text, $option_text,
$limits[$option_value] $limits[$option_value]
); );
...@@ -456,49 +495,58 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -456,49 +495,58 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
} }
} }
/****************************************************************************/
// Validation methods.
/****************************************************************************/
/** /**
* Add limit message to an option's label. * Validate webform options limit.
*
* @param string $label
* An option's label.
* @param array $limit
* The option's limit information
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup|string
* An option's label with a limit message.
*/ */
protected function getElementOptionLabel($label, array $limit) { public static function validateWebformOptionsLimit(&$element, FormStateInterface $form_state, &$complete_form) {
$message_display = $this->configuration['option_message_display']; /** @var \Drupal\webform\WebformSubmissionForm $form_object */
if ($message_display === static::MESSAGE_DISPLAY_NONE) { $form_object = $form_state->getFormObject();
return $label; /** @var \Drupal\webform\WebformSubmissionInterface $webform_submission */
} $webform_submission = $form_object->getEntity();
$webform = $form_object->getWebform();
$message = $this->configuration['option_' . $limit['status'] . '_message']; /** @var \Drupal\webform_options_limit\Plugin\WebformHandler\OptionsLimitWebformHandler $handler */
if (!$message) { $handler = $webform->getHandler($element['#webform_option_limit_handler_id']);
return $label; $handler->setWebformSubmission($webform_submission);
$handler->validateElement($element, $form_state);
} }
$message = $this->t($message, [ /**
'@label' => $label, * @param array $element
'@limit' => $limit['limit'], * @param \Drupal\Core\Form\FormStateInterface $form_state
'@total' => $limit['total'], *
'@remaining' => $limit['remaining'], * @internal
]); */
public function validateElement(array $element, FormStateInterface $form_state) {
$webform_submission = $this->getWebformSubmission();
$element_key = $this->configuration['element_key'];
switch ($message_display) { // Get casting as array to support multiple options.
case static::MESSAGE_DISPLAY_LABEL: $original_values = (array) $webform_submission->getElementOriginalData($element_key);
$t_args = ['@label' => $label, '@message' => $message]; $values = (array) $form_state->getValue($element_key);
return $this->t('@label @message', $t_args); if (empty($values) || $values === ['']) {
return;
}
case static::MESSAGE_DISPLAY_DESCRIPTION: $limits = $this->getLimits($values);
return $label foreach ($limits as $value => $limit) {
. (strpos($label, WebformOptionsHelper::DESCRIPTION_DELIMITER) === FALSE ? WebformOptionsHelper::DESCRIPTION_DELIMITER : '') // Do not apply option limit to any previously selected option value.
. $message; if (in_array($value, $original_values)) {
continue;
}
if ($limit['status'] === static::LIMIT_STATUS_NONE) {
$message = $this->getLimitMessage(static::LIMIT_STATUS_ERROR, $limit);
$form_state->setError($element, $message);
}
} }
} }
/****************************************************************************/ /****************************************************************************/
// Helper methods. // Element methods.
/****************************************************************************/ /****************************************************************************/
/** /**
...@@ -508,20 +556,37 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -508,20 +556,37 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
* Selected element. * Selected element.
*/ */
protected function getElement() { protected function getElement() {
return $this->getWebform()->getElement($this->configuration['element']); return $this->getWebform()->getElement($this->configuration['element_key']);
} }
/** /**
* Get selected webform element plugin. * Get selected webform element plugin.
* *
* @return \Drupal\webform\Plugin\WebformElementInterface|null * @return \Drupal\webform\Plugin\WebformElementInterface|null
* A webform element plugin instance * A webform element plugin instance.
*/ */
protected function getWebformElement() { protected function getWebformElement() {
$element = $this->getElement(); $element = $this->getElement();
return ($element) ? $this->elementManager->getElementInstance($element) : NULL; return ($element) ? $this->elementManager->getElementInstance($element) : NULL;
} }
/**
* Get selected webform element label.
*
* @return string
* A webform element label.
*/
protected function getElementLabel() {
if (isset($this->elementLabel)) {
return $this->elementLabel;
}
$element = $this->getElement();
$webform_element = $this->getWebformElement();
$this->elementLabel = $webform_element->getLabel($element);
return $this->elementLabel;
}
/** /**
* Get key/value array of webform elements with options or images. * Get key/value array of webform elements with options or images.
* *
...@@ -574,44 +639,34 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -574,44 +639,34 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
return $options; return $options;
} }
/** /****************************************************************************/
* Get options submission totals for the current webform and source entity. // Limits methods.
* /****************************************************************************/
* @return array
* A key/value array of options totals.
*/
protected function getTotals() {
$webform_submission = $this->getWebformSubmission();
$webform = $this->getWebform();
/** @var \Drupal\Core\Database\StatementInterface $result */
$query = $this->database->select('webform_submission', 's');
$query->join('webform_submission_data', 'sd', 's.sid = sd.sid');
$query->fields('sd', ['value']);
$query->addExpression('COUNT(value)', 'total');
$query->condition('sd.name', $this->configuration['element']);
$query->condition('sd.webform_id', $webform->id());
// @todo Add source entity support.
$query->groupBy('value');
return $query->execute()->fetchAllKeyed();
}
/** /**
* Get an associative array of options limits. * Get an associative array of options limits.
* *
* @param array $values
* Optional array of values to get options limit.
*
* @return array * @return array
* An associative array of options limits keyed by option value and * An associative array of options limits keyed by option value and
* including the option's limit, total, remaining, and status. * including the option's limit, total, remaining, and status.
*/ */
protected function getLimits() { protected function getLimits(array $values = []) {
$default_limit = isset($this->configuration['limits'][static::DEFAULT_LIMIT]) $default_limit = isset($this->configuration['limits'][static::DEFAULT_LIMIT])
? $this->configuration['limits'][static::DEFAULT_LIMIT] ? $this->configuration['limits'][static::DEFAULT_LIMIT]
: NULL; : NULL;
$totals = $this->getTotals();
$totals = $this->getTotals($values);
$options = $this->getElementOptions();
if ($values) {
$options = array_intersect_key($options, array_combine($values, $values));
}
$limits = []; $limits = [];
$option_keys = $this->getElementOptions(); foreach ($options as $option_key => $option_label) {
foreach ($option_keys as $option_key => $option_label) {
$limit = (isset($this->configuration['limits'][$option_key])) $limit = (isset($this->configuration['limits'][$option_key]))
? $this->configuration['limits'][$option_key] ? $this->configuration['limits'][$option_key]
: $default_limit; : $default_limit;
...@@ -644,4 +699,110 @@ class OptionsLimitWebformHandler extends WebformHandlerBase { ...@@ -644,4 +699,110 @@ class OptionsLimitWebformHandler extends WebformHandlerBase {
return $limits; return $limits;
} }
/**
* Get options submission totals for the current webform and source entity.
*
* @param array $values
* Optional array of values to get totals.
*
* @return array
* A key/value array of options totals.
*/
protected function getTotals(array $values = []) {
$webform = $this->getWebform();
/** @var \Drupal\Core\Database\StatementInterface $result */
$query = $this->database->select('webform_submission', 's');
$query->join('webform_submission_data', 'sd', 's.sid = sd.sid');
$query->fields('sd', ['value']);
$query->addExpression('COUNT(value)', 'total');
$query->condition('sd.name', $this->configuration['element_key']);
$query->condition('sd.webform_id', $webform->id());
$query->groupBy('value');
// Limit by option values.
if ($values) {
$query->condition('sd.value', $values, 'IN');
}
// Limit by source entity.
if ($this->configuration['limit_source_entity']) {
$source_entity = $this->getWebformSubmission()->getSourceEntity();
if ($source_entity) {
$query->condition('s.entity_type', $source_entity->getEntityTypeId());
$query->condition('s.entity_id', $source_entity->id());
}
else {
$query->isNull('s.entity_type');
$query->isNull('s.entity_id');
}
}
return $query->execute()->fetchAllKeyed();
}
/****************************************************************************/
// Labels and messages methods.
/****************************************************************************/
/**
* Get limit message.
*
* @param string $type
* Type of message.
* @param array $limit.
* Associative array containing limit, total, remaining, and label.
*
* @return \Drupal\Component\Render\FormattableMarkup|string
* A limit message.
*/
protected function getLimitMessage($type, array $limit) {
$message = $this->configuration['option_' . $type . '_message'];
if (!$message) {
return '';
}
return new FormattableMarkup($message, [
'@name' => $this->getElementLabel(),
'@label' => $limit['label'],
'@limit' => $limit['limit'],
'@total' => $limit['total'],
'@remaining' => $limit['remaining'],
]);
}
/**
* Get option limit label.
*
* @param string $label
* An option's label.
* @param array $limit
* The option's limit information
*
* @return \Drupal\Core\StringTranslation\TranslatableMarkup|string
* An option's limit label.
*/
protected function getLimitLabel($label, array $limit) {
$message_display = $this->configuration['option_message_display'];
if ($message_display === static::MESSAGE_DISPLAY_NONE) {
return $label;
}
$message = $this->getLimitMessage($limit['status'], $limit);
if (!$message) {
return $label;
}
switch ($message_display) {
case static::MESSAGE_DISPLAY_LABEL:
$t_args = ['@label' => $label, '@message' => $message];
return $this->t('@label @message', $t_args);
case static::MESSAGE_DISPLAY_DESCRIPTION:
return $label
. (strpos($label, WebformOptionsHelper::DESCRIPTION_DELIMITER) === FALSE ? WebformOptionsHelper::DESCRIPTION_DELIMITER : '')
. $message;
}
}
} }
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Available variables: * Available variables:
* - settings: The current configuration for this handler: * - settings: The current configuration for this handler:
* - element: The options element. * - element_key: The options element.
* - debug: Debugging flag. * - debug: Debugging flag.
* - handler: The handler information, including: * - handler: The handler information, including:
* - id: The handler plugin id. * - id: The handler plugin id.
......
...@@ -201,7 +201,7 @@ handlers: ...@@ -201,7 +201,7 @@ handlers:
conditions: { } conditions: { }
weight: 0 weight: 0
settings: settings:
element: options_limit_default element_key: options_limit_default
limits: limits:
A: 1 A: 1
B: 2 B: 2
...@@ -212,7 +212,7 @@ handlers: ...@@ -212,7 +212,7 @@ handlers:
option_single_message: '[@remaining remaining]' option_single_message: '[@remaining remaining]'
option_none_message: '[@remaining remaining]' option_none_message: '[@remaining remaining]'
option_unlimited_message: '[Unlimited]' option_unlimited_message: '[Unlimited]'
option_error_message: '@label is unavailable' option_error_message: '@name: @label is unavailable.'
debug: false debug: false
options_limit_messages: options_limit_messages:
id: options_limit id: options_limit
...@@ -222,7 +222,7 @@ handlers: ...@@ -222,7 +222,7 @@ handlers:
conditions: { } conditions: { }
weight: 0 weight: 0
settings: settings:
element: options_limit_messages element_key: options_limit_messages
limits: limits:
D: 1 D: 1
E: 2 E: 2
...@@ -233,5 +233,5 @@ handlers: ...@@ -233,5 +233,5 @@ handlers:
option_single_message: '@remaining option remaining / @limit limit / @total total' option_single_message: '@remaining option remaining / @limit limit / @total total'
option_none_message: 'No options remaining / @limit limit / @total total' option_none_message: 'No options remaining / @limit limit / @total total'
option_unlimited_message: 'Unlimited / @total total' option_unlimited_message: 'Unlimited / @total total'
option_error_message: '@label is unavailable' option_error_message: '@name: @label is unavailable.'
debug: false debug: false
...@@ -220,7 +220,7 @@ handlers: ...@@ -220,7 +220,7 @@ handlers:
conditions: { } conditions: { }
weight: 0 weight: 0
settings: settings:
element: select element_key: select
limits: limits:
A: 1 A: 1
B: 2 B: 2
......
...@@ -426,6 +426,13 @@ class WebformSubmission extends ContentEntityBase implements WebformSubmissionIn ...@@ -426,6 +426,13 @@ class WebformSubmission extends ContentEntityBase implements WebformSubmissionIn
return $this; return $this;
} }
/**
* {@inheritdoc}
*/
public function getElementOriginalData($key) {
return (isset($this->originalData[$key])) ? $this->originalData[$key] : NULL;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
......
...@@ -181,7 +181,7 @@ class WebformElementManager extends DefaultPluginManager implements FallbackPlug ...@@ -181,7 +181,7 @@ class WebformElementManager extends DefaultPluginManager implements FallbackPlug
$this->moduleHandler->alter($hooks, $element, $form_state, $context); $this->moduleHandler->alter($hooks, $element, $form_state, $context);
// Allow handlers to alter the webform element. // Allow handlers to alter the webform element.
if ($webform) { if ($webform_submission) {
$webform->invokeHandlers('alterElement', $element, $form_state, $context); $webform->invokeHandlers('alterElement', $element, $form_state, $context);
} }
} }
......
...@@ -338,6 +338,18 @@ interface WebformSubmissionInterface extends ContentEntityInterface, EntityOwner ...@@ -338,6 +338,18 @@ interface WebformSubmissionInterface extends ContentEntityInterface, EntityOwner
*/ */
public function setOriginalData(array $data); public function setOriginalData(array $data);
/**
* Get a webform submission element's original data.
*
* @param string $key
* An webform submission element's key.
*
* @return mixed
* An webform submission element's original data/value.
*/
public function getElementOriginalData($key);
/** /**
* Gets the webform submission's token. * Gets the webform submission's token.
* *
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment