I have Entity user:
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\DiscriminatorColumn;
use Doctrine\ORM\Mapping\DiscriminatorMap;
use Doctrine\ORM\Mapping\InheritanceType;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* User entity.
*
* @ApiResource(
* attributes={
* "order"={"lastname"="ASC"}
* },
* collectionOperations={
* },
* itemOperations={
* "get"={
* "normalization_context"={"groups"={"user_read"}}
* }
* }
* )
*
* @ORM\Entity
* @ORM\Table(name="user")
*
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="type", type="integer")
* @DiscriminatorMap({0 = "User", 1 = "Doctor"})
*/
class User
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer", nullable=false, options={"unsigned"=true})
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="firstname", type="string", length=255, nullable=false)
*
* @Groups({"user_read"})
*/
private $firstname;
/**
* @var string
*
* @ORM\Column(name="lastname", type="string", length=255, nullable=false)
*
* @Groups({"user_read"})
*/
private $lastname;
/**
* @var string
*
* @ORM\Column(name="phone", type="string", length=255, nullable=false)
*
* @Groups({"user_read"})
*/
private $phone;
/**
* @var string|null
*
* @ORM\Column(name="email", type="string", length=255, nullable=false)
*
* @Groups({"user_read"})
*/
private $email;
/**
* @var string
*
* @ORM\Column(name="password", type="string", length=255, nullable=false)
*/
private $password;
/**
* @var bool
*
* @ORM\Column(name="active", type="boolean", nullable=false)
*
* @Groups({"user_read"})
*/
private $active = true;
// getters and setters...
}
And inherited entity Doctor:
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* Doctor entity.
*
* @ApiResource(
* attributes={
* "order"={"lastname"="ASC"}
* },
* collectionOperations={},
* itemOperations={
* "get"={
* "normalization_context"={"groups"={"doctor_read"}}
* }
* }
* )
*
* @ORM\Entity
* @ORM\Table(name="doctor")
*/
class Doctor extends User
{
/**
* @var string|null
*
* @ORM\Column(name="title_before", type="string", length=255, nullable=true)
*
* @Groups({"doctor_read"})
*/
private $titleBefore;
/**
* @var string|null
*
* @ORM\Column(name="title_after", type="string", length=255, nullable=true)
*
* @Groups({"doctor_read"})
*/
private $titleAfter;
/**
* @var string|null
*
* @ORM\Column(name="work_name", type="string", length=255, nullable=true)
*
* @Groups({"doctor_read"})
*/
private $workName;
/**
* @var string|null
*
* @ORM\Column(name="work_street", type="string", length=255, nullable=true)
*
* @Groups({"read", "write"})
*
* @Groups({"doctor_read"})
*/
private $workStreet;
/**
* @var string|null
*
* @ORM\Column(name="work_zip", type="string", length=255, nullable=true)
*
* @Groups({"doctor_read"})
*/
private $workZip;
/**
* @var string|null
*
* @ORM\Column(name="work_city", type="string", length=255, nullable=true)
*
* @Groups({"doctor_read"})
*/
private $workCity;
/**
* @var string|null
*
* @ORM\Column(name="work_phone", type="string", length=255, nullable=true)
*
* @Groups({"doctor_read"})
*/
private $workPhone;
/**
* @var bool
*
* @ORM\Column(name="signature", type="boolean", nullable=false)
*/
private $signature = false;
// getters and setters...
}
There is api:swagger:export results:
swagger: '2.0'
basePath: /
info:
title: ''
version: 1.0.0
paths:
'/api/doctors/{id}':
get:
tags:
- Doctor
operationId: getDoctorItem
produces:
- application/ld+json
- application/json
- text/html
summary: 'Retrieves a Doctor resource.'
parameters:
-
name: id
in: path
required: true
type: string
responses:
200:
description: 'Doctor resource response'
schema:
$ref: '#/definitions/Doctor-doctor_read'
404:
description: 'Resource not found'
'/api/users/{id}':
get:
tags:
- User
operationId: getUserItem
produces:
- application/ld+json
- application/json
- text/html
summary: 'Retrieves a User resource.'
parameters:
-
name: id
in: path
required: true
type: string
responses:
200:
description: 'User resource response'
schema:
$ref: '#/definitions/User-user_read'
404:
description: 'Resource not found'
securityDefinitions:
apiKey:
type: apiKey
in: header
description: 'Value for the Authorization: Bearer header'
name: 'Authorization: Bearer'
security:
-
apiKey: []
definitions:
Doctor-doctor_read:
type: object
description: 'Doctor entity.'
properties:
titleBefore:
type: string
titleAfter:
type: string
workName:
type: string
workStreet:
type: string
workZip:
type: string
workCity:
type: string
workPhone:
type: string
User-user_read:
type: object
description: 'User entity.'
properties:
firstname:
type: string
lastname:
type: string
phone:
type: string
email:
type: string
active:
type: boolean
titleBefore:
type: string
titleAfter:
type: string
workName:
type: string
workStreet:
type: string
workZip:
type: string
workCity:
type: string
workPhone:
type: string
signature:
type: boolean
id:
readOnly: true
type: integer
password:
type: string
As you can see, User-user_read object has all properties from Doctor-doctor_read, even signature property, which is not in scope of get operation on Doctor entity (not in group doctor_read).
I think, problem is in ApiPlatform\Core\Metadata\Property\Factory\InheritedPropertyNameCollectionFactory line 54:
if (is_subclass_of($knownResourceClass, $resourceClass)) {
foreach ($this->create($knownResourceClass) as $propertyName) {
$propertyNames[$propertyName] = $propertyName;
}
}
First of all, its completely ignore groups, so there is first correction:
foreach ($this->create($knownResourceClass, $options) as $propertyName) {
And I am not sure why there is this part of code at all.
If I have resource User, I don`t expect data from resource Doctor , even when I want to get all users and in collection will be some doctors as well. Am I wrong?
I have Entity user:
And inherited entity Doctor:
There is api:swagger:export results:
As you can see, User-user_read object has all properties from Doctor-doctor_read, even signature property, which is not in scope of get operation on Doctor entity (not in group doctor_read).
I think, problem is in ApiPlatform\Core\Metadata\Property\Factory\InheritedPropertyNameCollectionFactory line 54:
First of all, its completely ignore groups, so there is first correction:
And I am not sure why there is this part of code at all.
If I have resource User, I don`t expect data from resource Doctor , even when I want to get all users and in collection will be some doctors as well. Am I wrong?