Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Customizing the User Entity

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

The really neat thing about Symfony's security system is that it doesn't care at all about what your User class looks like. As long as it implements UserInterface, so, as long as it has these methods, you can do anything you want with it. Heck, it doesn't even need to be an entity!

Adding more Fields to User

For example, we already have an email field, but I also want to be able to store the first name for each user. Cool: we can just add that field! Find your terminal and run:

php bin/console make:entity

Update the User class and add firstName as a string, length 255 - or shorter if you want - and not nullable. Done!

Check out the User class! Yep, there's the new firstName property and... at the bottom, the getter and setter methods:

... lines 1 - 10
class User implements UserInterface
{
... lines 13 - 29
/**
* @ORM\Column(type="string", length=255)
*/
private $firstName;
... lines 34 - 105
public function getFirstName(): ?string
{
return $this->firstName;
}
public function setFirstName(string $firstName): self
{
$this->firstName = $firstName;
return $this;
}
}

Awesome!

Setting Doctrine's server_version

I think we're ready to make the migration. But! A word of warning. Check out the roles field on top:

... lines 1 - 10
class User implements UserInterface
{
... lines 13 - 24
/**
* @ORM\Column(type="json")
*/
private $roles = [];
... lines 29 - 116
}

It's an array and its Doctrine type is json. This is really cool. Newer databases - like PostgreSQL and MySQL 5.7 - have a native "JSON" column type that allows you to store an array of data.

But, if you're using MySQL 5.6 or lower, this column type does not exist. And actually, that's not a problem! In that case, Doctrine is smart enough to use a normal text field, json_encode() your array when saving, and json_decode() it automatically when we query. So, no matter what database you use, you can use this json Doctrine column type.

But, here's the catch. Open config/packages/doctrine.yaml. One of the keys here is server_version, which is set to 5.7 by default:

... lines 1 - 7
doctrine:
dbal:
... lines 10 - 11
server_version: '5.7'
... lines 13 - 31

This tells Doctrine that when it interacts with the database, it should expect that our database has all the features supported by MySQL 5.7, including that native JSON column type. If your computer, or more importantly, if your production database is using MySQL 5.6, then you'll get a huge error when Doctrine tries to make queries using the native MySQL JSON column type.

If you're in this situation, just set this back to 5.6:

... lines 1 - 7
doctrine:
dbal:
... lines 10 - 11
server_version: '5.6'
... lines 13 - 31

Doctrine will then create a normal text column for the JSON field.

Generating the Migration

Ok, now run:

php bin/console make:migration

Perfect! Go check that file out in src/Migrations:

... lines 1 - 10
final class Version20180830012659 extends AbstractMigration
{
public function up(Schema $schema) : void
{
... lines 15 - 17
$this->addSql('CREATE TABLE user (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(180) NOT NULL, roles LONGTEXT NOT NULL COMMENT \'(DC2Type:json)\', first_name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_8D93D649E7927C74 (email), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB');
}
... lines 20 - 27
}

And... nice! CREATE TABLE user. Look at the roles field: a LONGTEXT column. If you kept your server_version at 5.7, this would be a json column.

Let's run this:

php bin/console doctrine:migrations:migrate

Adding Fixtures

One last step: we need to add some dummy users into the database. Start with:

php bin/console make:fixtures

Call it UserFixture. Go check that out: src/DataFixtures/UserFixture.php:

... lines 1 - 2
namespace App\DataFixtures;
use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\Persistence\ObjectManager;
class UserFixture extends Fixture
{
public function load(ObjectManager $manager)
{
// $product = new Product();
// $manager->persist($product);
$manager->flush();
}
}

If you watched our Doctrine tutorial, you might remember that we created a special BaseFixture with some sweet shortcut methods. Before I started recording this tutorial, based on some feedback from you nice people, I made a few improvements to that class. Go team!

... lines 1 - 9
abstract class BaseFixture extends Fixture
{
... lines 12 - 21
public function load(ObjectManager $manager)
{
$this->manager = $manager;
$this->faker = Factory::create();
$this->loadData($manager);
}
... lines 29 - 90
}

The way you use this class is still the same: extend BaseFixture and update the load() method to be protected function loadData(). I'll remove the old use statement.

... lines 1 - 2
namespace App\DataFixtures;
use Doctrine\Common\Persistence\ObjectManager;
class UserFixture extends BaseFixture
{
protected function loadData(ObjectManager $manager)
{
... lines 11 - 14
}
}

Inside, call $this->createMany(). The arguments to this method changed a bit since the last tutorial:

... lines 1 - 9
abstract class BaseFixture extends Fixture
{
... lines 12 - 29
/**
* Create many objects at once:
*
* $this->createMany(10, function(int $i) {
* $user = new User();
* $user->setFirstName('Ryan');
*
* return $user;
* });
*
* @param int $count
* @param string $groupName Tag these created objects with this group name,
* and use this later with getRandomReference(s)
* to fetch only from this specific group.
* @param callable $factory
*/
protected function createMany(int $count, string $groupName, callable $factory)
{
for ($i = 0; $i < $count; $i++) {
$entity = $factory($i);
if (null === $entity) {
throw new \LogicException('Did you forget to return the entity object from your callback to BaseFixture::createMany()?');
}
$this->manager->persist($entity);
// store for usage later as groupName_#COUNT#
$this->addReference(sprintf('%s_%d', $groupName, $i), $entity);
}
}
... lines 61 - 90
}

Pass this 10 to create 10 users. Then, pass a "group name" - main_users. Right now, this key is meaningless. But later, we'll use it in a different fixture class to relate other objects to these users. Finally, pass a callback with an $i argument:

... lines 1 - 7
class UserFixture extends BaseFixture
{
protected function loadData(ObjectManager $manager)
{
$this->createMany(10, 'main_users', function($i) {
... lines 13 - 17
});
$manager->flush();
}
}

This will be called 10 times and our job inside is simple: create a User, put some data on it and return!

Do it! $user = new User():

... lines 1 - 4
use App\Entity\User;
... lines 6 - 7
class UserFixture extends BaseFixture
{
protected function loadData(ObjectManager $manager)
{
$this->createMany(10, 'main_users', function($i) {
$user = new User();
... lines 14 - 17
});
... lines 19 - 20
}
}

Then $user->setEmail() with sprintf() spacebar%d@example.com. For the %d wildcard, pass $i:

... lines 1 - 7
class UserFixture extends BaseFixture
{
protected function loadData(ObjectManager $manager)
{
$this->createMany(10, 'main_users', function($i) {
$user = new User();
$user->setEmail(sprintf('spacebar%d@example.com', $i));
... lines 15 - 17
});
... lines 19 - 20
}
}

Which will be one, two, three, four, five, six, seven, eight, nine, ten for the 10 calls.

The only other field is first name. To set this, we an use Faker, which we already setup inside BaseFixture: $this->faker->firstName:

... lines 1 - 7
class UserFixture extends BaseFixture
{
protected function loadData(ObjectManager $manager)
{
$this->createMany(10, 'main_users', function($i) {
$user = new User();
$user->setEmail(sprintf('spacebar%d@example.com', $i));
$user->setFirstName($this->faker->firstName);
... lines 16 - 17
});
... lines 19 - 20
}
}

Finally, at the bottom, return $user:

... lines 1 - 7
class UserFixture extends BaseFixture
{
protected function loadData(ObjectManager $manager)
{
$this->createMany(10, 'main_users', function($i) {
$user = new User();
$user->setEmail(sprintf('spacebar%d@example.com', $i));
$user->setFirstName($this->faker->firstName);
return $user;
});
... lines 19 - 20
}
}

And... we're done! This step had nothing to do with security: this is just boring Doctrine & PHP code inside a fancy createMany() method to make life easier.

Load 'em up:

php bin/console doctrine:fixtures:load

Let's see what these look like:

php bin/console doctrine:query:sql 'SELECT * FROM user'

Nice! Our User class is done! Now, it's time to add a login form and a login form authenticator: the first way that we'll allow our users to login.

Leave a comment!

80
Login or Register to join the conversation

Fun fact, I'm using postgres, and it appears that my User entity created a table that conflicted with postgres users.

I found this when I got the following error from `AbstractPostgreSQLDriver`:

`SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "user"
LINE 1: DELETE FROM user`

If anyone else has this problem, it's easy to change the table name for the entity using annotations. Check out https://stackoverflow.com/q....

2 Reply
Balázs S. Avatar
Balázs S. Avatar Balázs S. | Campbell | posted 3 years ago | edited

Ran into this today in Chapter 6 when tried to fetch the user. A simple fix is to add a new annotation

@ORM\Table(name="user")

to the User class using backticks around user between the double quotes. This helps Doctrine 2.x to use our user table, not PostgreSQL's. ;-)

1 Reply
Paweł Ł. Avatar

it doesn't work for me :(

Reply

Hey Paweł Ł.

That's odd. What database are you using?

Reply

That's a good fix or just use a different name for the table, something like app_user. Cheers!

Reply

Thanks for the tip Campbell! I'll keep that in the mind for the future - so we can just choose a different table name that works for everyone :).

Cheers!

Reply
MolloKhan Avatar MolloKhan | SFCASTS | posted 2 years ago | edited

Hey Abelardo,

try running the command through the Symfony binary symfony console make:migration
The Symfony binary has an integration with Docker, so it will take care of setting your the environment variables properly

Cheers!

1 Reply
Abelardo Avatar

Hi there!
After rebuilding my containers and deleting my database, tables and so forth I could solve this issue.

Thanks for your help!
Cheers.

1 Reply
Jörg daniel F. Avatar
Jörg daniel F. Avatar Jörg daniel F. | posted 2 years ago

hello then I try to ./bin/console doctrine:fixtures:load
I got this error :-(


PHP Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: syntax error, unexpected '$manager' (T_VARIABLE) in /Users/jorgfluck/docker/login/src/DataFixtures/UserFixture.php:21
Stack trace:
#0 [internal function]: Symfony\Component\Debug\DebugClassLoader->loadClass('App\\DataFixture...')
#1 [internal function]: spl_autoload_call('App\\DataFixture...')
Reply

Hey Jörg daniel F.

Seems like you have a typo in the Fixtures file. Check src/DataFixtures/UserFixture.php:21 for the mistakes

Cheers!

Reply
Farshad Avatar
Farshad Avatar Farshad | posted 2 years ago

I havent followed the previous tutorial where you created the BaseFixture.php. I don't quite understand what is going on here. I don't necessarily want to add dummy users through this system. Can I skip this step? Or is it gonna be used for other things as well?

Reply

Hey Farry7,

If you look at the course code in finish/ directory - you will see we use those dummy users to randomly set Articles' authors. Of course, you can skip this step - it's up to you - but you would probably need to tweak that ArticleFixtures class to set the authors. But probably create at least 1 user via fixtures that you will use is a good idea, so you can easily attach all the articles to that one user.

Hope this helps!

Cheers!

Reply
Abelardo Avatar
Abelardo Avatar Abelardo | posted 2 years ago

Hi there,
According to the Symfony doc, the http_basic (email & password) is not compatible with logout feature (?) but my app demands a scheduled time out.
By other hand, I don't see in Symfony documentation how to implement a scheduled time out: do you offer a tutorial how to handle this situation?

Cheers.

Reply

Hey @AbelardoLG!

According to the Symfony doc, the http_basic (email & password) is not compatible with logout feature (?)

If I remember correctly, the problem is that when you use http_basic, most browsers cache/store the submitted email and password. And then, if the user logs out... and then comes back to the site, their browser will automatically (without even asking them) re-send the email & password via HTTP basic. So, Symfony does log them out... but their browser automatically re-authenticates them.

In general, if you need some more secure system that logs users out, HTTP basic might not the right solution for you.

By other hand, I don't see in Symfony documentation how to implement a scheduled time out: do you offer a tutorial how to handle this situation?

Usually this is just done via your session lifetime :)


# config/packages/framework.yaml
framework:
    session:
        # e.g. 2 days (172800 == 2 days)
        cookie_lifetime: 172800

With this solution, the user would need to be idle for 2 days (or close their browser) to be logged out.

If you actually need to force the user to re-authenticate on an interval (e.g. the user must be logged out after 24 hours, even if they have been active that entire time), then we can do that with some event listeners.

First, add a property - like "lastLoggedInAt" - on your User object. To populate this, listen to this event - https://github.com/symfony/symfony/blob/5.x/src/Symfony/Component/Security/Core/Event/AuthenticationSuccessEvent.php - with an event subscriber and set this property to the current date on the User and Save.

Second create another event subscriber (you can use make:subscriber) and listen on the RequestEvent https://github.com/symfony/symfony/blob/5.x/src/Symfony/Component/HttpKernel/Event/RequestEvent.php ). On this event, check to see if the lastLoggedInAt is "too old". If it is, redirect them to /logout to trigger a log out.

Let me know if you need any more pointers on this part - I've left out some of the details, which might be easy for you or might be tricky :).

Cheers!

1 Reply
Abelardo Avatar
Abelardo Avatar Abelardo | weaverryan | posted 2 years ago | edited

Hi weaverryan !
Thanks for your explanation.

When I set the session timeout to 60 (1 minute), my app does nothing; so, shouldn't it automatically show the login page? If I reload the browser then my app shows the login page: is this an expected behaviour?.

Warmest regards.

Reply

Hey @AbelardoLG!

> When I set the session timeout to 60 (1 minute), my app does nothing; so, shouldn't it automatically show the login page? If I reload the browser then my app shows the login page: is this an expected behaviour?.

Hmm. I'm not sure I totally understand - that sounds like it's working correctly. This is what is happening behind the scenes:

1) You log in. Symfony sets a PHPSESSID cookie with a lifetime of 1 minute
2) If you refresh during the next 1 minute, you are still authenticated.
3) The first time you refresh *after* 1 minute, the cookie will *not* be sent, and you will become unauthenticated (and then your app would redirect to the login page).

I think this is exactly the behavior you're describing and it *is* expected. If you need someone to be logged out even if they don't refresh (e.g. they are just looking at a page), then you'll need to make some AJAX calls every now and then to check to see if the user is still authenticated and, if they are not, reload the page (so that the user can *see* that they are now not authenticated).

Cheers!

1 Reply
Abelardo Avatar

Ok, thanks for your comment.

Have a nice day! Brs from Madrid, España. :)

Reply
n0 Avatar

The information about the JSON type does not seem to be valid anymore here. At least Symfony 5+Doctrine will not automatically decode the array. I have tested this on multiple different MariaDB databases, and all of them get the same error:
Could not convert database value "ROL_USER" to Doctrine Type json

It seems this only works with MySQL, as MariaDB which is the default in most Linux distros handles the JSON field completely differently.

Reply
sadikoff Avatar sadikoff | SFCASTS | n0 | posted 2 years ago | edited

Hey n0

You should have and encoded array of roles, not just one role inside your database. Value should be like ["ROLE_USER"]

Cheers

Reply
Gaetano S. Avatar
Gaetano S. Avatar Gaetano S. | posted 3 years ago

Hi,

I started this part of course and I adapted the others fixtures for the new parameters of createMany method of BaseFixture :
Example for articleFixtures.php

$this->createMany(10, 'articles', function($i) {

$article = new Article();

$article->set...

...

...

return $article;

When I try to load fixtures I have this error:

> purging database
> loading App\DataFixtures\AppFixtures
> loading App\DataFixtures\TagFixture
> loading App\DataFixtures\ArticleFixtures

In BaseFixture.php line 89:

Did not find any references saved with the group name "App\Entity\Tag"

I'm trying to get the correct order of all fixtures but I can't.
Help me, please

Reply
Gaetano S. Avatar

I tried to do a rollback of my branch and, before creating the userFixture, I updated BaseFixture.php, I modified the arguments of all fixtures in the method createMany() and I tried to load dummy data. Same problem.

This is my code in ArticleFixtures:

class ArticleFixtures extends BaseFixture implements DependentFixtureInterface
{
private static $articleTitles = [
'Why Asteroids Taste Like Bacon',
'Life on Planet Mercury: Tan, Relaxing and Fabulous',
'Light Speed Travel: Fountain of Youth or Fallacy',
];
private static $articleImages = [
'asteroid.jpeg',
'mercury.jpeg',
'lightspeed.png',
];
private static $articleAuthors = [
'Mike Ferengi',
'Amy Oort',
];

public function loadData(ObjectManager $manager): void
{
$this->createMany(10, 'article', function($i) {
$article = new Article();
$article
->setTitle($this->faker->randomElement(self::$articleTitles))
->setContent( )
->setAuthor($this->faker->randomElement(self::$articleAuthors))
->setHeartCount($this->faker->numberBetween(5,100))
->setImageFilename($this->faker->randomElement(self::$articleImages))
;

// publish most articles
if ($this->faker->boolean(70)) {
$article->setPublishedAt($this->faker->dateTimeBetween('-100 days', '-1 days'));
}

$tags = $this->getRandomReferences(Tag::class, $this->faker->numberBetween(0, 5)); !!!!Maybe here the problem

foreach ($tags as $tag)
{
$article->addTag($tag);
}

return $article;
});
$manager->flush();
}

/**
* @inheritDoc
*/
public function getDependencies()
{
return [TagFixture::class];
}
}

Thanks for your help

Reply
Gaetano S. Avatar

Finally, with a calm debug :) of getRandomReference() method, I found the problem. When I call getRandomReferences() from ArticleFixtures, Phpstorm tell me to pass the class name because the first argument is string $classname. When I realized that I need the groupname, I said 'Eureka'.
Maybe it's better to change the $classname for $groupname. I can sleep better this night :).

Reply

Hey Gaetano S.

Woh that really can be confusing. We are very sorry for that!!! I think it's safe to rename it. I'll check it out.
Thank you for your report and investigation!

Cheers!

Reply
Gaetano S. Avatar

No problem. It's also a good way to learn.

Reply
Tim W. Avatar

The code works fine for me but at the final part i am getting stuck.. the

php bin/console doctrine:query:sql 'SELECT * FROM user'

gives an error. This is the message i get

Too many arguments, expected arguments "command" "sql".
Reply

Hey @TimWetzels!

Try the same command, but with double quotes around it:

> php bin/console doctrine:query:sql "SELECT * FROM user"

If you're a Mac user (just a guess), the terminal now uses "zsh" by default where that * is a special character. So, command that have a "*" in it like this, now need double-quotes around this.

Let me know if that helps!

Cheers!

Reply
Default user avatar

Why can't i use dependency injection on Class UserFixtures load method ?
public function load(UserPasswordEncoderInterface $passwordEncoder)
$passwordEncoder->encodePassword... doesn't seem to work and i'm forced to use the constructor.

Reply
Default user avatar

Oh o noticed you answered that previously already. No post delete button though :/

Reply

Hey Wuwu,

Don't worry about deleting comments ;) Glad you found the answer!

Cheers!

Reply
Robert Avatar

When trying to load the fixtures i get this following error:

Cannot find any references for class "main_article"

Reply
Robert Avatar

Okay i fixed it by acctualy paying attention to what i am doing :D

$comment->setArticle($this->getRandomReference('main_articles'));

was set to article and not articles.

Reply

Hey Roby,

Great catch ;)

Cheers!

Reply
Petr T. Avatar
Petr T. Avatar Petr T. | posted 3 years ago

Uff, does not work for me, but why?

In BaseFixtures.php line 76:
Compile Error: Cannot declare class App\DataFixtures\BaseFixture, because the name is already in use

What could be a problem?

Reply
Petr T. Avatar

Maybe more useful informations:
composer req orm-fixtures
Using version ^3.2 for doctrine/doctrine-fixtures-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "4.3.*"
Package operations: 2 installs, 0 updates, 0 removals
- Installing doctrine/data-fixtures (v1.3.2): Loading from cache
- Installing doctrine/doctrine-fixtures-bundle (3.2.2): Loading from cache
Writing lock file
Generating autoload files
ocramius/package-versions: Generating version class...
ocramius/package-versions: ...done generating version class
Symfony operations: 1 recipe (6ec0990e709b57a3882c12230b5c20a8)
- Configuring doctrine/doctrine-fixtures-bundle (>=3.0): From github.com/symfony/recipes:...
Executing script cache:clear [KO]
[KO]
Script cache:clear returned with error code 255
!!
!! Fatal error: Cannot declare class App\DataFixtures\BaseFixture, because the name is already in use in src\DataFixtures\BaseFixtures.php on line 76
!!
!! In BaseFixtures.php line 76:
!!
!! Compile Error: Cannot declare class App\DataFixtures\BaseFixture, because the name is already in use
!!

Reply
Petr T. Avatar

Ok, I have tried to exclude the folder DataFixtures in services.yaml.. but then no Fixsture Service found for doctrine:fixtures:load
Therefore I exclude DataFixtures/BaseFixtures.php and it works (but not fully corrected - no entries in DB, but compiler is OK)

Reply

Hey Petr T.

Have you looked inside BaseFixtures.php? Probably something wrong inside this class

Cheers!

Reply
Petr T. Avatar
Petr T. Avatar Petr T. | sadikoff | posted 3 years ago | edited

Hello sadikoff
thanks! But the problem was obvious (unfortunatelly not for fisrt view). The correct file name is BaseFixture.php (and not with 's' on the end). A little bit pitty, Symfony help a little bit more with that in its error msg. But my stupid fault.

Reply
Vanderlam F. Avatar
Vanderlam F. Avatar Vanderlam F. | posted 3 years ago

Hello. When I send the command php bin\console make:migration on windows powershell, it returns these errors:

In AbstractMySQLDriver.php line 106:
An exception occurred in driver: could not find driver

In PDOConnection.php line 31:
could not find driver

In PDOConnection.php line 27:
could not find driver

the same goes if I send the doctrine:migrations:diff command

thanks in advance. Love your symfony series <3

Reply

Hey Vanderlam F.

Double check that you can connect to your database first. Check for the environment variable DATABASE_URL inside .env or .env.local. If the URL is correct, then validate your schema by running the command php bin/console doctrine:schema:validate
I hope it helps!

Cheers!

Reply
Vanderlam F. Avatar

Also, where can I find these files so I can send whats on the line of error?

Reply
Duilio P. Avatar
Duilio P. Avatar Duilio P. | posted 4 years ago | edited

It seemed appropriate to reduce the cost of encrypting passwords in development (config/packages/dev/security.yaml) in order to generate the dummy users faster (when executing doctrine:load:fixtures. Otherwise I had to wait for a few seconds:


security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
            cost: 4

I suppose this is fine as long as it's set in the development or testing environment and not in production.

Reply

Hey Duilio P.

That's a good idea. In big projects fixtures may take some time to run, so reducing its time sounds good. I would just add a comment clarifying why you did that on the dev/security.yaml file, so other developers don't get confused

Cheers!

1 Reply
Dmitriy Avatar
Dmitriy Avatar Dmitriy | posted 4 years ago

Is it possible to work with the database in Symfony, if the version of MySQL on the development and production server is different.

What to do with config/packages/doctrine.yaml
and configuring

server_version: '5.7'

in this case?

It will take different values.

Reply

Hey Dmitriy!

Great question! Yes, but you should set this server_version setting to the *lowest* of the versions. This will prevent it from using, for example, any new features in MySQL 5.7 if your production server is actually only on MySQL 5.6.

Cheers!

Reply
Dmitriy Avatar

Thank you, Ryan. It is perfectly.

Reply
Gary L. Avatar
Gary L. Avatar Gary L. | posted 4 years ago | edited

Hello everyone,

I just finish the course about "Doctrine & The Database" and I want to follow this course.
I'm working with the same code from the old course. Do you have an idea why I've this error when I try to :fixtures:load ?

Error message :

<blockquote>In BaseFixture.php line 57:

Argument 1 passed to App\DataFixtures\BaseFixture::createMany() must be of the type
integer, string given, called in /Users/computer/first-project/src/DataFixture
s/ArticleFixtures.php on line 66</blockquote>

The line 57 in BaseFixture is :

protected function createMany(int $count, string $groupName, callable $factory) {

Do you think the problem is come from the old code form the previous course ?

Thank you!

Reply
Lukasz Avatar

How u overcome a
" Argument 1 passed to App\DataFixtures\BaseFixture::createMany() must be of the type int, string given, called in E:\xampp\htdocs\symfony-project\src\DataFixtures\TagFixture.php on line 11 " ?

Reply

Hey Lukasz!

Why are you passing in a string? The first argument is for specifying how many records you want

Cheers!

Reply

Hey @Galnash

That's correct, the BaseFixture class got refactored, so I think you only have to download the new one, and probably you'll have to do some tweaks to your Fixture classes.

Cheers!

Reply
Ozornick Avatar
Ozornick Avatar Ozornick | MolloKhan | posted 3 years ago | edited

I did not buy access to the course. I had to adapt fixtures myself, it's simple. It was a bad move in relation to state employees =) For example,
`class TagFixture extends BaseFixture
{

protected function loadData(ObjectManager $manager)
{
    $this->createMany(10, 'tag', function($i) {
        $tag = new Tag();
        $tag->setName($this->faker->realText(20));

        return $tag;
    });
    $manager->flush();
}

}`

Reply
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": "^7.1.3",
        "ext-iconv": "*",
        "composer/package-versions-deprecated": "^1.11", // 1.11.99
        "knplabs/knp-markdown-bundle": "^1.7", // 1.7.0
        "knplabs/knp-paginator-bundle": "^2.7", // v2.8.0
        "knplabs/knp-time-bundle": "^1.8", // 1.8.0
        "nexylan/slack-bundle": "^2.0,<2.2.0", // v2.0.0
        "php-http/guzzle6-adapter": "^1.1", // v1.1.1
        "sensio/framework-extra-bundle": "^5.1", // v5.2.0
        "stof/doctrine-extensions-bundle": "^1.3", // v1.3.0
        "symfony/asset": "^4.0", // v4.1.4
        "symfony/console": "^4.0", // v4.1.4
        "symfony/flex": "^1.0", // v1.17.6
        "symfony/framework-bundle": "^4.0", // v4.1.4
        "symfony/lts": "^4@dev", // dev-master
        "symfony/orm-pack": "^1.0", // v1.0.6
        "symfony/security-bundle": "^4.0", // v4.1.4
        "symfony/serializer-pack": "^1.0", // v1.0.1
        "symfony/twig-bundle": "^4.0", // v4.1.4
        "symfony/web-server-bundle": "^4.0", // v4.1.4
        "symfony/yaml": "^4.0", // v4.1.4
        "twig/extensions": "^1.5" // v1.5.2
    },
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.0", // 3.0.2
        "easycorp/easy-log-handler": "^1.0.2", // v1.0.7
        "fzaninotto/faker": "^1.7", // v1.8.0
        "symfony/debug-bundle": "^3.3|^4.0", // v4.1.4
        "symfony/dotenv": "^4.0", // v4.1.4
        "symfony/maker-bundle": "^1.0", // v1.7.0
        "symfony/monolog-bundle": "^3.0", // v3.3.0
        "symfony/phpunit-bridge": "^3.3|^4.0", // v4.1.4
        "symfony/profiler-pack": "^1.0", // v1.0.3
        "symfony/var-dumper": "^3.3|^4.0" // v4.1.4
    }
}
userVoice