-
Notifications
You must be signed in to change notification settings - Fork 118
Expand file tree
/
Copy pathContextFormTrait.php
More file actions
141 lines (124 loc) · 5.45 KB
/
ContextFormTrait.php
File metadata and controls
141 lines (124 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
namespace Drupal\rules\Form\Expression;
use Drupal\Core\Form\FormStateInterface;
use Drupal\rules\Context\ContextConfig;
use Drupal\rules\Context\ContextDefinitionInterface;
/**
* Provides form logic for handling contexts when configuring an expression.
*/
trait ContextFormTrait {
/**
* Provides the form part for a context parameter.
*/
public function buildContextForm(array $form, FormStateInterface $form_state, $context_name, ContextDefinitionInterface $context_definition, array $configuration) {
$form['context'][$context_name] = [
'#type' => 'fieldset',
'#title' => $context_definition->getLabel(),
];
$form['context'][$context_name]['description'] = [
'#markup' => $context_definition->getDescription(),
];
// If the form has been submitted already take the mode from the submitted
// values, otherwise default to existing configuration. And if that does not
// exist default to the "input" mode.
$mode = $form_state->get('context_' . $context_name);
if (!$mode) {
if (isset($configuration['context_mapping'][$context_name])) {
$mode = 'selector';
}
else {
$mode = 'input';
}
$form_state->set('context_' . $context_name, $mode);
}
$title = $mode == 'selector' ? $this->t('Data selector') : $this->t('Value');
if (isset($configuration['context_values'][$context_name])) {
$default_value = $configuration['context_values'][$context_name];
}
elseif (isset($configuration['context_mapping'][$context_name])) {
$default_value = $configuration['context_mapping'][$context_name];
}
else {
$default_value = $context_definition->getDefaultValue();
}
$form['context'][$context_name]['setting'] = [
'#type' => $context_definition->getFormElement(),
'#title' => $title,
'#required' => $context_definition->isRequired(),
'#default_value' => $default_value,
];
$element = &$form['context'][$context_name]['setting'];
if ($mode == 'selector') {
// Always use a textfield for selector mode.
$element['#type'] = 'textfield';
$element['#description'] = $this->t("The data selector helps you drill down into the data available to Rules. <em>To make entity fields appear in the data selector, you may have to use the condition 'entity has field' (or 'content is of type').</em> More useful tips about data selection is available in <a href=':url'>the online documentation</a>.", [
':url' => 'https://www.drupal.org/node/1300042',
]);
$url = $this->getRulesUiHandler()->getUrlFromRoute('autocomplete', []);
$element['#attributes']['class'][] = 'rules-autocomplete';
$element['#attributes']['data-autocomplete-path'] = $url->toString();
$element['#attached']['library'][] = 'rules/rules.autocomplete';
}
elseif ($context_definition->isMultiple()) {
$element['#type'] = 'textarea';
// @todo get a description for possible values that can be filled in.
$element['#description'] = $this->t('Enter one value per line for this multi-valued context.');
// Glue the list of values together as one item per line in the text area.
if (is_array($default_value)) {
$element['#default_value'] = implode("\n", $default_value);
}
}
$value = $mode == 'selector' ? $this->t('Switch to the direct input mode') : $this->t('Switch to data selection');
$form['context'][$context_name]['switch_button'] = [
'#type' => 'submit',
'#name' => 'context_' . $context_name,
'#attributes' => ['class' => ['rules-switch-button']],
'#parameter' => $context_name,
'#value' => $value,
'#submit' => [static::class . '::switchContextMode'],
// Do not validate!
'#limit_validation_errors' => [],
];
return $form;
}
/**
* Creates a context config object from the submitted form values.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The form state containing the submitted values.
* @param \Drupal\Core\Plugin\Context\ContextDefinitionInterface[] $context_definitions
* The context definitions of the plugin.
*
* @return \Drupal\rules\Context\ContextConfig
* The context config object populated with context mappings/values.
*/
protected function getContextConfigFromFormValues(FormStateInterface $form_state, array $context_definitions) {
$context_config = ContextConfig::create();
foreach ($form_state->getValue('context') as $context_name => $value) {
if ($form_state->get("context_$context_name") == 'selector') {
$context_config->map($context_name, $value['setting']);
}
else {
// Each line of the textarea is one value for multiple contexts.
if ($context_definitions[$context_name]->isMultiple()) {
$values = explode("\n", $value['setting']);
$context_config->setValue($context_name, $values);
}
else {
$context_config->setValue($context_name, $value['setting']);
}
}
}
return $context_config;
}
/**
* Submit callback: switch a context to data selecor or direct input mode.
*/
public static function switchContextMode(array &$form, FormStateInterface $form_state) {
$element_name = $form_state->getTriggeringElement()['#name'];
$mode = $form_state->get($element_name);
$switched_mode = $mode == 'selector' ? 'input' : 'selector';
$form_state->set($element_name, $switched_mode);
$form_state->setRebuild();
}
}