Issue 1:
Symfony version(s) affected: 4.1. symfony/workflow: 4.2

Description

Hello. I've faced an issue when I placing two or more values in from section at transitions description in config. As far as I know, this is allowed, right?

So I'm getting false negative results when trying to apply for state transfer with allowed from values.

How to reproduce

After some research, I believe that the problem is in the following buildTransitionBlockerListForTransition method. The method just iterates all over places and creates TransitionBlockerList on first false condition. But as far as I get - method have to iterate over all forms and only then create TransitionBlockerList if needed.

Here is the reference on code that I've described above.

https://github.com/symfony/workflow/blob/master/Workflow.php#L247

Possible Solution

Iterate over all places and create TransitionBlockerList only if $marking->has($place) have returned false for every $place

Additional context

My workflow config

framework:
workflows:
payment:
type: 'workflow'
supports:
- App\Entity\Payment
- App\Entity\RecurringPayment
initial_place: new
marking_store:
type: 'single_state'
arguments:
- 'status'
places:
- new
- accepted
- error
- declined
- pending
- refunded
- cancelled
transitions:
pending:
from: new
to: pending
accepted:
from: [new, pending, accepted]
to: accepted
refunded:
from: accepted
to: refunded
cancelled:
from: [new, pending, accepted]
to: cancelled
error:
from: [new, pending]
to: error
declined:
from: [new, pending]
to: declined

Issue 2:
Hi all,

I'm posting this RFC to submit a new validator constraint idea. I don't know if it's worth it or not and that's why I would like to get some feedbacks.

Something that annoys me with validation constraints is repeating the validation groups everytime in all constraints when dealing with multiple validation contexts. Below is a very simple example:

class User
{
/**
* @Assert\NotBlank(groups = { "Signup" })
* @Assert\Length(min = 6, max = 15, groups = { "Signup" })
* @Assert\Regex(pattern = "^/[a-z0-9]+$/", groups = { "Signup" })
*/
private $username;

/**
* @Assert\NotBlank(groups = { "Signup" })
* @Assert\Length(min = 8, groups = { "Signup", "Profile" })
*
*/
private $password;
}

As you can see in the above code, for the $username property, we have to repeat the groups option to indicate for which context we want to validate that property. I think this is annonying to duplicate that group option.

That's why I suggest to introduce a new Group constraint that is a collection of constraints to be triggered only for a particular (set of) group(s).

class User
{
/**
* @Assert\Group(groups = { "Signup" }, constraints = {
* @Assert\NotBlank(),
* @Assert\Length(min = 6, max = 15),
* @Assert\Regex(pattern = "^/[a-z0-9]+$/")
* })
*/
private $username;

/**
* @Assert\NotBlank(groups = { "Signup" })
* @Assert\Length(min = 8, groups = { "Signup", "Profile" })
*
*/
private $password;
}

As you can see, I can embed my three constraints into one single Group constraint that tells for which context we want to execute that set of annotations. I find it a bit more readable and it also avoids to duplicate the goup name everywhere in the other constraints.

What do you think of such feature?

Is it something that you would need or help improve your efficiency?

Regards.