API Platform 2.7 with PHP8 Attribute exception on ApiSubResource

98 views Asked by At

I am facing an issue from days by trying to upgrade my code from PHP 7.4 to PHP8.x.

I am working with Symfony 5.4 and API Platform 2.7.16.

My problem concern an ApiSubresource link.
Indeed, I have a class attribute on my entity which refers to another class which is not an Entity as SubResource.

When I am dealing with PHP 7 annotation, everything is fine, but when I switch to PHP8 Attributes, it does not work anymore.

I have to say, I made changes in doctrine config file for working with attributes and not annotations obviously.

Here is the Annotations form entity

<?php

namespace App\AwesomeDirectory\Entity;

/**
 * @ApiResource(
 *     forceEager=false,
 *     order={"sortableName"="ASC"},
 *     attributes={
 *         "pagination_enabled"=true,
 *         "pagination_client_enabled"=false,
 *         "pagination_items_per_page"=15,
 *         "pagination_maximum_items_per_page"=30
 *     },
 *     normalizationContext={"groups"={"group:read"}},
 *     denormalizationContext={"groups"={"group:write"}},
 *     collectionOperations={...},
 *     itemOperations={...},
 *     subresourceOperations={...}
 * )
 * @ORM\Entity(repositoryClass=FooRepository::class)
 * @Gedmo\SoftDeleteable(fieldName="deletedAt", hardDelete=false)
 * @Gedmo\Loggable
 * @ORM\HasLifecycleCallbacks()
 */
class Foo extends BaseEntity
{

    // ... Class variables ...

    
    /**
     * @ApiSubresource
     * @var Bar[]
     * @ApiProperty(security="is_granted('AWESOME_ROLE')")
     */
    private $bars;
 
    // ...
}

The Bar class, still with Annotations' style

<?php

namespace App\AwesomeDirectory\Model;


/**
 * @ApiResource(
 *     normalizationContext={"groups"={...}},
 *     itemOperations={
 *         "get"={
 *             "controller"=NotFoundAction::class
 *         }
 *     },
 *     collectionOperations={},
 *     subresourceOperations={
 *         "api_foos_bars_get_subresource"={
 *             "security"="is_granted('read_foo_simple_subresource', request.attributes.get('id'))"
 *          }
 *     }
 * )
 */
class Bar 
{
    /**
     * @Groups({"foo_bar:read"})
     * @ApiProperty(readableLink=false)
     */
    private ?Foo $foo;

    /**
     * @Groups({"foo_indicator:read"})
     * @ApiProperty(
     *     attributes={
     *         "openapi_context"={
     *             "array"={
     *                 "Fubar"="baz"
     *             }
     *         }
     *     }
     * )
     */
    private ?string $name;

    /**
     * @Groups({"foo_bar:read"})
     */
    private ?float $value;

    /**
     * @ApiProperty(identifier=true)
     */
    public function getId(): string
    {
        // ...
    }

    public function getFoo(): ?Foo
    {
        return $this->foo;
    }

    public function setFoo(?Foo $foo): self
    {
        $this->foo = $foo;

        return $this;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(?string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getValue(): ?float
    {
        return $this->value;
    }

    public function setValue(?float $value): self
    {
        $this->value = $value;

        return $this;
    }
}

And now the PHP8's attributes' style :

<?php
declare(strict_types=1);

namespace App\AwesomeDirectory\Entity;

#[ApiResource(
    collectionOperations: [...],
    itemOperations: [...],
    subresourceOperations: [...],
    attributes: [
        'pagination_enabled' => true,
        'pagination_client_enabled' => false,
        'pagination_items_per_page' => 15,
        'pagination_maximum_items_per_page' => 30,
    ],
    denormalizationContext: ['groups' => ['group:write']],
    forceEager: false,
    normalizationContext: ['groups' => ['group:read']],
    order: ['sortableName' => 'ASC'],
)]
#[ORM\Entity(repositoryClass: FooRepository::class)]
#[Gedmo\SoftDeleteable(fieldName: 'deletedAt', hardDelete: false)]
#[Gedmo\Loggable]
#[ORM\HasLifecycleCallbacks]
class Foo extends BaseEntity
{
    // ... class attributes ...
    
    #[ApiSubresource]
    #[ApiProperty(security: "is_granted('AWESOME_ROLE')")]
    private array $bars;

    // ...
}  

The Bar class, Attributes' style

<?php
declare(strict_types=1);

namespace App\AwesomeDirectory\Model;

#[ApiResource(
    collectionOperations: [],
    itemOperations: ['get' => ['controller' => NotFoundAction::class]],
    subresourceOperations: [
        'api_foos_bars_get_subresource' => [
            'security' => "is_granted('read_foo_simple_subresource', request.attributes.get('id'))"
        ]
    ],
    normalizationContext: ['groups' => ['foo_bar:read']]
)]
final class Bar
{
    #[Groups(['foo_bar:read'])]
    #[ApiProperty(readableLink: false)]
    private ?Foo $foo;

    #[Groups(['foo_bar:read'])]
    #[ApiProperty(attributes: ['openapi_context' => ['array' => ['Fubar' => 'baz']]])]
    private ?string $name;

    #[Groups(['foo_bar:read'])]
    private ?float $value;

    #[ApiProperty(identifier: true)]
    public function getId(): string
    {
        // ...
    }

    public function getFoo(): ?Foo
    {
        return $this->foo;
    }

    public function setFoo(?Foo $foo): self
    {
        $this->foo = $foo;

        return $this;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(?string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getValue(): ?float
    {
        return $this->value;
    }

    public function setValue(?float $value): self
    {
        $this->value = $value;

        return $this;
    }
}

In the Annotations' style, everything works well, but in Attributes' style, I have this issue :

SELECT o FROM App\AwesomeDirectory\Entity\Foo o WHERE o IN(SELECT WHERE id_a1.id = :id_p1)
[Syntax Error] line 0, col 67: Error: Unexpected 'WHERE'

The Data Provider Context is :

Context
[▼
  "property" => "bars"
  "identifiers" => [▼
    "id" => [▼
      "App\AwesomeDirectory\Entity\Foo"
      "id"
      true
    ]
  ]
  "collection" => false
  "operationId" => "api_foos_bars_get_subresource"
  "groups" => [▼
    "group:read"
    "common:read"
  ]
  "operation_type" => "subresource"
  "subresource_operation_name" => "api_foos_bars_get_subresource"
  "iri_only" => false
  "input" => null
  "output" => null
  "resource_class" => "App\AwesomeDirectory\Entity\Patient"
  "request_uri" => "/api/foos/e3d27cbd-696a-4994-b7d5-cfb3195a3c80/bars"
  "uri" => "https://localhost:8000/api/foos/e3d27cbd-696a-4994-b7d5-cfb3195a3c80/bars"
  "subresource_identifiers" => [▼
    "id" => "e3d27cbd-696a-4994-b7d5-cfb3195a3c80"
  ]
  "subresource_resources" => [▼
    "App\AwesomeDirectory\Entity\Foo" => [▼
      "id" => "e3d27cbd-696a-4994-b7d5-cfb3195a3c80"
    ]
  ]
  "disable_type_enforcement" => true
  "skip_null_values" => false
  "enable_max_depth" => true
  "has_identifier_converter" => true
]

Could you point me out where is the issue and/or help me to solve it please ? I am pacing around with this issue and drives me crazy :)

Thanks !

0

There are 0 answers