Closed as not planned
Description
Symfony version(s) affected
7.0.x
Description
Configure a backed enum as enumType on your doctrine entity together with the workflow component throws a "unable to convert to string"-error when retrieving the enabled transitions
.
How to reproduce
Create a backed enum:
enum CustomerStatus: string
{
case New = 'new';
case AccountActive = 'account_active';
case AccountActivationExpired = 'account_activation_expired';
case AccountDeletedByCustomer = 'account_deleted_by_customer';
case AccountDisabledByAdmin = 'account_disabled_by_admin';
case AccountDeletedByAdmin = 'account_deleted_by_admin';
}
Create an entity and use the enum above as enumType:
#[ORM\Column(type: 'string', length: 255, enumType: CustomerStatus::class)]
private CustomerStatus $status;
public function getStatus(): CustomerStatus
{
return $this->status;
}
public function setStatus(CustomerStatus $status): static
{
$this->status = $status;
return $this;
}
Configure the following workflow:
framework:
workflows:
customer:
type: 'state_machine'
marking_store:
type: 'method'
property: 'status'
initial_marking: 'new'
supports:
- 'App\Entity\Customer'
places:
new: ~
account_active:
account_activation_expired:
account_deleted_by_customer:
account_disabled_by_admin:
account_deleted_by_admin:
transitions:
activate:
from: [ 'new', 'account_disabled_by_admin' ]
to: 'account_active'
guard: "is_granted('ROLE_ADMIN')"
activation_expires:
from: 'new'
to: 'account_activation_expired'
guard: "is_granted('ROLE_ADMIN')"
delete_by_customer:
from: [ 'new', 'account_active' ]
to: 'account_deleted_by_customer'
guard: "is_granted('ROLE_CUSTOMER')"
disable_by_admin:
from: [ 'new', 'account_active' ]
to: 'account_disabled_by_admin'
guard: "is_granted('ROLE_ADMIN')"
delete_by_admin:
from: [ 'new', 'account_active' ]
to: 'account_deleted_by_admin'
guard: "is_granted('ROLE_ADMIN')"
Retrieve the enabled transitions using the workflow component:
public function __construct(private WorkflowInterface $customerStateMachine)
{}
public function something()
{
$this->customerStateMachine->getEnabledTransitions(new Customer()); // throws error
}
Will throw the following error:
Object of class App\Enum\CustomerStatus could not be converted to string
Possible Solution
in vendor/symfony/workflow/MarkingStore/MethodMarkingStore.php:67
if ($this->singleState) {
$marking = [(string) $marking => 1]; // throws error due to explicit cast to string
} elseif (!\is_array($marking)) {
throw new LogicException(sprintf('The marking stored in "%s::$%s" is not an array and the Workflow\'s Marking store is instantiated with $singleState=false.', get_debug_type($subject), $this->property));
}
Check if type is backed enum, get value and set as string:
if ($this->singleState) {
if ($marking instanceof \BackedEnum){
$marking = $marking->value;
}
$marking = [(string) $marking => 1];
} elseif (!\is_array($marking)) {
throw new LogicException(sprintf('The marking stored in "%s::$%s" is not an array and the Workflow\'s Marking store is instantiated with $singleState=false.', get_debug_type($subject), $this->property));
}
Additional Context
No response