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