diff --git a/src/Element/WorkflowTransitionElement.php b/src/Element/WorkflowTransitionElement.php index d40e545556ed1d6206977f85dc1e3243d81a933b..5871e1a7304b31ea04ff09bb34057ef0bcc5a4a5 100644 --- a/src/Element/WorkflowTransitionElement.php +++ b/src/Element/WorkflowTransitionElement.php @@ -8,6 +8,7 @@ use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Render\Element\FormElement; use Drupal\workflow\Entity\Workflow; use Drupal\workflow\Entity\WorkflowManager; +use Drupal\workflow\Entity\WorkflowTransitionInterface; /** * Provides a form element for the WorkflowTransitionForm and ~Widget. @@ -333,16 +334,14 @@ class WorkflowTransitionElement extends FormElement { * The form. * @param \Drupal\Core\Form\FormStateInterface $form_state * The form state. - * @param array $item + * @param array $values * The field item. * * @return \Drupal\workflow\Entity\WorkflowTransitionInterface * A new Transition object. */ - public static function copyFormValuesToTransition(EntityInterface $transition, array $form, FormStateInterface $form_state, array $item) { + public static function copyFormValuesToTransition(EntityInterface $transition, array $form, FormStateInterface $form_state, array $values) { /** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $transition */ - $values = $item; - $input = $form_state->getUserInput(); // @todo #2287057: verify if submit() really is only used for UI. If not, $user must be passed. $user = workflow_current_user(); @@ -356,7 +355,7 @@ class WorkflowTransitionElement extends FormElement { $action_values = _workflow_transition_form_get_triggering_button($form_state); $to_sid = $action_values['to_sid'] ?? $values['to_sid'][0]['target_id']; // Note: when editing existing Transition, user may still change comments. - $comment = $input['comment'][0]['value'] ?? ''; + $comment = $values['comment'][0]['value'] ?? ''; $timestamp_values = $values['timestamp'][0]['value']; $is_scheduled = (bool) $timestamp_values['scheduled']; $timestamp = WorkflowTransitionTimestamp::valueCallback($timestamp_values, $timestamp_values, $form_state) @@ -409,35 +408,48 @@ class WorkflowTransitionElement extends FormElement { $transition->schedule($is_scheduled); $transition->force($force); } - - // Also add the transition to the ItemList. - $entity = $transition->getTargetEntity(); - $entity->{$field_name}->__set('_workflow_transition', $transition); - - // Add the attached fields. + // Add the attached fields to the transition. // Caveat: This works automatically on a Workflow Form, // but only with a hack on a widget. + // @todo This line seems necessary for node edit, not for node view. // @todo Support 'attached fields' in ScheduledTransition. $fields = WorkflowManager::getAttachedFields('workflow_transition', $transition->bundle()); /** @var \Drupal\Core\Field\Entity\BaseFieldOverride $field */ foreach ($fields as $field_name => $field) { - $user_input = $input[$field_name] ?? []; if (isset($values[$field_name])) { - // @todo This line seems necessary for node edit, not for node view. $transition->{$field_name} = $values[$field_name]; } // #2899025 For each field, let other modules modify the copied values, // as a workaround for not-supported field types. + $input ??= $form_state->getUserInput(); $context = [ 'field' => $field, 'field_name' => $field_name, - 'user_input' => $user_input, + 'user_input' => $input[$field_name] ?? [], 'item' => $values, ]; \Drupal::moduleHandler()->alter('copy_form_values_to_transition_field', $transition, $context); } + + // Also add the transition to the ItemList. + self::updateEntity($form_state, $transition); + return $transition; } + + protected static function updateEntity(FormStateInterface $form_state, WorkflowTransitionInterface $transition) { + // Add value to itemlist in two formats. + //$items->setValue($transition->getToSid()); + //$items->filterEmptyItems(); + // $items->__set('_workflow_transition', $transition); + $entity = $transition->getTargetEntity(); + $field_name = $transition->getFieldName(); + $to_sid = $transition->getToSid(); + $entity->{$field_name}->__set('_workflow_transition', $transition); + $entity->{'to_sid'} = $to_sid; + $form_state->setValue(['to_sid', 0, 'target_id'], $to_sid); + } + } diff --git a/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php b/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php index e1a2013249009fff6cad6d6e02b5ab15161130d0..c1e4c151c73f3dc50b5b0e2dd2e444cf9b002959 100644 --- a/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php +++ b/src/Plugin/Field/FieldWidget/WorkflowDefaultWidget.php @@ -10,6 +10,7 @@ use Drupal\workflow\Element\WorkflowTransitionElement; use Drupal\workflow\Entity\Workflow; use Drupal\workflow\Entity\WorkflowManager; use Drupal\workflow\Entity\WorkflowTransition; +use Drupal\workflow\Entity\WorkflowTransitionInterface; /** * Plugin implementation of the 'workflow_default' widget. @@ -97,7 +98,6 @@ class WorkflowDefaultWidget extends WidgetBase { // Override WidgetBase::extractFormValues() since // it extracts field values without respecting #tree = TRUE. // So, the following function massageFormValues has nothing to do. - $field_name = $this->fieldDefinition->getName(); $transition = $form_state->getValue('_workflow_transition'); $values = ['transition' => @@ -105,26 +105,20 @@ class WorkflowDefaultWidget extends WidgetBase { $form_state->getUserInput() + ['#default_value' => $transition], ]; - $key_exists = TRUE; - if ($key_exists) { - // Let the widget massage the submitted values. - $values = $this->massageFormValues($values, $form, $form_state); - - // Get the new value from an action button if set in the workflow settings. - $action_info = _workflow_transition_form_get_triggering_button($form_state); - if ($field_name == $action_info['field_name']) { - // $values = [0 => $action_info['to_sid']]; - } - - // Assign the values and remove the empty ones. - $items->setValue($values['transition']['value']); - $items->filterEmptyItems(); - // Also add the transition to the ItemList. - $items->__set('_workflow_transition', $transition); - } + // Let the widget massage the submitted values. + $values = $this->massageFormValues($values, $form, $form_state); + // Update the targetEntity. + $this->updateEntity($items, $transition); } + protected function updateEntity($items, WorkflowTransitionInterface $transition) { + // Add value to itemlist in two formats. + $to_sid = $transition->getToSid(); + $items->setValue($to_sid); + $items->filterEmptyItems(); + $items->__set('_workflow_transition', $transition); + } /** * {@inheritdoc} @@ -173,13 +167,6 @@ class WorkflowDefaultWidget extends WidgetBase { // - add to history; add to watchdog // Return the new State ID. (Execution may fail and return the old Sid.) - // Get the new value from an action button if set in the workflow settings. - $action_info = _workflow_transition_form_get_triggering_button($form_state); - $field_name = $transition->getFieldName(); - if ($field_name == $action_info['field_name']) { - $transition->set('to_sid', $action_info['to_sid']); - } - $force = FALSE; // @todo D8-port: add to form for usage in VBO. // Now, save/execute the transition.