View source
<?php
namespace Drupal\webform;
use Drupal\Core\Form\OptGroup;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\webform\Plugin\WebformElement\WebformElement;
use Drupal\webform\Plugin\WebformElementManagerInterface;
use Drupal\webform\Utility\WebformArrayHelper;
use Drupal\webform\Utility\WebformOptionsHelper;
class WebformEntityConditionsManager implements WebformEntityConditionsManagerInterface {
use StringTranslationTrait;
protected $elementManager;
public function __construct(WebformElementManagerInterface $element_manager) {
$this->elementManager = $element_manager;
}
public function toText(WebformInterface $webform, array $states, array $options = []) {
$options += [
'name' => $this
->t('element'),
'states' => [],
'triggers' => [],
'logic' => [],
];
$options['states'] += [
'visible' => $this
->t('visible'),
'invisible' => $this
->t('hidden'),
'visible-slide' => $this
->t('visible'),
'invisible-slide' => $this
->t('hidden'),
'enabled' => $this
->t('enabled'),
'disabled' => $this
->t('disabled'),
'readwrite' => $this
->t('read/write'),
'readonly' => $this
->t('read-only'),
'expanded' => $this
->t('expanded'),
'collapsed' => $this
->t('collapsed'),
'required' => $this
->t('required'),
'optional' => $this
->t('optional'),
'checked' => $this
->t('checked'),
'unchecked' => $this
->t('unchecked'),
];
$options['triggers'] += [
'empty' => $this
->t('is empty'),
'filled' => $this
->t('is filled'),
'checked' => $this
->t('is checked'),
'unchecked' => $this
->t('is not checked'),
'value' => '=',
'!value' => '!=',
'pattern' => $this
->t('matches'),
'!pattern' => $this
->t('does not match'),
'less' => '<',
'less_equal' => '<=',
'greater' => '>',
'greater_equal' => '>=',
'between' => $this
->t('is between'),
'!between' => $this
->t('is not between'),
];
$options['logic'] += [
'and' => $this
->t('all'),
'or' => $this
->t('any'),
'xor' => $this
->t('one'),
];
$build = [];
foreach ($states as $state => $conditions) {
$t_args = [
'@name' => $options['name'],
'@state' => isset($options['states'][$state]) ? $options['states'][$state] : $state,
];
$build[$state] = [
'state' => [
'#markup' => $this
->t('This @name is <strong>@state</strong>', $t_args),
'#suffix' => ' ',
],
'conditions' => $this
->buildConditions($webform, $conditions, $options),
];
}
return $build;
}
protected function buildConditions(WebformInterface $webform, array $conditions, array $options) {
if (WebformArrayHelper::isSequential($conditions)) {
$logic = in_array('xor', $conditions) ? 'xor' : 'or';
}
else {
$logic = 'and';
}
$condition_items = [];
foreach ($conditions as $index => $value) {
if (is_string($value) && in_array($value, [
'and',
'or',
'xor',
])) {
continue;
}
if (is_int($index) && is_array($value) && (WebformArrayHelper::isSequential($value) || count($value) > 1)) {
$condition_items[] = $this
->buildConditions($webform, $value, $options + [
'nested' => TRUE,
]);
}
else {
if (is_int($index)) {
$selector = key($value);
$condition = $value[$selector];
}
else {
$selector = $index;
$condition = $value;
}
$condition_items[] = $this
->buildConditionItem($webform, $selector, $condition, $options + [
'nested' => TRUE,
]);
}
}
$t_args = [
'@logic' => $options['logic'][$logic],
];
$build = [];
$build['logic'] = [
'#markup' => empty($options['nested']) ? $this
->t('when <strong>@logic</strong> of the following conditions are met:', $t_args) : $this
->t('When <strong>@logic</strong> of the following (nested) conditions are met:', $t_args),
];
$build['condition'] = [
'#theme' => 'item_list',
'#items' => $condition_items,
];
return $build;
}
protected function buildConditionItem(WebformInterface $webform, $selector, array $condition, array $options) {
if (WebformArrayHelper::isSequential($condition)) {
$sub_condition_items = [];
foreach ($condition as $sub_condition) {
$sub_condition_items[] = $this
->buildConditionItem($webform, $selector, $sub_condition, $options);
}
return $sub_condition_items;
}
$input_name = WebformSubmissionConditionsValidator::getSelectorInputName($selector);
if (!$input_name) {
return [];
}
$element_key = WebformSubmissionConditionsValidator::getInputNameAsArray($input_name, 0);
$element_option_key = WebformSubmissionConditionsValidator::getInputNameAsArray($input_name, 1);
$element = $webform
->getElement($element_key);
if (!$element && strpos($selector, ':input[name="files[') === 0) {
$element_key = WebformSubmissionConditionsValidator::getInputNameAsArray($input_name, 1);
$element = $webform
->getWebform()
->getElement($element_key);
}
if (!$element) {
return [];
}
$trigger_state = key($condition);
$trigger_value = $condition[$trigger_state];
$element_plugin = $this->elementManager
->getElementInstance($element);
if ($element_plugin instanceof WebformElement) {
return [];
}
if ($trigger_state === 'value' && is_array($trigger_value)) {
$trigger_substate = key($trigger_value);
if (in_array($trigger_substate, [
'pattern',
'!pattern',
'less',
'less_equal',
'greater',
'greater_equal',
'between',
'!between',
])) {
$trigger_state = $trigger_substate;
$trigger_value = reset($trigger_value);
}
}
$element_options = isset($element['#options']) ? OptGroup::flattenOptions($element['#options']) : [];
$element_title = $element['#admin_title'];
if ($element_option_key) {
$element_title .= ': ' . WebformOptionsHelper::getOptionText($element_option_key, $element_options, TRUE);
}
if ($trigger_state === 'checked' && $trigger_value === FALSE) {
$trigger_state = 'unchecked';
$trigger_value = TRUE;
}
elseif ($trigger_state === 'unchecked' && $trigger_value === FALSE) {
$trigger_state = 'checked';
$trigger_value = TRUE;
}
$t_args = [
'@name' => $element_title,
'@trigger' => $options['triggers'][$trigger_state],
];
switch ($trigger_state) {
case 'empty':
case 'filled':
case 'checked':
case 'unchecked':
return [
'#markup' => $this
->t('<strong>@name</strong> @trigger.', $t_args),
];
case 'between':
$range = explode(':', $trigger_value);
$t_args['@min'] = $range[0];
$t_args['@max'] = $range[1];
return [
'#markup' => $this
->t('<strong>@name</strong> @trigger <strong>@min</strong> and <strong>@max</strong>.', $t_args),
];
default:
$t_args['@value'] = isset($element_options[$trigger_value]) ? $element_options[$trigger_value] : $trigger_value;
return [
'#markup' => $this
->t('<strong>@name</strong> @trigger <strong>@value</strong>.', $t_args),
];
}
}
}