ab4a4c1c6501f6e279b6676a985e4f12700fb9b5
[yaffs-website] / web / core / modules / workflows / src / Form / WorkflowStateAddForm.php
1 <?php
2
3 namespace Drupal\workflows\Form;
4
5 use Drupal\Core\Entity\EntityForm;
6 use Drupal\Core\Entity\EntityInterface;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\Core\Form\SubformState;
9 use Drupal\Core\Plugin\PluginFormFactoryInterface;
10 use Drupal\workflows\StateInterface;
11 use Symfony\Component\DependencyInjection\ContainerInterface;
12
13 /**
14  * Class WorkflowStateAddForm.
15  */
16 class WorkflowStateAddForm extends EntityForm {
17
18   /**
19    * The plugin form factory.
20    *
21    * @var \Drupal\Core\Plugin\PluginFormFactoryInterface
22    */
23   protected $pluginFormFactory;
24
25   /**
26    * Creates an instance of WorkflowStateEditForm.
27    *
28    * @param \Drupal\Core\Plugin\PluginFormFactoryInterface $pluginFormFactory
29    *   The plugin form factory.
30    */
31   public function __construct(PluginFormFactoryInterface $pluginFormFactory) {
32     $this->pluginFormFactory = $pluginFormFactory;
33   }
34
35   /**
36    * {@inheritdoc}
37    */
38   public static function create(ContainerInterface $container) {
39     return new static(
40       $container->get('plugin_form.factory')
41     );
42   }
43
44   /**
45    * {@inheritdoc}
46    */
47   public function getFormId() {
48     return 'workflow_state_add_form';
49   }
50
51   /**
52    * {@inheritdoc}
53    */
54   public function form(array $form, FormStateInterface $form_state) {
55     $form = parent::form($form, $form_state);
56
57     /* @var \Drupal\workflows\WorkflowInterface $workflow */
58     $workflow = $this->getEntity();
59     $workflow_type = $workflow->getTypePlugin();
60
61     $form['label'] = [
62       '#type' => 'textfield',
63       '#title' => $this->t('Label'),
64       '#maxlength' => 255,
65       '#default_value' => '',
66       '#description' => $this->t('Label for the state.'),
67       '#required' => TRUE,
68     ];
69
70     $form['id'] = [
71       '#type' => 'machine_name',
72       '#machine_name' => [
73         'exists' => [$this, 'exists'],
74       ],
75     ];
76
77     if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) {
78       $form['type_settings'] = [
79         '#tree' => TRUE,
80       ];
81       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
82       $form['type_settings'] += $this->pluginFormFactory
83         ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY)
84         ->buildConfigurationForm($form['type_settings'], $subform_state);
85     }
86
87     return $form;
88   }
89
90   /**
91    * Determines if the workflow state already exists.
92    *
93    * @param string $state_id
94    *   The workflow state ID.
95    *
96    * @return bool
97    *   TRUE if the workflow state exists, FALSE otherwise.
98    */
99   public function exists($state_id) {
100     /** @var \Drupal\workflows\WorkflowInterface $original_workflow */
101     $original_workflow = \Drupal::entityTypeManager()->getStorage('workflow')->loadUnchanged($this->getEntity()->id());
102     return $original_workflow->getTypePlugin()->hasState($state_id);
103   }
104
105   /**
106    * Copies top-level form values to entity properties
107    *
108    * This form can only change values for a state, which is part of workflow.
109    *
110    * @param \Drupal\Core\Entity\EntityInterface $entity
111    *   The entity the current form should operate upon.
112    * @param array $form
113    *   A nested array of form elements comprising the form.
114    * @param \Drupal\Core\Form\FormStateInterface $form_state
115    *   The current state of the form.
116    */
117   protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
118     /** @var \Drupal\workflows\WorkflowInterface $entity */
119     $values = $form_state->getValues();
120     $type_plugin = $entity->getTypePlugin();
121
122     // Replicate the validation that Workflow::addState() does internally as the
123     // form values have not been validated at this point.
124     if (!$type_plugin->hasState($values['id']) && !preg_match('/[^a-z0-9_]+/', $values['id'])) {
125       $type_plugin->addState($values['id'], $values['label']);
126     }
127   }
128
129   /**
130    * {@inheritdoc}
131    */
132   public function validateForm(array &$form, FormStateInterface $form_state) {
133     parent::validateForm($form, $form_state);
134     /** @var \Drupal\workflows\WorkflowTypeInterface $workflow_type */
135     $workflow = $this->entity;
136     $workflow_type = $workflow->getTypePlugin();
137
138     if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) {
139       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
140       $this->pluginFormFactory
141         ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY)
142         ->validateConfigurationForm($form['type_settings'], $subform_state);
143     }
144   }
145
146   /**
147    * {@inheritdoc}
148    */
149   public function save(array $form, FormStateInterface $form_state) {
150     /** @var \Drupal\workflows\WorkflowInterface $workflow */
151     $workflow = $this->entity;
152     $workflow_type = $workflow->getTypePlugin();
153     $state = $workflow_type->getState($form_state->getValue('id'));
154
155     if ($workflow_type->hasFormClass(StateInterface::PLUGIN_FORM_KEY)) {
156       $subform_state = SubformState::createForSubform($form['type_settings'], $form, $form_state);
157       $subform_state->set('state', $state);
158       $this->pluginFormFactory
159         ->createInstance($workflow_type, StateInterface::PLUGIN_FORM_KEY)
160         ->submitConfigurationForm($form['type_settings'], $subform_state);
161     }
162
163     $workflow->save();
164     drupal_set_message($this->t('Created %label state.', [
165       '%label' => $workflow->getTypePlugin()->getState($form_state->getValue('id'))->label(),
166     ]));
167     $form_state->setRedirectUrl($workflow->toUrl('edit-form'));
168   }
169
170   /**
171    * {@inheritdoc}
172    */
173   protected function actions(array $form, FormStateInterface $form_state) {
174     $actions['submit'] = [
175       '#type' => 'submit',
176       '#value' => $this->t('Save'),
177       '#submit' => ['::submitForm', '::save'],
178     ];
179     return $actions;
180   }
181
182 }