8000 Add an initialize method to workflows · Issue #44213 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
Add an initialize method to workflows #44213
Closed
@bambi42

Description

@bambi42

Description

At the moment the recommended way to initialize a workflow for an object $subject is to call WorkflowInterface::getMarking($subject). Internally this will call the getter for the configured property holding the marking on $subject. If this returns null the configured initial marking will be set on $subject.
The problem is that if you use typed properties in $subject::class the marking property has to be either nullable or has to initialize the marking property with the initial marking. In my opinion both of these options are suboptimal.
Option 1 probably doesn't reflect your model in a good way, most of the times you don't want a marking to be null at any time.
Option 2 conflicts with separation of concerns considerations.
The only other fix I can think of is to implement the getter for your marking like this:

public function getMarking(): string
{
    return $this->marking ?? null;
}

But I think this is very unintuitive and even worse than options 1 and 2.

The only good solution I can think of is to add a method WorkflowInterface::initialize($subject) that will only set the marking property of $subject to the configured initial marking without trying to get the marking first.
In my opinion this would also be a much more intuitive way of initializing a workflow than calling WorkflowInterface::getMarking($subject).

If no one disagrees with my opinion and proposal on this I would gladly implement this feature myself.

Example

// src/Entity/Book
namespace App\Entity;

class Book
{
    private string $marking;

    public function getMarking(): string
    {
        return $this->marking;
    }

    public function setMarking(string $marking): void
    {
        $this->marking = $marking;
    }
}
# config/workflow.yaml
framework:
    workflows:
        book:
            type: 'state_machine'
            marking_store:
                type: 'method'
                property: 'marking'
            supports:
                - App\Entity\Book
            initial_marking: on_shelf
            places:
                - on_shelf
                - ...
// some code initializing the workflow in App\Entity\Book
$book = new Book();

// current way that results in an exception
/** @var WorkflowInterface $bookStateMachine */
$bookStateMachine->getMarking($book); // Typed property must not be accessed before initialization

// current way that works
$initialMarking = new Marking();
foreach ($bookStateMachine>getDefinition()->getInitialPlaces() as $initialPlace) {
    $initialMarking->mark($initialPlace);
}
$bookStateMachine->getMarkingStore()->setMarking($book, $initialMarking);
$book->getMarking(); // 'on_shelf'

// proposed way
$bookStateMachine->initialize($book);
$book->getMarking(); // 'on_shelf'

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0