Chapters
48 Chapters
|
5:13:28
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
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!
13.
Setting a Custom Field Via a Listener
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 tutorial also works great with API Platform 2.6.
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^2.1", // v2.5.10
"composer/package-versions-deprecated": "^1.11", // 1.11.99
"doctrine/annotations": "^1.0", // 1.12.1
"doctrine/doctrine-bundle": "^2.0", // 2.1.2
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.0.2
"doctrine/orm": "^2.4.5", // 2.8.2
"nelmio/cors-bundle": "^2.1", // 2.1.0
"nesbot/carbon": "^2.17", // 2.39.1
"phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.0", // 5.2.2
"ramsey/uuid-doctrine": "^1.6", // 1.6.0
"symfony/asset": "5.1.*", // v5.1.5
"symfony/console": "5.1.*", // v5.1.5
"symfony/debug-bundle": "5.1.*", // v5.1.5
"symfony/dotenv": "5.1.*", // v5.1.5
"symfony/expression-language": "5.1.*", // v5.1.5
"symfony/flex": "^1.1", // v1.21.6
"symfony/framework-bundle": "5.1.*", // v5.1.5
"symfony/http-client": "5.1.*", // v5.1.5
"symfony/monolog-bundle": "^3.4", // v3.5.0
"symfony/security-bundle": "5.1.*", // v5.1.5
"symfony/twig-bundle": "5.1.*", // v5.1.5
"symfony/validator": "5.1.*", // v5.1.5
"symfony/webpack-encore-bundle": "^1.6", // v1.8.0
"symfony/yaml": "5.1.*" // v5.1.5
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3", // 3.3.2
"symfony/browser-kit": "5.1.*", // v5.1.5
"symfony/css-selector": "5.1.*", // v5.1.5
"symfony/maker-bundle": "^1.11", // v1.23.0
"symfony/phpunit-bridge": "5.1.*", // v5.1.5
"symfony/stopwatch": "5.1.*", // v5.1.5
"symfony/twig-bundle": "5.1.*", // v5.1.5
"symfony/web-profiler-bundle": "5.1.*", // v5.1.5
"zenstruck/foundry": "^1.1" // v1.8.0
}
}
6 Comments
Hi,
how might one filter/create a custom API platform filter for a virtual property like 'isMe'? If someone wanted an API client to be able to filter and retrieve either all resources where isMe is set to false, or all resource where isMe is set to true, how would one best go about that, considering pagination should still be maintained. In the later videos you talk about a custom data provider and a custom paginator, would both these need to be implemented?
Many thanks
Hey Johanna B.!
My apologies for the very slow reply - I was just starting a holiday when you commented, and the team left this (tough) question for me :). I think, unless I'm neglecting a complication - that adding a filter for a virtual property would not be any different than any other custom filter. For example, here is the main video where we implement a custom filter for a Doctrine entity - https://symfonycasts.com/screencast/api-platform-extending/entity-filter-logic
In that example, in getDescription(), we name the filter "search". But that does not need to correspond to any property name on our class. So we could also call it "isMe" or "fooBar". It really controls what the query parameter will be called. So, assuming you call your filter isMe, in filterProperty, if
$propertyis set toisMe, then you could then do whatever logic you wanted to modify the query. Specifically, you would probably get the current user and add something like:If you do this, I think it's all you need. You would still be using the built-in entity data provider, which is nice because that also automatically handles pagination. For example, if I own 50 CheeseListing, then the results for isMe=1 would automatically be paginated for me.
If I'm missing some complication, let me know - I'm just thinking through this problem, so something may not be occurring to me :).
Cheers!
Many thanks for your reply! Yes, that makes a lot of sense to me. If you don't mind me asking another question - what now happens if we have a virtual property which we cannot (feasibly) filter for using the queryBuilder, perhaps because it involves very complicated logic and is far removed from any property mapped to the database? I hope my question makes sense! Many thanks
Hey Johanna B.!
My pleasure - but sorry for the slow reply to this one! :).
> what now happens if we have a virtual property which we cannot (feasibly) filter for using the queryBuilder, perhaps because it involves very complicated logic and is far removed from any property mapped to the database
One way or another (even if you were building a normal web app and not an API), you will need to create a query to pull items back from the database. So, somehow, you really need to modify the query to fetch the results you need. If, for some reason, the logic was SO complex that you needed to make a query to the database... and then do extra logic in PHP to filter the final results then, hmm, I think you would need a completely custom data provider for this :). But then you would need to manually add pagination support to that.
Cheers!
There are several entities in our projects that have a "json_data" field (json type in MySQL). This happens because, as our systems are used in several different clients, there are clients of ours that need some specific fields, and instead of creating fields directly in our entities and tables in MySQL (and that way we end up with polluted tables with many fields that don't make sense to other customers of ours), we store as dynamic fields within that json_data field.
I wonder if there is any way to correctly display these peculiarities in the swagger documentation.
The idea of "dynamic fields" within the json field would not be to prevent the API user from sending any invalid values (this validation is done in another way, at runtime), but simply to inform that that installation of our system expects to receive such and such dynamic fields. I don’t intend to create any type of validation to prevent the user from sending fields beyond what is expected, because, over time, new dynamic fields can be created, so that part of the records in the tables would be from a previous "json metadata" and another part would already have the values of a more current "json metadata".
If there was a way to "hack" swagger documentation to inform the user about this details would be nice. And it would be perfect if api-platform created the calls to POST already showing the fields inside json!
Hey Carlos!
That's a pretty interesting question :). I can, at least, give you some hints!
A) What you ultimately want to do is update the OpenAPI JSON documentation - which you can see directly if you go to /api/docs.json.
B) This JSON is created just like any other JSON in the system: via a normalizer. Specifically, it is this DocumentationNormalizer - https://github.com/api-plat...
C) So, like anything else in the system, you can add a custom normalizer that "extends" this. Though, I have never done this, and this is a very complex class :). Iirc, it eventually calls - https://github.com/api-plat... - so if I'm correct, it may even be easier to "decorate" this... or I think it also uses the "property name collection factory" to get the "array of all properties for a class"... and so you could also create a custom https://github.com/api-plat... and use decoration to put your custom class into the system (your custom property name collection factory would return your dynamic properties).
That was a big brain dump - let me know if any of it helps :).
Cheers!
"Houston: no signs of life"
Start the conversation!