Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / workflows / src / Form / WorkflowEditForm.php
1 <?php
2
3 namespace Drupal\workflows\Form;
4
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;
12 use Drupal\Core\Url;
13 use Drupal\workflows\WorkflowTypeInterface;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15
16 /**
17  * The form for editing workflows.
18  *
19  * @internal
20  */
21 class WorkflowEditForm extends EntityForm {
22
23   /**
24    * The plugin form factory.
25    *
26    * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
27    */
28   protected $pluginFormFactory;
29
30   /**
31    * Creates an instance of WorkflowStateEditForm.
32    *
33    * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
34    *   The plugin form factory.
35    */
36   public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
37     $this->pluginFormFactory = $pluginFormFactory;
38   }
39
40   /**
41    * {@inheritdoc}
42    */
43   public static function create(ContainerInterface $container) {
44     return new static(
45       $container->get('plugin_form.factory')
46     );
47   }
48
49   /**
50    * {@inheritdoc}
51    */
52   public function form(array $form, FormStateInterface $form_state) {
53     $form = parent::form($form, $form_state);
54
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()]);
59
60     $form['label'] = [
61       '#type' => 'textfield',
62       '#title' => $this->t('Label'),
63       '#maxlength' => 255,
64       '#default_value' => $workflow->label(),
65       '#required' => TRUE,
66     ];
67
68     $form['id'] = [
69       '#type' => 'machine_name',
70       '#default_value' => $workflow->id(),
71       '#machine_name' => [
72         'exists' => [Workflow::class, 'load'],
73       ],
74       '#disabled' => TRUE,
75     ];
76
77     $header = [
78       'state' => $this->t('State'),
79       'weight' => $this->t('Weight'),
80       'operations' => $this->t('Operations'),
81     ];
82     $form['states_container'] = [
83       '#type' => 'details',
84       '#title' => $this->t('States'),
85       '#open' => TRUE,
86       '#collapsible' => 'FALSE',
87     ];
88     $form['states_container']['states'] = [
89       '#type' => 'table',
90       '#header' => $header,
91       '#title' => $this->t('States'),
92       '#empty' => $this->t('There are no states yet.'),
93       '#tabledrag' => [
94         [
95           'action' => 'order',
96           'relationship' => 'sibling',
97           'group' => 'state-weight',
98         ],
99       ],
100     ];
101
102     $states = $workflow->getTypePlugin()->getStates();
103
104     // Warn the user if there are no states.
105     if (empty($states)) {
106       $this->messenger()->addWarning(
107         $this->t(
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()]
110         )
111       );
112     }
113
114     $state_weight_delta = round(count($states) / 2);
115     foreach ($states as $state) {
116       $links = [
117         'edit' => [
118           'title' => $this->t('Edit'),
119           'url' => Url::fromRoute('entity.workflow.edit_state_form', ['workflow' => $workflow->id(), 'workflow_state' => $state->id()]),
120         ],
121       ];
122       if ($this->entity->access('delete-state:' . $state->id())) {
123         $links['delete'] = [
124           'title' => t('Delete'),
125           'url' => Url::fromRoute('entity.workflow.delete_state_form', [
126             'workflow' => $workflow->id(),
127             'workflow_state' => $state->id(),
128           ]),
129         ];
130       }
131       $form['states_container']['states'][$state->id()] = [
132         '#attributes' => ['class' => ['draggable']],
133         'state' => ['#markup' => $state->label()],
134         '#weight' => $state->weight(),
135         'weight' => [
136           '#type' => '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,
142         ],
143         'operations' => [
144           '#type' => 'operations',
145           '#links' => $links,
146         ],
147       ];
148     }
149     $form['states_container']['state_add'] = [
150       '#markup' => $workflow->toLink($this->t('Add a new state'), 'add-state-form')->toString(),
151     ];
152
153     $header = [
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'),
159     ];
160     $form['transitions_container'] = [
161       '#type' => 'details',
162       '#title' => $this->t('Transitions'),
163       '#open' => TRUE,
164     ];
165     $form['transitions_container']['transitions'] = [
166       '#type' => 'table',
167       '#header' => $header,
168       '#title' => $this->t('Transitions'),
169       '#empty' => $this->t('There are no transitions yet.'),
170       '#tabledrag' => [
171         [
172           'action' => 'order',
173           'relationship' => 'sibling',
174           'group' => 'transition-weight',
175         ],
176       ],
177     ];
178
179     $transitions = $workflow->getTypePlugin()->getTransitions();
180     $transition_weight_delta = round(count($transitions) / 2);
181     foreach ($transitions as $transition) {
182       $links['edit'] = [
183         'title' => $this->t('Edit'),
184         'url' => Url::fromRoute('entity.workflow.edit_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
185       ];
186       $links['delete'] = [
187         'title' => t('Delete'),
188         'url' => Url::fromRoute('entity.workflow.delete_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
189       ];
190       $form['transitions_container']['transitions'][$transition->id()] = [
191         '#attributes' => ['class' => ['draggable']],
192         'label' => ['#markup' => $transition->label()],
193         '#weight' => $transition->weight(),
194         'weight' => [
195           '#type' => '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,
201         ],
202         'from' => [
203           '#theme' => 'item_list',
204           '#items' => array_map([State::class, 'labelCallback'], $transition->from()),
205           '#context' => ['list_style' => 'comma-list'],
206         ],
207         'to' => ['#markup' => $transition->to()->label()],
208         'operations' => [
209           '#type' => 'operations',
210           '#links' => $links,
211         ],
212       ];
213     }
214     $form['transitions_container']['transition_add'] = [
215       '#markup' => $workflow->toLink($this->t('Add a new transition'), 'add-transition-form')->toString(),
216     ];
217
218     if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
219       $form['type_settings'] = [
220         '#tree' => TRUE,
221       ];
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);
226     }
227
228     return $form;
229   }
230
231   /**
232    * {@inheritdoc}
233    */
234   public function validateForm(array &$form, FormStateInterface $form_state) {
235     /* @var \Drupal\workflows\WorkflowInterface $workflow */
236     $workflow = $this->entity;
237     $workflow_type = $workflow->getTypePlugin();
238
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);
244     }
245   }
246
247   /**
248    * {@inheritdoc}
249    */
250   public function save(array $form, FormStateInterface $form_state) {
251     /* @var \Drupal\workflows\WorkflowInterface $workflow */
252     $workflow = $this->entity;
253     $workflow_type = $workflow->getTypePlugin();
254
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);
260     }
261
262     $workflow->save();
263     $this->messenger()->addStatus($this->t('Saved the %label Workflow.', ['%label' => $workflow->label()]));
264   }
265
266   /**
267    * {@inheritdoc}
268    */
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
271     // state.
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']);
278     }
279     foreach ($values['transitions'] as $transition_id => $transition_values) {
280       $entity->getTypePlugin()->setTransitionWeight($transition_id, $transition_values['weight']);
281     }
282   }
283
284 }