Updated to Drupal 8.5. Core Media not yet in use.
[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       drupal_set_message(
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         'warning'
112       );
113     }
114
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         ],
142         'operations' => [
143           '#type' => 'operations',
144           '#links' => $links,
145         ],
146       ];
147     }
148     $form['states_container']['state_add'] = [
149       '#markup' => $workflow->toLink($this->t('Add a new state'), 'add-state-form')->toString(),
150     ];
151
152     $header = [
153       'label' => $this->t('Label'),
154       'weight' => $this->t('Weight'),
155       'from' => $this->t('From'),
156       'to' => $this->t('To'),
157       'operations' => $this->t('Operations')
158     ];
159     $form['transitions_container'] = [
160       '#type' => 'details',
161       '#title' => $this->t('Transitions'),
162       '#open' => TRUE,
163     ];
164     $form['transitions_container']['transitions'] = [
165       '#type' => 'table',
166       '#header' => $header,
167       '#title' => $this->t('Transitions'),
168       '#empty' => $this->t('There are no transitions yet.'),
169       '#tabledrag' => [
170         [
171           'action' => 'order',
172           'relationship' => 'sibling',
173           'group' => 'transition-weight',
174         ],
175       ],
176     ];
177     foreach ($workflow->getTypePlugin()->getTransitions() as $transition) {
178       $links['edit'] = [
179         'title' => $this->t('Edit'),
180         'url' => Url::fromRoute('entity.workflow.edit_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
181       ];
182       $links['delete'] = [
183         'title' => t('Delete'),
184         'url' => Url::fromRoute('entity.workflow.delete_transition_form', ['workflow' => $workflow->id(), 'workflow_transition' => $transition->id()]),
185       ];
186       $form['transitions_container']['transitions'][$transition->id()] = [
187         '#attributes' => ['class' => ['draggable']],
188         'label' => ['#markup' => $transition->label()],
189         '#weight' => $transition->weight(),
190         'weight' => [
191           '#type' => 'weight',
192           '#title' => t('Weight for @title', ['@title' => $transition->label()]),
193           '#title_display' => 'invisible',
194           '#default_value' => $transition->weight(),
195           '#attributes' => ['class' => ['transition-weight']],
196         ],
197         'from' => [
198           '#theme' => 'item_list',
199           '#items' => array_map([State::class, 'labelCallback'], $transition->from()),
200           '#context' => ['list_style' => 'comma-list'],
201         ],
202         'to' => ['#markup' => $transition->to()->label()],
203         'operations' => [
204           '#type' => 'operations',
205           '#links' => $links,
206         ],
207       ];
208     }
209     $form['transitions_container']['transition_add'] = [
210       '#markup' => $workflow->toLink($this->t('Add a new transition'), 'add-transition-form')->toString(),
211     ];
212
213     if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
214       $form['type_settings'] = [
215         '#tree' => TRUE,
216       ];
217       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
218       $form['type_settings'] += $this->pluginFormFactory
219         ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
220         ->buildConfigurationForm($form['type_settings'], $subform_state);
221     }
222
223     return $form;
224   }
225
226   /**
227    * {@inheritdoc}
228    */
229   public function validateForm(array &$form, FormStateInterface $form_state) {
230     /* @var \Drupal\workflows\WorkflowInterface $workflow */
231     $workflow = $this->entity;
232     $workflow_type = $workflow->getTypePlugin();
233
234     if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
235       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
236       $this->pluginFormFactory
237         ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
238         ->validateConfigurationForm($form['type_settings'], $subform_state);
239     }
240   }
241
242   /**
243    * {@inheritdoc}
244    */
245   public function save(array $form, FormStateInterface $form_state) {
246     /* @var \Drupal\workflows\WorkflowInterface $workflow */
247     $workflow = $this->entity;
248     $workflow_type = $workflow->getTypePlugin();
249
250     if ($workflow_type->hasFormClass(WorkflowTypeInterface::PLUGIN_FORM_KEY)) {
251       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
252       $this->pluginFormFactory
253         ->createInstance($workflow_type, WorkflowTypeInterface::PLUGIN_FORM_KEY)
254         ->submitConfigurationForm($form['type_settings'], $subform_state);
255     }
256
257     $workflow->save();
258     drupal_set_message($this->t('Saved the %label Workflow.', ['%label' => $workflow->label()]));
259   }
260
261   /**
262    * {@inheritdoc}
263    */
264   protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
265     // This form can only set the workflow's ID, label and the weights for each
266     // state.
267     /** @var \Drupal\workflows\WorkflowInterface $entity */
268     $values = $form_state->getValues();
269     $entity->set('label', $values['label']);
270     $entity->set('id', $values['id']);
271     foreach ($values['states'] as $state_id => $state_values) {
272       $entity->getTypePlugin()->setStateWeight($state_id, $state_values['weight']);
273     }
274     foreach ($values['transitions'] as $transition_id => $transition_values) {
275       $entity->getTypePlugin()->setTransitionWeight($transition_id, $transition_values['weight']);
276     }
277   }
278
279 }