3 namespace Drupal\workflows\Form;
5 use Drupal\Core\Form\SubformState;
6 use Drupal\Core\Plugin\PluginFormFactoryInterface;
7 use Drupal\workflows\Entity\Workflow;
8 use Drupal\workflows\State;
9 use Drupal\Core\Entity\EntityForm;
10 use Drupal\Core\Entity\EntityInterface;
11 use Drupal\Core\Form\FormStateInterface;
13 use Drupal\workflows\WorkflowTypeInterface;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
17 * The form for editing workflows.
21 class WorkflowEditForm extends EntityForm {
24 * The plugin form factory.
26 * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
28 protected $pluginFormFactory;
31 * Creates an instance of WorkflowStateEditForm.
33 * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
34 * The plugin form factory.
36 public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
37 $this->pluginFormFactory = $pluginFormFactory;
43 public static function create(ContainerInterface $container) {
45 $container->get('plugin_form.factory')
52 public function form(array $form, FormStateInterface $form_state) {
53 $form = parent::form($form, $form_state);
55 /* @var \Drupal\workflows\WorkflowInterface $workflow */
56 $workflow = $this->entity;
57 $workflow_type = $workflow->getTypePlugin();
58 $form['#title'] = $this->t('Edit %label workflow', ['%label' => $workflow->label()]);
61 '#type' => 'textfield',
62 '#title' => $this->t('Label'),
64 '#default_value' => $workflow->label(),
69 '#type' => 'machine_name',
70 '#default_value' => $workflow->id(),
72 'exists' => [Workflow::class, 'load'],
78 'state' => $this->t('State'),
79 'weight' => $this->t('Weight'),
80 'operations' => $this->t('Operations'),
82 $form['states_container'] = [
84 '#title' => $this->t('States'),
86 '#collapsible' => 'FALSE',
88 $form['states_container']['states'] = [
91 '#title' => $this->t('States'),
92 '#empty' => $this->t('There are no states yet.'),
96 'relationship' => 'sibling',
97 'group' => 'state-weight',
102 $states = $workflow->getTypePlugin()->getStates();
104 // Warn the user if there are no states.
105 if (empty($states)) {
106 $this->messenger()->addWarning(
108 'This workflow has no states and will be disabled until there is at least one, <a href=":add-state">add a new state.</a>',
109 [':add-state' => $workflow->toUrl('add-state-form')->toString()]
114 $state_weight_delta = round(count($states) / 2);
115 foreach ($states as $state) {
118 'title' => $this->t('Edit'),
119 'url' => Url::fromRoute('entity.workflow.edit_state_form', ['workflow' => $workflow->id(), 'workflow_state' => $state->id()]),
122 if ($this->entity->access('delete-state:' . $state->id())) {
124 'title' => t('Delete'),
125 'url' => Url::fromRoute('entity.workflow.delete_state_form', [
126 'workflow' => $workflow->id(),
127 'workflow_state' => $state->id(),
131 $form['states_container']['states'][$state->id()] = [
132 '#attributes' => ['class' => ['draggable']],
133 'state' => ['#markup' => $state->label()],
134 '#weight' => $state->weight(),
137 '#title' => t('Weight for @title', ['@title' => $state->label()]),
138 '#title_display' => 'invisible',
139 '#default_value' => $state->weight(),
140 '#attributes' => ['class' => ['state-weight']],
141 '#delta' => $state_weight_delta,
144 '#type' => 'operations',
149 $form['states_container']['state_add'] = [
150 '#markup' => $workflow->toLink($this->t('Add a new state'), 'add-state-form')->toString(),
154 'label' => $this->t('Label'),
155 'weight' => $this->t('Weight'),
156 'from' => $this->t('From'),
157 'to' => $this->t('To'),
158 'operations' => $this->t('Operations'),
160 $form['transitions_container'] = [
161 '#type' => 'details',
162 '#title' => $this->t('Transitions'),
165 $form['transitions_container']['transitions'] = [
167 '#header' => $header,
168 '#title' => $this->t('Transitions'),
169 '#empty' => $this->t('There are no transitions yet.'),
173 'relationship' => 'sibling',
174 'group' => 'transition-weight',
179 $transitions = $workflow->getTypePlugin()->getTransitions();
180 $transition_weight_delta = round(count($transitions) / 2);
181 foreach ($transitions as $transition) {
183 'title' => $this->t('Edit'),
184 'url' => Url::fromRoute('entity.workflow.edit_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
187 'title' => t('Delete'),
188 'url' => Url::fromRoute('entity.workflow.delete_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
190 $form['transitions_container']['transitions'][$transition->id()] = [
191 '#attributes' => ['class' => ['draggable']],
192 'label' => ['#markup' => $transition->label()],
193 '#weight' => $transition->weight(),
196 '#title' => t('Weight for @title', ['@title' => $transition->label()]),
197 '#title_display' => 'invisible',
198 '#default_value' => $transition->weight(),
199 '#attributes' => ['class' => ['transition-weight']],
200 '#delta' => $transition_weight_delta,
203 '#theme' => 'item_list',
204 '#items' => array_map([State::class, 'labelCallback'], $transition->from()),
205 '#context' => ['list_style' => 'comma-list'],
207 'to' => ['#markup' => $transition->to()->label()],
209 '#type' => 'operations',
214 $form['transitions_container']['transition_add'] = [
215 '#markup' => $workflow->toLink($this->t('Add a new transition'), 'add-transition-form')->toString(),
218 if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
219 $form['type_settings'] = [
222 $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
223 $form['type_settings'] += $this->pluginFormFactory
224 ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
225 ->buildConfigurationForm($form['type_settings'], $subform_state);
234 public function validateForm(array &$form, FormStateInterface $form_state) {
235 /* @var \Drupal\workflows\WorkflowInterface $workflow */
236 $workflow = $this->entity;
237 $workflow_type = $workflow->getTypePlugin();
239 if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
240 $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
241 $this->pluginFormFactory
242 ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
243 ->validateConfigurationForm($form['type_settings'], $subform_state);
250 public function save(array $form, FormStateInterface $form_state) {
251 /* @var \Drupal\workflows\WorkflowInterface $workflow */
252 $workflow = $this->entity;
253 $workflow_type = $workflow->getTypePlugin();
255 if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
256 $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
257 $this->pluginFormFactory
258 ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
259 ->submitConfigurationForm($form['type_settings'], $subform_state);
263 $this->messenger()->addStatus($this->t('Saved the %label Workflow.', ['%label' => $workflow->label()]));
269 protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
270 // This form can only set the workflow's ID, label and the weights for each
272 /** @var \Drupal\workflows\WorkflowInterface $entity */
273 $values = $form_state->getValues();
274 $entity->set('label', $values['label']);
275 $entity->set('id', $values['id']);
276 foreach ($values['states'] as $state_id => $state_values) {
277 $entity->getTypePlugin()->setStateWeight($state_id, $state_values['weight']);
279 foreach ($values['transitions'] as $transition_id => $transition_values) {
280 $entity->getTypePlugin()->setTransitionWeight($transition_id, $transition_values['weight']);