Security update for Core, with self-updated composer
[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 class WorkflowEditForm extends EntityForm {
20
21   /**
22    * The plugin form factory.
23    *
24    * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
25    */
26   protected $pluginFormFactory;
27
28   /**
29    * Creates an instance of WorkflowStateEditForm.
30    *
31    * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
32    *   The plugin form factory.
33    */
34   public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
35     $this->pluginFormFactory = $pluginFormFactory;
36   }
37
38   /**
39    * {@inheritdoc}
40    */
41   public static function create(ContainerInterface $container) {
42     return new static(
43       $container->get('plugin_form.factory')
44     );
45   }
46
47   /**
48    * {@inheritdoc}
49    */
50   public function form(array $form, FormStateInterface $form_state) {
51     $form = parent::form($form, $form_state);
52
53     /* @var \Drupal\workflows\WorkflowInterface $workflow */
54     $workflow = $this->entity;
55     $workflow_type = $workflow->getTypePlugin();
56     $form['#title'] = $this->t('Edit %label workflow', ['%label' => $workflow->label()]);
57
58     $form['label'] = [
59       '#type' => 'textfield',
60       '#title' => $this->t('Label'),
61       '#maxlength' => 255,
62       '#default_value' => $workflow->label(),
63       '#required' => TRUE,
64     ];
65
66     $form['id'] = [
67       '#type' => 'machine_name',
68       '#default_value' => $workflow->id(),
69       '#machine_name' => [
70         'exists' => [Workflow::class, 'load'],
71       ],
72       '#disabled' => TRUE,
73     ];
74
75     $header = [
76       'state' => $this->t('State'),
77       'weight' => $this->t('Weight'),
78       'operations' => $this->t('Operations')
79     ];
80     $form['states_container'] = [
81       '#type' => 'details',
82       '#title' => $this->t('States'),
83       '#open' => TRUE,
84       '#collapsible' => 'FALSE',
85     ];
86     $form['states_container']['states'] = [
87       '#type' => 'table',
88       '#header' => $header,
89       '#title' => $this->t('States'),
90       '#empty' => $this->t('There are no states yet.'),
91       '#tabledrag' => [
92         [
93           'action' => 'order',
94           'relationship' => 'sibling',
95           'group' => 'state-weight',
96         ],
97       ],
98     ];
99
100     $states = $workflow->getTypePlugin()->getStates();
101
102     // Warn the user if there are no states.
103     if (empty($states)) {
104       drupal_set_message(
105         $this->t(
106           'This workflow has no states and will be disabled until there is at least one, <a href=":add-state">add a new state.</a>',
107           [':add-state' => $workflow->toUrl('add-state-form')->toString()]
108         ),
109         'warning'
110       );
111     }
112
113     foreach ($states as $state) {
114       $links = [
115         'edit' => [
116           'title' => $this->t('Edit'),
117           'url' => Url::fromRoute('entity.workflow.edit_state_form', ['workflow' => $workflow->id(), 'workflow_state' => $state->id()]),
118         ]
119       ];
120       if ($this->entity->access('delete-state:' . $state->id())) {
121         $links['delete'] = [
122           'title' => t('Delete'),
123           'url' => Url::fromRoute('entity.workflow.delete_state_form', [
124             'workflow' => $workflow->id(),
125             'workflow_state' => $state->id()
126           ]),
127         ];
128       }
129       $form['states_container']['states'][$state->id()] = [
130         '#attributes' => ['class' => ['draggable']],
131         'state' => ['#markup' => $state->label()],
132         '#weight' => $state->weight(),
133         'weight' => [
134           '#type' => 'weight',
135           '#title' => t('Weight for @title', ['@title' => $state->label()]),
136           '#title_display' => 'invisible',
137           '#default_value' => $state->weight(),
138           '#attributes' => ['class' => ['state-weight']],
139         ],
140         'operations' => [
141           '#type' => 'operations',
142           '#links' => $links,
143         ],
144       ];
145     }
146     $form['states_container']['state_add'] = [
147       '#markup' => $workflow->toLink($this->t('Add a new state'), 'add-state-form')->toString(),
148     ];
149
150     $header = [
151       'label' => $this->t('Label'),
152       'weight' => $this->t('Weight'),
153       'from' => $this->t('From'),
154       'to' => $this->t('To'),
155       'operations' => $this->t('Operations')
156     ];
157     $form['transitions_container'] = [
158       '#type' => 'details',
159       '#title' => $this->t('Transitions'),
160       '#open' => TRUE,
161     ];
162     $form['transitions_container']['transitions'] = [
163       '#type' => 'table',
164       '#header' => $header,
165       '#title' => $this->t('Transitions'),
166       '#empty' => $this->t('There are no transitions yet.'),
167       '#tabledrag' => [
168         [
169           'action' => 'order',
170           'relationship' => 'sibling',
171           'group' => 'transition-weight',
172         ],
173       ],
174     ];
175     foreach ($workflow->getTypePlugin()->getTransitions() as $transition) {
176       $links['edit'] = [
177         'title' => $this->t('Edit'),
178         'url' => Url::fromRoute('entity.workflow.edit_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
179       ];
180       $links['delete'] = [
181         'title' => t('Delete'),
182         'url' => Url::fromRoute('entity.workflow.delete_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
183       ];
184       $form['transitions_container']['transitions'][$transition->id()] = [
185         '#attributes' => ['class' => ['draggable']],
186         'label' => ['#markup' => $transition->label()],
187         '#weight' => $transition->weight(),
188         'weight' => [
189           '#type' => 'weight',
190           '#title' => t('Weight for @title', ['@title' => $transition->label()]),
191           '#title_display' => 'invisible',
192           '#default_value' => $transition->weight(),
193           '#attributes' => ['class' => ['transition-weight']],
194         ],
195         'from' => [
196           '#theme' => 'item_list',
197           '#items' => array_map([State::class, 'labelCallback'], $transition->from()),
198           '#context' => ['list_style' => 'comma-list'],
199         ],
200         'to' => ['#markup' => $transition->to()->label()],
201         'operations' => [
202           '#type' => 'operations',
203           '#links' => $links,
204         ],
205       ];
206     }
207     $form['transitions_container']['transition_add'] = [
208       '#markup' => $workflow->toLink($this->t('Add a new transition'), 'add-transition-form')->toString(),
209     ];
210
211     if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
212       $form['type_settings'] = [
213         '#tree' => TRUE,
214       ];
215       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
216       $form['type_settings'] += $this->pluginFormFactory
217         ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
218         ->buildConfigurationForm($form['type_settings'], $subform_state);
219     }
220
221     return $form;
222   }
223
224   /**
225    * {@inheritdoc}
226    */
227   public function validateForm(array &$form, FormStateInterface $form_state) {
228     /* @var \Drupal\workflows\WorkflowInterface $workflow */
229     $workflow = $this->entity;
230     $workflow_type = $workflow->getTypePlugin();
231
232     if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
233       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
234       $this->pluginFormFactory
235         ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
236         ->validateConfigurationForm($form['type_settings'], $subform_state);
237     }
238   }
239
240   /**
241    * {@inheritdoc}
242    */
243   public function save(array $form, FormStateInterface $form_state) {
244     /* @var \Drupal\workflows\WorkflowInterface $workflow */
245     $workflow = $this->entity;
246     $workflow_type = $workflow->getTypePlugin();
247
248     if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
249       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
250       $this->pluginFormFactory
251         ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
252         ->submitConfigurationForm($form['type_settings'], $subform_state);
253     }
254
255     $workflow->save();
256     drupal_set_message($this->t('Saved the %label Workflow.', ['%label' => $workflow->label()]));
257   }
258
259   /**
260    * {@inheritdoc}
261    */
262   protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
263     // This form can only set the workflow's ID, label and the weights for each
264     // state.
265     /** @var \Drupal\workflows\WorkflowInterface $entity */
266     $values = $form_state->getValues();
267     $entity->set('label', $values['label']);
268     $entity->set('id', $values['id']);
269     foreach ($values['states'] as $state_id => $state_values) {
270       $entity->getTypePlugin()->setStateWeight($state_id, $state_values['weight']);
271     }
272     foreach ($values['transitions'] as $transition_id => $transition_values) {
273       $entity->getTypePlugin()->setTransitionWeight($transition_id, $transition_values['weight']);
274     }
275   }
276
277 }