Chapters
33 Chapters
|
3:34:13
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!Compatible PHP versions: ^7.1.3
Subscribe to download the code!Compatible PHP versions: ^7.1.3
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
03.
Customizing the User Entity
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
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
"doctrine/annotations": "^1.0", // 1.10.2
"doctrine/doctrine-bundle": "^1.6.10", // 1.10.2
"doctrine/doctrine-migrations-bundle": "^1.3|^2.0", // v2.0.0
"doctrine/orm": "^2.5.11", // v2.7.2
"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
"phpdocumentor/reflection-docblock": "^3.0|^4.0", // 4.3.0
"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/cache": "^3.3|^4.0", // v4.1.4
"symfony/console": "^4.0", // v4.1.4
"symfony/flex": "^1.0", // v1.21.6
"symfony/framework-bundle": "^4.0", // v4.1.4
"symfony/lts": "^4@dev", // dev-master
"symfony/property-access": "^3.3|^4.0", // v4.1.4
"symfony/property-info": "^3.3|^4.0", // v4.1.4
"symfony/security-bundle": "^4.0", // v4.1.4
"symfony/serializer": "^3.3|^4.0", // v4.1.4
"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/stopwatch": "^3.3|^4.0", // v4.1.4
"symfony/var-dumper": "^3.3|^4.0", // v4.1.4
"symfony/web-profiler-bundle": "^3.3|^4.0" // v4.1.4
}
}
80 Comments
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....
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. ;-)
it doesn't work for me :(
Hey Paweł Ł.
That's odd. What database are you using?
That's a good fix or just use a different name for the table, something like
app_user. Cheers!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!
Hey Abelardo,
try running the command through the Symfony binary
symfony console make:migrationThe Symfony binary has an integration with Docker, so it will take care of setting your the environment variables properly
Cheers!
Hi there!
After rebuilding my containers and deleting my database, tables and so forth I could solve this issue.
Thanks for your help!
Cheers.
hello then I try to ./bin/console doctrine:fixtures:load
I got this error :-(
Hey Jörg daniel F.
Seems like you have a typo in the Fixtures file. Check
src/DataFixtures/UserFixture.php:21for the mistakesCheers!
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?
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!
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.
Hey @AbelardoLG!
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.
Usually this is just done via your session lifetime :)
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!
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.
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!
Ok, thanks for your comment.
Have a nice day! Brs from Madrid, España. :)
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.
Hey n0
You should have and encoded array of roles, not just one role inside your database. Value should be like
["ROLE_USER"]Cheers
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
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
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 :).
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!
No problem. It's also a good way to learn.
The code works fine for me but at the final part i am getting stuck.. the
gives an error. This is the message i get
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!
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.
Oh o noticed you answered that previously already. No post delete button though :/
Hey Wuwu,
Don't worry about deleting comments ;) Glad you found the answer!
Cheers!
When trying to load the fixtures i get this following error:
Cannot find any references for class "main_article"
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.
Hey Roby,
Great catch ;)
Cheers!
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?
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
!!
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)
Hey Petr T.
Have you looked inside
BaseFixtures.php? Probably something wrong inside this classCheers!
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.
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
Hey Vanderlam F.
Double check that you can connect to your database first. Check for the environment variable
DATABASE_URLinside.envor.env.local. If the URL is correct, then validate your schema by running the commandphp bin/console doctrine:schema:validateI hope it helps!
Cheers!
Also, where can I find these files so I can send whats on the line of error?
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:I suppose this is fine as long as it's set in the development or testing environment and not in production.
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.yamlfile, so other developers don't get confusedCheers!
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.
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!
Thank you, Ryan. It is perfectly.
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!
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 " ?
Hey Lukasz!
Why are you passing in a string? The first argument is for specifying how many records you want
Cheers!
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!
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
{
}`
"Houston: no signs of life"
Start the conversation!