-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Workflow][RFC] Simplify workflow configuration #52378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Big yes to me! Would it make sense to still keep About the con, I'm not sure it would be a big deal. Of course it's always cool to have some double check, but I don't think this is necessary, other than being nice for the DX. |
Not sure it's required anymore. But removing it required breaking the BC. (with BC layer etc, but still) |
It would be great! |
This sound great, if we require support I can create a PR to achieve this. I have 2 possible approaches in mind:
# Definition.php
public function __construct(array $places, array $transitions, $initialPlaces = null, MetadataStoreInterface $metadataStore = null)
{
if (empty($places)) {
$places = $this->inferPlacesFromTransitions($transitions);
}
foreach ($places as $place) {
$this->addPlace($place);
}
//...
} Pros:
Cons:
framework:
workflows:
article:
infer_places: true
transitions:
go:
from: first
to: last Pros:
Cons:
|
Good practice is to use constants, isn't it? I would deprecate the |
Thanks for you support, but I'll take care of this one. |
Could be a nice enhancement to the DX, great idea 🙂 |
I think that you can't just drop https://symfony.com/blog/new-in-symfony-4-1-workflow-improvements#allow-to-store-metadata |
Hmm, there is a big drawback: no more metadata on place! so we must keep it |
I've been working on a bundle that allows workflows to be defined as attributes. For example. final const PLACE_NEW = 'new';
final const PLACE_COMPOSER_LOADED = 'loaded';
final const PLACE_OUTDATED = 'outdated_symfony';
final const PLACE_OUTDATED_PHP = 'php_too_old';
final const PLACE_ABANDONED = 'abandoned';
final const PLACE_VALID_REQUIREMENTS = 'valid';
#[Transition([self::PLACE_NEW], self::PLACE_COMPOSER_LOADED)]
final const TRANSITION_LOAD = 'load';
#[Transition([self::PLACE_COMPOSER_LOADED], self::PLACE_OUTDATED)]
final const TRANSITION_OUTDATED = 'outdated';
#[Transition([self::PLACE_COMPOSER_LOADED], self::PLACE_VALID_REQUIREMENTS)]
final const TRANSITION_VALID = 'valid'; It also supports metadata. #[Attribute(Attribute::TARGET_CLASS_CONSTANT)]
class Transition
{
public function __construct(
public array|string $from,
public array|string $to,
public ?string $guard=null,
public ?array $metadata=[]
) {
} Then I autowire the configuration during the compilerPass: class ConfigureFromAttributesService
{
static public function configureFramework(string $workflowClass, FrameworkConfig $framework, array|string $supports)
{
$reflectionClass = new \ReflectionClass($workflowClass);
// look in attribute first
$workflow = $framework->workflows()->workflows($reflectionClass->getShortName())
->supports($supports);
$constants = $reflectionClass->getConstants();
$seen = [];
foreach ($reflectionClass->getConstants() as $name => $constantValue) {
$reflectionConstant = new \ReflectionClassConstant($workflowClass, $name);
foreach ($reflectionConstant->getAttributes() as $attribute) {
$instance = $attribute->newInstance();
assert($reflectionConstant->getValue() == $constantValue);
switch ($instance::class) {
case Place::class:
// check for initial
if ($instance->initial) {
$initial = $constantValue;
}
$seen[] = $name;
$workflow->place()->name($constantValue) // the name of the place is the value of the constant
->metadata($instance->metadata);
break;
case Transition::class:
$workflow->transition()
->name($constantValue)
->from($instance->from)
->to($instance->to)
->metadata($instance->metadata);
break;
}
}
}
// shortcut to add all places of a certain pattern, if not already seen
foreach ($constants as $name => $constantValue) {
if (preg_match('/PLACE_/', $name)) {
if (!in_array($name, $seen)) {
$workflow->place()->name($constantValue);
// @todo: look at attributes
if (empty($initial)) {
$initial = $constantValue;
}
}
}
}
$workflow->initialMarking($initial);
}
} While I use the bundle for all my projects, it's not yet ready for prime time. Nonetheless, if you're rethinking workflows, I've found this approach to be helpful for me. Now that I'm posting this, I really should add some documentation to https://github.com/survos/SurvosWorkflowHelperBundle |
This PR was merged into the 7.1 branch. Discussion ---------- [Workflow] determines places from transitions | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | Fix #52378 | License | MIT Commits ------- ed30d81 [workflow] determines places form transitions
I have been thinking about this for a while, so it's time to open a RFC!
The workflow definition is redundant. You have to define the places twice:
places
transitions
Example:
I think we could simplify it to:
Indeed, all places could be guessed from the transitions
from
s etto
s. If aplace is not reached by a transition, it become useless anyway.
Pros
Cons
place
and thetransitions
transition, it'snot caught anymore
WDYT ?
The text was updated successfully, but these errors were encountered: