Chapters
28 Chapters
|
2:24:59
|
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!
28.
Criteria System: Champion Collection Filtering
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!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
This course is built on Symfony 3, but most of the concepts apply just fine to newer versions of Symfony.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": "^7.1.3",
"symfony/symfony": "3.4.*", // v3.4.49
"doctrine/orm": "^2.5", // 2.7.5
"doctrine/doctrine-bundle": "^1.6", // 1.12.13
"doctrine/doctrine-cache-bundle": "^1.2", // 1.4.0
"symfony/swiftmailer-bundle": "^2.3", // v2.6.7
"symfony/monolog-bundle": "^2.8", // v2.12.1
"symfony/polyfill-apcu": "^1.0", // v1.23.0
"sensio/distribution-bundle": "^5.0", // v5.0.25
"sensio/framework-extra-bundle": "^3.0.2", // v3.0.29
"incenteev/composer-parameter-handler": "^2.0", // v2.1.4
"composer/package-versions-deprecated": "^1.11", // 1.11.99.4
"knplabs/knp-markdown-bundle": "^1.4", // 1.9.0
"doctrine/doctrine-migrations-bundle": "^1.1", // v1.3.2
"stof/doctrine-extensions-bundle": "^1.2" // v1.3.0
},
"require-dev": {
"sensio/generator-bundle": "^3.0", // v3.1.7
"symfony/phpunit-bridge": "^3.0", // v3.4.47
"nelmio/alice": "^2.1", // v2.3.6
"doctrine/doctrine-fixtures-bundle": "^2.3" // v2.4.1
}
}
25 Comments
Big thanks!
One problem:
Invalid:
->orderBy(['yearsStudied', 'DESC'])Valid
->orderBy(['yearsStudied' => 'DESC'])Information from official repository Doctrine Collections: <a href="https://github.com/doctrine/collections/blame/5f0470363ff042d0057006ae7acabc5d7b5252d5/lib/Doctrine/Common/Collections/Criteria.php#L154">Link to github</a>
Hey Maxim M.
I don't fully get it. In the link you posted I see that the `orderBy` method accepts an array, and about your second example (the valid one) I think it won't even compile (unless Disqus messed up with your syntax)
Cheers!
I made a typo. Already changed the original post.
Hey Maxim M.
Sorry for my slow reply, SymfonyWorld week was crazy. I see now your point. We'll add a note about it
Cheers!
I have a n+1 problem, that why I need to join to another table.
I could create a new Method inside my repository and join the other table to solve it.
But the correct and more elegant way would be to use criteria to do this (Because I have the benefit of calling my Action inside my entity and don't have to write any Controller code)
But how the heck can I write ->join() with the Criteria system? I haven't found a solution.
Its really simple with the query builder, but is it possible with the Criteria system as well and how?
You could use filter instead of matching eg inside a Contrat Entity, and even combine them :
`
public function getActiveContrat(): Collection
{
$criteria = Criteria::create()
$sub = 'Baz';
return $this->contrats
->matching($criteria);
}
`
Hey Mike P.!
I can't remember for sure, but I *think* I checked into that a bit when I wrote this tutorial and I *think* it's not possible. In other words, I think you'll need to do a repository method for this :/.
Sorry I didn't have better news!
Cheers!
Thank you very much for your reply Ryan!
Is it correct as well, that with Criteria() we can't do custom querys like SELECT AVG() or SELECT SUM()?
I can't find any possibility via google or in the source code.
Hey Mike P.!
Criteria are such a strange, little-known, little-documented feature :p. I believe you are correct. I've never tried it, but I believe that this system is all about *filtering* and re-ordering results, but not controlling which fields (or a SUM for example) are included. It's a shame - because I'm sure all these things are possible to implement in that system - but someone needs to do it... and Doctrine is complex.
Cheers!
I have a question about de criteria filter on collection. When i use an criteria betweenDates and have a second criteria with byPerson does doctrine filter first the betweenDate and then byPerson? This because of performances.
Or is it better to use a querybuilder with the given dates. parse it trough an arrayCollection and then use the criteria byPerson?
I'm Courious ..
Cheers Rob
Hey Rsteuber
That's a good question. A criteria it's only a way to add more statements to your query, in this case more clauses to the WHERE. So, I think it relies on the DB engine you are using (MySql, Postgres, etc). What you can do is to execute your code and watch the final ran query in the profiler
Cheers!
You helped me a lot with this series on many2many relationsships, thanks a lot!
I have one question about the criteria filtering. Would it be possible to order the genus experts in the getExpertScientists method by a field in the user table? I now have a special query builder in the repository class, but I am not sure, if this works with the form system because it (as far as I understand it) would use the getExpertScientists in the genus class, right?
Hey Luc!
Awesome - very happy to hear things make more sense now!
Now, about your question :). First, yes, if you're using the CollectionType like we do in this tutorial, then the form system will call getExpertScientists in order to know which embedded forms to list on the page (assuming your form field is called
expertScientists). Unfortunately, it looks like the Criteria system does not support joining :(. This is definitely a bummer - there's an issue about it here: https://github.com/doctrine/doctrine2/issues/2918. So, the only way I can think to do this is in the old, inefficient way - e.g. ingetExpertScientists, loop over all scientists and manually create an array with only the ones you want. This will work fine, unless you have a HUGE list of scientists. If you DO have a huge list, then you would need to do something a bit more clever/ugly, like setting themappedoption to false on that field, and manually setting the data on it in the controller$form['expertScientists']->setData($filteredExpertScientists).Let me know if that helps! Cheers!
Hello Ryan,
Thank you for the tip, its works great with an iterator and uasort in the getExpertScientists (well, in my version returning phone numbers). It is OK in this situation to do it in the getter, since a user only has a hand-full of numbers. But it is good to know that it could also work for larger arrays with the mapped-option.
Awesome! And great question :)
Thrilled I got through the series! It was fantastic and instrumental to my building my own Symfony web app. That being said, I'm surprised we got all the way to the end and the tutorial app isn't really finished. Are there going to be more tutorials based on this project?
Woohoo! Congrats! I understand what you mean - the app won't ever really be finished - when we write the tutorials, we emphasize teaching the important stuff... not necessarily working on all the small, less-important details to get the app fully ready. And then, we also keep adding onto it as more important topic become obvious :). Right now, we don't have anything immediately planned for this tutorial series. However, in the future, we do want to cover deployment, HTTP caching, unit testing, file upload, and a potentially a bunch of other topics. If there's something you feel is missing after going through everything, I'd be eager to know it!
Cheers!
I like the idea having criterias mapping to one "business rule" to select different subsets of my entities.
But using this with more that one entity leads to an error I described here:
https://stackoverflow.com/q...
Maybe someone has done this before or can give me a better solution to this.
Hey Benutzer
Nice question! There you have an answer in SO. Ff you want to choose the Criteria's way, you will have to provide an alias. it can be a constant living in the Owner Repository class, but you will have to pass it every time
Another thing you can do is, only use a Criteria for your entities and use the QueryBuilder in your repositories instead. This might look as code duplication, but you are working in two separate layers. The QueryBuilder works at the DataBase layer, modifying the query directly, and your entities works with Collections. So, I think this duplication is a good thing, because it gives you more flexibility.
Cheers!
As soon as I switched to Doctrine's Criteria system I started getting this error:
Hey Giorgio,
Could you show us the line 20 in your "genus/list.html.twig" template? And the code where you use those Doctrine Criteria which caused this error?
Cheers!
Here it is! Should have posted it with my comment now that I think about it.
Twig:
`{{ genus.genusScientists|length }} ({{ genus.expertScientists|length }} experts)
`Php:
Thank you!
Hi from 2018, Symfony 4.1.4.
I had a similar error using Criteria and i fix the array to make it work:
->orderBy(['yearsStudied' => 'DESC']);
Hi Giorgio,
Try to remove the ->orderBy() section to see the error disappear.
Regards,
Hey Giorgio,
Hm, I don't any problems with your code, actually, it's exactly the same code as we have in screencast. I wonder, what if you just return "$this->getGenusScientists()" in this "getExpertScientists()" method. Does it fix the error? Because I suppose the problem in another place and the error should remain.
Cheers!
"Houston: no signs of life"
Start the conversation!