Setting a parameter as an array in a Nelmio Alice generator

I ask, is it possible to pass an array as a value for some elements? For example, in my case, I am trying to set roles for the FOSUserBundle User object, which takes roles as an array of values, not simple values. I have this in my chair:

 UserBundle\Entity\User: User0: username: admin email: admin@local.com enabled: 1 plainPassword: admin roles: [ROLE_ADMIN] groups: @Group0 User{1..10}: username: <firstNameMale> email: <companyEmail> enabled: <boolean(35)> plainPassword: <lexify> roles: 35%? [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] groups: @Group* 

But it does not work, and I get this error:

[Symfony \ Component \ Debug \ Exception \ ContextErrorException] Catchable Fatal Error: argument 1 passed to FOS \ UserBundle \ Model \ User :: setRoles () must be from an array of types, the specified string, called / var / www / html / vendor / nelmio / alice / src / Nelmio / Alice / Loader / Base.php on line 483 and defined in / var / www / html / vendor / friendsofsymfony / user-bundle / FOS / UserBundle / Model / User.php line 530

Any advice on this?

Update Answer

Using the first approach with a simple array in a YAML file:

After making some changes, as @frumious suggested that the device now has this content:

 UserBundle\Entity\User: User0: username: admin email: admin@local.com enabled: 1 plainPassword: admin roles: [ROLE_ADMIN] groups: @Group0 User{1..10}: username: <firstNameMale> email: <companyEmail> enabled: <boolean(35)> plainPassword: <lexify> roles: [ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] groups: @Group* 

Thus, I will always assign two roles for each test user, but I have some problems trying to find the place where Faker should be placed, and what code to write inside it.

But anytime I try to execute a set by calling:

 h4cc_alice_fixtures:load:sets ./src/CommonBundle/DataFixtures/TananeSet.php 

I got this error:

[ErrorException] Catchable Fatal Error: argument 1 passed to Doctrine \ Common \ Collections \ ArrayCollection :: __ construct () must be from an array of types, a given object, called in / var / www / html / vendor / doctrine / orm / lib / Doctrine /ORM/UnitOfWork.php o
n line 555 and defined in /var/www/html/vendor/doctrine/collections/lib/Doctrine/Common/Collections/ArrayCollection.php line 47

Which makes me think that the problem here is related to the $groups variable in the User object. This is the code snippet for this object:

 /** * @ORM\Entity * @ORM\Table(name="fos_user") * @Gedmo\SoftDeleteable(fieldName="deletedAt", timeAware=false) * @ORM\Entity(repositoryClass="UserBundle\Entity\Repository\UserRepository") */ class User extends BaseUser { /** * Hook timestampable behavior * updates createdAt, updatedAt fields */ use TimestampableEntity; /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * @ORM\ManyToMany(targetEntity="Group") * @ORM\JoinTable(name="fos_user_user_group", * joinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id")}, * inverseJoinColumns={@ORM\JoinColumn(name="group_id", referencedColumnName="id")} * ) */ protected $groups; /** * @ORM\Column(name="deletedAt", type="datetime", nullable=true) */ protected $deletedAt; } 

How can I fix this error? What should I pass as a parameter to groups ?

Using the second approach: service definition

Following another @frumious suggestion, I define the following service:

 services: roles.faker.provider: class: CommonBundle\Tools\RolesFakerProvider tags: - { name: h4cc_alice_fixtures.provider } 

And this is the method:

 namespace CommonBundle\Tools; class RolesFakerProvider { public function randomRoles() { $names = ['ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO']; return [$names[array_rand($names)]]; } } 

Then I made the following changes:

 UserBundle\Entity\User: User0: username: admin email: admin@local.com enabled: 1 plainPassword: admin roles: [ROLE_ADMIN] groups: @Group0 User{1..10}: username: <firstNameMale> email: <companyEmail> enabled: <boolean(35)> plainPassword: <lexify> # BEFORE #roles: [ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] # AFTER roles: <randomRoles> groups: @Group* 

And instead, this error is returned:

[Symfony \ Component \ Debug \ Exception \ ContextErrorException] Grip Fatal error: argument 1 passed to FOS \ UserBundle \ Model \ User :: setRoles () must be an array of types, a line called in / var / www / html / vendor / nelmio / alice / src / Nelmio / Alice / Loader / Base.php on line 483 and defined in / var / www / html / vendor / friendsofsymfony / user-bundle / FOS / UserBundle / Model / User.php line 530

What makes me think that the function is not returning an array , or something else is failing, any advice around this too?

+7
source share
3 answers

In fact, this is just an assumption based on a quick look at documents, but I suspect that the problem is that roles: 35%? [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] roles: 35%? [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] bit after roles: interpreted as a single line because it does not start with [ , since a normal YAML array would have to.

As for the solution, I suspect that you cannot do this directly in YAML.

One (untested) option: use the custom Faker method :

Faker

 public function roles() { return = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO']; } 

Yaml

 User{1..10}: username: <firstNameMale> email: <companyEmail> enabled: <boolean(35)> plainPassword: <lexify> roles: 35%? <roles()> groups: @Group* 

Final request: Do you really want Alice to assign all these roles to the user 35% of the time? If not, and in fact you want to select one of them based on the probability in each user, then I believe that you still need a non-standard method, but instead you should use the selection logic, and not in YAML.

EDIT

Well, it sounds like you need random single roles for each test instance, in which case you will need a special code something like this:

 public function randomRole() { $names = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO']; return $names[array_rand($names)]; } 

According to Alice , it looks like you can stick with this directly in YAML as follows:

 User{1..10}: username: <firstNameMale> email: <companyEmail> enabled: <boolean(35)> plainPassword: <lexify> roles: <?php $names = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO']; echo $names[array_rand($names)]; ?> groups: @Group* 

Or AliceFixturesBundle docs tell you how to enable a separate provider (as described above)

services.yml

 services: your.faker.provider: class: YourProviderClass tags: - { name: h4cc_alice_fixtures.provider } 


This sentence does not work, keeping offspring, but moving down!

I thought that perhaps you can do this by defining the array separately at the top and then referencing it using Alice Value Objects , but since the array is not a normal object, I don’t see how to create it. You need something like this:

 Array: Array0: [ROLE_ADMIN, ROLE_USER, ROLE_PROFILE_ONE, ROLE_PROFILE_TWO] UserBundle\Entity\User: User0: username: admin email: admin@local.com enabled: 1 plainPassword: admin roles: [ROLE_ADMIN] groups: @Group0 User{1..10}: username: <firstNameMale> email: <companyEmail> enabled: <boolean(35)> plainPassword: <lexify> roles: 35%? @Array0 groups: @Group* 
+6
source

The problem that I believe is that you need to install an array of roles, so you cannot just return a single role. Or do it on the line:

 User{1..10}: username: <firstNameMale> email: <companyEmail> enabled: <boolean(35)> plainPassword: <lexify> roles: <?php $names = ['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO']; echo '['.$names[array_rand($names)].']'; ?> groups: @Group* 

Another problem may be that when you give the array something, it can unpack it as an arg list. Try passing it [ ['Foo'] ] that is, an array as the first arg of another array. In any case, when you find out, I think you should send a transfer request for documents or create a file at least because it probably shouldn't be so complicated.

+1
source

Try this

 roles: <randomElements(['ROLE_ADMIN', 'ROLE_USER', 'ROLE_PROFILE_ONE', 'ROLE_PROFILE_TWO'], 2)> 

randomElements :
1- array 'Array to get the elements. The default is af '.
2- integer "The number of elements to be taken."
3- boolean 'Allows you to select items multiple times. The default is false.

It will return an array.

0
source

Source: https://habr.com/ru/post/1203447/


All Articles