I created this repository to showcase the use of DiscriminatorMap, as well as a listener that automatically attaches the connected user. It also includes a Doctrine extension that filters and returns only the data belonging to the authenticated user. Additionally, there is a SerializerContextBuilder that allows reading and writing attributes.
-
âś… DiscriminatorMap (in Element.php):
Uses DiscriminatorMap to associate the values 'email' and 'paper' with their respective classes. This entity implements the
AuthorInterface
andCurrentUserIsAuthorInterface
. It also leverages several annotations related to Doctrine and ApiPlatform, such as#[ApiFilter]
for handling filters and#[Groups]
for managing serialization groups. -
âś… AuthorInterface.php:
This file defines an
AuthorInterface
that ensures the presence of agetAuthor()
method. The currently authenticated user is then assigned using theAttachAuthorDoctrineListener
. -
âś… CurrentUserIsAuthorInterface.php:
This file defines the
CurrentUserIsAuthorInterface
, which is used to verify if the current user is the author of an element. It then applies theCurrentUserIsAuthorExtension
to ensure that authors can only access their created elements. -
âś… SerializerContextBuilder.php:
This file contains a class that extends
SerializerContextBuilderInterface
and overrides thecreateFromRequest()
method to add custom serialization groups based on the resource type and operation (collection, item, etc.). It also enables adding groups for parent classes, enhancing the flexibility of serialization levels depending on entities and their relationships. For instance, using the attribute#[Groups(['element:read', 'element:write'])]
.
-
src/DoctrineExtension/CurrentUserIsAuthorExtension.php
-
src/DoctrineListener/AttachAuthorDoctrineListener.php
-
src/Entity/DMS/Element.php
-
src/Entity/DMS/Email.php
-
src/Entity/DMS/Paper.php
-
src/Entity/AuthorInterface.php
-
src/Entity/CurrentUserIsAuthorInterface.php
-
src/Serializer/SerializerContextBuilder.php
make up
Update database docker compose exec php php bin/console d:s:u --force
Fill with fixtures docker compose exec php php bin/console doctrine:fixtures:load --no-interaction
POST /api/login_check
{
"email": "[email protected]",
"password": "1234"
}
{
"email": "[email protected]",
"password": "1234"
}
Using order on alls
GET https://localhost/vehicles?order[createdAt]=desc
Using order only on cars
GET https://localhost/cars?order[createdAt]=asc
Get all cars
GET https://localhost/bikes
Using Filter
GET https://localhost/vehicles?categories[]=/categories/12
{
"@context": "/contexts/Vehicle",
"@id": "/vehicles",
"@type": "hydra:Collection",
"hydra:totalItems": 40,
"hydra:member": [
{
"@id": "/bikes/153",
"@type": "Bike",
"carrier": true,
"id": 153,
"brand": "Triumph",
"createdAt": "2024-07-05T10:23:03+00:00"
},
{
"@id": "/cars/185",
"@type": "Car",
"numberOfDoors": 3,
"id": 185,
"brand": "Toyota",
"createdAt": "2024-07-04T08:40:18+00:00"
},
{
"@id": "/bikes/167",
"@type": "Bike",
"carrier": true,
"id": 167,
"brand": "Indian Motorcycle",
"createdAt": "2024-07-04T03:54:39+00:00"
},
],
"hydra:view": {
"@id": "/vehicles?order%5BcreatedAt%5D=desc&page=1",
"@type": "hydra:PartialCollectionView",
"hydra:first": "/vehicles?order%5BcreatedAt%5D=desc&page=1",
"hydra:last": "/vehicles?order%5BcreatedAt%5D=desc&page=2",
"hydra:next": "/vehicles?order%5BcreatedAt%5D=desc&page=2"
},
"hydra:search": {
"@type": "hydra:IriTemplate",
"hydra:template": "/vehicles{?order[id],order[brand],order[createdAt],brand}",
"hydra:variableRepresentation": "BasicRepresentation",
"hydra:mapping": [
{
"@type": "IriTemplateMapping",
"variable": "order[id]",
"property": "id",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[brand]",
"property": "brand",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[createdAt]",
"property": "createdAt",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "brand",
"property": "brand",
"required": false
}
]
}
}
{
"@context": "/contexts/Car",
"@id": "/cars",
"@type": "hydra:Collection",
"hydra:totalItems": 20,
"hydra:member": [
{
"@id": "/cars/176",
"@type": "Car",
"numberOfDoors": 252,
"id": 176,
"brand": "Honda",
"createdAt": "2024-06-05T16:30:08+00:00"
},
{
"@id": "/cars/189",
"@type": "Car",
"numberOfDoors": 23946130,
"id": 189,
"brand": "Toyota",
"createdAt": "2024-06-09T01:34:25+00:00"
},
{
"@id": "/cars/174",
"@type": "Car",
"numberOfDoors": 18,
"id": 174,
"brand": "Audi",
"createdAt": "2024-06-09T08:19:03+00:00"
}
],
"hydra:view": {
"@id": "/cars?order%5BcreatedAt%5D=asc",
"@type": "hydra:PartialCollectionView"
},
"hydra:search": {
"@type": "hydra:IriTemplate",
"hydra:template": "/cars{?order[id],order[brand],order[createdAt],order[numberOfDoors],order[id],order[brand],order[createdAt],order[numberOfDoors],brand}",
"hydra:variableRepresentation": "BasicRepresentation",
"hydra:mapping": [
{
"@type": "IriTemplateMapping",
"variable": "order[id]",
"property": "id",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[brand]",
"property": "brand",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[createdAt]",
"property": "createdAt",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[numberOfDoors]",
"property": "numberOfDoors",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[id]",
"property": "id",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[brand]",
"property": "brand",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[createdAt]",
"property": "createdAt",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[numberOfDoors]",
"property": "numberOfDoors",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "brand",
"property": "brand",
"required": false
}
]
}
}
{
"@context": "/contexts/Bike",
"@id": "/bikes",
"@type": "hydra:Collection",
"hydra:totalItems": 20,
"hydra:member": [
{
"@id": "/bikes/72",
"@type": "Bike",
"carrier": false,
"id": 72,
"brand": "BMW Motorrad"
},
{
"@id": "/bikes/73",
"@type": "Bike",
"carrier": false,
"id": 73,
"brand": "Yamaha"
},
{
"@id": "/bikes/74",
"@type": "Bike",
"carrier": false,
"id": 74,
"brand": "Ducati"
}
],
"hydra:search": {
"@type": "hydra:IriTemplate",
"hydra:template": "/bikes{?order[id],order[brand],order[hasCarrier],brand}",
"hydra:variableRepresentation": "BasicRepresentation",
"hydra:mapping": [
{
"@type": "IriTemplateMapping",
"variable": "order[id]",
"property": "id",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[brand]",
"property": "brand",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "order[hasCarrier]",
"property": "hasCarrier",
"required": false
},
{
"@type": "IriTemplateMapping",
"variable": "brand",
"property": "brand",
"required": false
}
]
}
}