From 76e19416fa212cf2712d932fa3f5a4e7726b2c94 Mon Sep 17 00:00:00 2001
From: John Voskuilen <john.voskuilen@sapito.nl>
Date: Wed, 26 Mar 2025 00:24:28 +0100
Subject: [PATCH] Issue #3513418 by johnv, dcoppel, arunsahijpal, spiderman: In
 formatter, show State label, not Transition label

---
 src/Entity/WorkflowState.php                  |  2 ++
 src/Entity/WorkflowTargetEntity.php           |  2 +-
 .../WorkflowDefaultFormatter.php              |  5 ++++
 src/Plugin/Field/FieldType/WorkflowItem.php   | 29 +++++++------------
 workflow.module                               |  9 ++++--
 5 files changed, 25 insertions(+), 22 deletions(-)

diff --git a/src/Entity/WorkflowState.php b/src/Entity/WorkflowState.php
index b3d4ae95..9a13e5ad 100644
--- a/src/Entity/WorkflowState.php
+++ b/src/Entity/WorkflowState.php
@@ -498,6 +498,8 @@ class WorkflowState extends ConfigEntityBase implements WorkflowStateInterface {
       $options = $workflow->getStates(WorkflowInterface::ACTIVE_CREATION_STATES);
     }
     elseif ($current_sid) {
+      // This is called by FormatterBase->view();
+      // which calls WorkflowItem->getPossibleOptions();
       $transitions = $this->getTransitions($entity, $field_name, $account, $force);
     }
     elseif ($entity->{$field_name}->value ?? NULL) {
diff --git a/src/Entity/WorkflowTargetEntity.php b/src/Entity/WorkflowTargetEntity.php
index 48223d2a..80461c25 100644
--- a/src/Entity/WorkflowTargetEntity.php
+++ b/src/Entity/WorkflowTargetEntity.php
@@ -297,7 +297,7 @@ class WorkflowTargetEntity {
     $item = $entity->{$field_name}[0] ?? NULL;
     $transition ??= $item ? $item->getTransition() : NULL;
 
-    // For VBO, a dummy node has been created.
+    // For VBO, a dummy entity has been created.
     $transition ??= WorkflowTransition::create(['entity' => $entity, 'field_name' => $field_name]);
 
     return $transition;
diff --git a/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php b/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php
index f17d1f64..ce96f497 100644
--- a/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/WorkflowDefaultFormatter.php
@@ -147,6 +147,11 @@ class WorkflowDefaultFormatter extends FormatterBase implements ContainerFactory
       return $elements;
     }
 
+    if (!$entity->{$field_name}->first()) {
+      // An entity can exist already before adding the workflow field.
+      return $elements;
+    }
+
     // Only build form if user has possible target state(s).
     $transition = $entity->{$field_name}->first()->getTransition();
     if (!WorkflowTransitionElement::showWidget($transition)) {
diff --git a/src/Plugin/Field/FieldType/WorkflowItem.php b/src/Plugin/Field/FieldType/WorkflowItem.php
index 1fc3d2ec..799c6116 100644
--- a/src/Plugin/Field/FieldType/WorkflowItem.php
+++ b/src/Plugin/Field/FieldType/WorkflowItem.php
@@ -248,9 +248,11 @@ class WorkflowItem extends ListItemBase {
    */
   public function getState() {
     $sid = $this->getStateId();
-    $wid = $this->getFieldDefinition()->getSetting('workflow_type');
-    $values = ['id' => $sid, 'wid' => $wid];
-    $state = WorkflowState::create($values);
+    $state = WorkflowState::load($sid)
+      ?? WorkflowState::create([
+        'id' => $sid,
+        'wid' => $this->getFieldDefinition()->getSetting('workflow_type'),
+      ]);
     return $state;
   }
 
@@ -283,22 +285,11 @@ class WorkflowItem extends ListItemBase {
       return $transition;
     }
 
-    // @todo Move to WorkflowTransition::getDefaultStateId().
     // Create a transition, to pass to the form.
-    $user = workflow_current_user();
+    // @todo $this->set('_workflow_transition'); (?)
     $entity = $this->getEntity();
     $field_name = $this->getParent()->getName();
-    $current_sid = $entity->isNew()
-      ? WorkflowTargetEntity::getCreationStateId($entity, $field_name)
-      : $this->value;
-
-    if (!$current_sid) {
-      return $transition;
-    }
-
-    $transition = WorkflowTransition::create([$current_sid, 'field_name' => $field_name])
-      ->setTargetEntity($entity);
-
+    $transition = WorkflowTransition::create(['entity' => $entity, 'field_name' => $field_name]);
     return $transition;
   }
 
@@ -406,9 +397,9 @@ class WorkflowItem extends ListItemBase {
       $field_name = $this->getParent()->getName();
       $user = workflow_current_user();
 
-      $sid = workflow_node_current_state($entity, $field_name);
-      $state = $workflow->getState($sid);
-      $allowed_options = $state->getOptions($entity, $field_name, $user, FALSE);
+      $field_config = $entity->get($field_name)->getFieldDefinition();
+      $field_storage = $field_config->getFieldStorageDefinition();
+      $allowed_options = workflow_state_allowed_values($field_storage, $entity);
     }
 
     return $allowed_options;
diff --git a/workflow.module b/workflow.module
index 4a50c92d..07a68556 100644
--- a/workflow.module
+++ b/workflow.module
@@ -223,10 +223,10 @@ function workflow_state_allowed_values(FieldStorageDefinitionInterface $field_st
   // Note: $cacheable is a reference.
   $cacheable = FALSE;
 
+  $field_name = $field_storage_definition->getName();
   switch (TRUE) {
     case $entity instanceof WorkflowTransitionInterface:
       /** @var \Drupal\workflow\Entity\WorkflowTransitionInterface $entity */
-      $field_name = $field_storage_definition->getName();
       $state = match ($field_name) {
         'from_sid' => $entity->getFromState(),
         'to_sid' => $entity->getToState(),
@@ -266,9 +266,14 @@ function workflow_state_allowed_values(FieldStorageDefinitionInterface $field_st
       $allowed_options = WorkflowState::loadMultiple([], $wid);
       break;
 
+    case $entity instanceof EntityInterface:
     default:
-      // Should not happen.
       $allowed_options = [];
+      // An entity can exist already before adding the workflow field.
+      if ($item = $entity->{$field_name}->first()) {
+        $state = $item->getState();
+        $allowed_options = $state->getWorkflow()->getStates();
+      }
       break;
   }
 
-- 
GitLab