Skip to content
Snippets Groups Projects
Commit 2a39ba4a authored by John Voskuilen's avatar John Voskuilen
Browse files

Issue #3508157: New transition is not properly created in 8.x-1.8

parent 0eda1aa8
No related branches found
No related tags found
No related merge requests found
Pipeline #430192 passed with warnings
......@@ -238,7 +238,7 @@ class WorkflowTransitionElement extends FormElement {
// @todo Repair $workflow->'name_as_title': no container if no details (schedule/comment).
$attribute_name = 'to_sid';
$attribute_key = 'target_id';
$element[$attribute_name]['widget'][0][$attribute_key] = [
$widget = [
// Avoid error with grouped options when workflow not set.
'#type' => ($wid) ? $options_type : 'select',
'#title' => (!$workflow_settings['name_as_title'] && !$transition->isExecuted())
......@@ -252,7 +252,8 @@ class WorkflowTransitionElement extends FormElement {
// Remove autocomplete settings from BaseFieldDefinitions().
'#maxlength' => 999,
'#size' => 0,
] + ($element[$attribute_name]['widget'][0][$attribute_key] ?? []);
];
self::updateWidget($element[$attribute_name]['widget'], $attribute_key, $widget);
if (_workflow_use_action_buttons($options_type)) {
// In WorkflowTransitionForm, a default 'Submit' button is added there.
......@@ -263,26 +264,28 @@ class WorkflowTransitionElement extends FormElement {
// It will be replaced by action buttons, but sometimes, the select box
// is still shown.
// @see workflow_form_alter().
$element[$attribute_name]['widget'][0][$attribute_key] = [
$widget = [
'#type' => 'select',
'#access' => FALSE,
] + ($element[$attribute_name]['widget'][0][$attribute_key] ?? []);
];
self::updateWidget($element[$attribute_name]['widget'], $attribute_key, $widget);
}
// Display scheduling form under certain conditions.
$attribute_name = 'timestamp';
$attribute_key = 'value';
$element[$attribute_name]['widget'][0][$attribute_key] = [
$widget = [
'#type' => 'workflow_transition_timestamp',
'#default_value' => $transition,
// '#default_value' => new DrupalDateTime('2000-01-01 00:00:00'),
] + ($element[$attribute_name]['widget'][0][$attribute_key] ?? []);
];
self::updateWidget($element[$attribute_name]['widget'], $attribute_key, $widget);
// Show comment, when both Field and Instance allow this.
// This overrides BaseFieldDefinition.
$attribute_name = 'comment';
$attribute_key = 'value';
$element[$attribute_name]['widget'][0][$attribute_key] = [
$widget = [
'#type' => 'textarea',
'#title' => t('Comment'),
'#description' => t('Briefly describe the changes you have made.'),
......@@ -290,8 +293,10 @@ class WorkflowTransitionElement extends FormElement {
'#default_value' => $transition->getComment(),
'#weight' => $field_weight,
'#required' => $workflow_settings['comment_log_node'] == '2',
] + ($element[$attribute_name]['widget'][0][$attribute_key] ?? []);
];
self::updateWidget($element[$attribute_name]['widget'], $attribute_key, $widget);
// There is no standard widget for 'force' (yet).
$element['force'] = [
'#type' => 'checkbox',
'#title' => t('Force transition'),
......@@ -305,6 +310,28 @@ class WorkflowTransitionElement extends FormElement {
return $element;
}
/**
* Adds the workflow attributes to the standard attribute of each widget.
*
* For some reason, the widgets are in another level when the entity form page
* is presented, then when the entity form page is submitted.
*
* @param array $haystack
* The array in which the widget is hidden.
* @param string $attribute_key
* The widget key.
* @param array $data
* The additional workflow data for the widget.
*/
protected static function updateWidget(array &$haystack, string $attribute_key, array $data) {
if (isset($haystack[0][$attribute_key])) {
$haystack[0][$attribute_key] = $data + $haystack[0][$attribute_key];
}
else {
$haystack[$attribute_key] = $data + $haystack[$attribute_key];
}
}
/**
* Returns a unique string identifying the form.
*
......@@ -357,7 +384,7 @@ class WorkflowTransitionElement extends FormElement {
// Note: when editing existing Transition, user may still change comments.
$comment = $values['comment'][0]['value'] ?? '';
// @todo Why is 'timestamp' empty at create Node - when is it unset?
$timestamp_values ??= $values['widget']['timestamp'][0]['value'] ?? NULL;
$timestamp_values = $values['widget']['timestamp'][0]['value'] ?? NULL;
$timestamp_values ??= $values['timestamp'][0]['value'] ?? NULL;
$timestamp_values ??= ['scheduled' => false];
$is_scheduled = (bool) $timestamp_values['scheduled'];
......
......@@ -310,8 +310,7 @@ class Workflow extends ConfigEntityBase implements WorkflowInterface {
$creation_state = $this->getCreationState();
$options = $creation_state->getOptions($entity, $field_name, $user, $force);
if ($options) {
$keys = array_keys($options);
$sid = $keys[0];
$sid = array_key_first($options);
}
else {
// This should never happen, but it did during testing.
......
......@@ -485,7 +485,7 @@ class WorkflowState extends ConfigEntityBase {
// Define an Entity-specific cache per page load.
static $cache = [];
$entity_id = ($entity) ? $entity->id() : '';
$entity_id = ($entity) ? $entity->id() ?? '' : '';
$entity_type_id = ($entity) ? $entity->getEntityTypeId() : '';
$current_sid = $this->id();
......
......@@ -165,7 +165,7 @@ class WorkflowTransition extends ContentEntityBase implements WorkflowTransition
public static function create(array $values = []) {
$state = $values[0] ?? NULL;
switch (TRUE) {
// First paramter must be State object or State ID.
// First parameter must be State object or State ID.
case is_string($state):
$state = WorkflowState::load($state);
case $state instanceof WorkflowState:
......
......@@ -78,7 +78,7 @@ class WorkflowTransitionForm extends ContentEntityForm {
/** @var \Drupal\Core\Entity\EntityFormBuilder $entity_form_builder */
$entity_form_builder = \Drupal::getContainer()->get('entity.form_builder');
$transition = WorkflowTransitionForm::getDefaultTransition($entity, $field_name, $transition);
$transition ??= WorkflowTransitionForm::getDefaultTransition($entity, $field_name, $transition);
//@todo Check if WorkflowDefaultWidget::createInstance() can be used.
$form = $entity_form_builder->getForm($transition, 'add', $form_state_additions);
return $form;
......@@ -88,19 +88,7 @@ class WorkflowTransitionForm extends ContentEntityForm {
* {@inheritdoc}
*/
public static function getDefaultTransition(EntityInterface $entity, $field_name, ?WorkflowTransitionInterface $transition = NULL): WorkflowTransitionInterface {
$entity_type_id = $entity->getEntityTypeId();
$entity_id = $entity->id();
// Only 1 scheduled transition can be found, but multiple executed ones.
$transition ??= isset($entity->{$field_name}[0]) ? $entity->{$field_name}[0]->getTransition() : NULL;
$transition ??= WorkflowScheduledTransition::loadByProperties($entity_type_id, $entity_id, [], $field_name);
if (!$transition) {
// Create a transition, to pass to the form. No need to use setValues().
$current_sid = workflow_node_current_state($entity, $field_name);
$transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]);
$transition->setTargetEntity($entity);
}
return $transition;
return workflow_get_transition($entity, $field_name, $transition);
}
public static function trimWorkflowTransitionForm(array $workflow_form, WorkflowTransition $transition) {
......
......@@ -79,7 +79,7 @@ function _workflow_transition_form_get_first_workflow_element(&$form) {
return $form;
}
// We are on node edit page. First fetche the field.
// We are on node edit page. First fetche th field.
$workflow_element = [];
foreach (Element::children($form) as $key) {
$transition = $form[$key]['widget'][0]['#default_value'] ?? NULL;
......@@ -229,8 +229,8 @@ function _workflow_transition_form_get_triggering_button(WorkflowTransitionInter
// Field_name may not exist due to '#access' = false.
$result['field_name'] = $input['field_name'] ?? NULL;
// To_sid is taken from the Workflow widget, not from the button.
$result['to_sid'] ??= $input['widget']['to_sid'][0]['target_id'] ?? NULL;
$result['to_sid'] ??= $input['to_sid'][0]['target_id'] ?? NULL;
$result['to_sid'] ??= $input['widget']['to_sid'][0]['target_id'] ?? $input['widget']['to_sid']['target_id'] ?? NULL;
$result['to_sid'] ??= $input['to_sid'][0]['target_id'] ?? $input['to_sid']['target_id'] ?? NULL;
}
// Try to get new Sid from a value. (@todo When is this?)
$result['to_sid'] ??= $values['to_sid'][0]['target_id'] ?? NULL;
......
......@@ -16,7 +16,9 @@ use Drupal\user\Entity\User;
use Drupal\user\RoleInterface;
use Drupal\workflow\Entity\Workflow;
use Drupal\workflow\Entity\WorkflowManager;
use Drupal\workflow\Entity\WorkflowScheduledTransition;
use Drupal\workflow\Entity\WorkflowState;
use Drupal\workflow\Entity\WorkflowTransition;
use Drupal\workflow\Entity\WorkflowTransitionInterface;
define('WORKFLOW_CREATION_STATE', 1);
......@@ -227,6 +229,28 @@ function workflow_get_user_role_names(string $permission = '') {
return $role_names[$permission];
}
/**
* {@inheritdoc}
*/
function workflow_get_transition(EntityInterface $entity, $field_name, ?WorkflowTransitionInterface $transition = NULL): WorkflowTransitionInterface {
$transition ??= $entity->{$field_name}[0]
? $entity->{$field_name}[0]->getTransition()
: NULL;
// Only 1 scheduled transition can be found, but multiple executed ones.
$transition ??= WorkflowScheduledTransition::loadByProperties(
$entity->getEntityTypeId(),
$entity->id(),
[],
$field_name);
if (!$transition) {
// Create a transition, to pass to the form. No need to use setValues().
$current_sid = workflow_node_current_state($entity, $field_name);
$transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name]);
$transition->setTargetEntity($entity);
}
return $transition;
}
/**
* Get an options list for workflow states.
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment