ApiPlatform ApiFilter no working when using Custom StateProvider 2024

37 Views Asked by At

I've seen this question here before but none of the solutions worked and can't understand why.

My Class (Not an Entity)

use ApiPlatform\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Metadata\ApiFilter;
use ApiPlatform\Metadata\GetCollection;
use App\State\CustomStateProvider;
use DateTimeInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
    #[GetCollection(formats: [
    'jsonld',
    'json',
    'html',
    'csv' => 'text/csv' ], 
    shortName: 'APIS WURTH',
    paginationItemsPerPage: 5,
    description: 'Endpoints de Test para Wurth',
    //filters: ['dossier' => 'exact'],
    filters: [
        'clearence' => 'partial',
        'reference' => 'exact'
    ],
    provider: CustomStateProvider::class
)]
#[ApiFilter(SearchFilter::class, properties: ['clearence'=> 'partial', 'reference' => 'exact'])]
class MyApiDataClass{...}

My Provider:

class CustomStateProvider implements ProviderInterface
{
    public function __construct(private readonly EntityManagerInterface $em, private readonly SerializerInterface $serializer){}
    public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
    {
        if ($operation instanceof CollectionOperationInterface) {              
            $all = $this->getDataCollection();
            $data = [];
            foreach ($all as $a) {
                $data[] = $this->serializer->deserialize($a, MyApiDataClass::class, 'json');
            }
            return $data;
        }
        {...}
    }
}

All answers i've seen are more than 4 years old and i don't know how to adapt the answers to this. Filters are working. Here is another working class:

#[ORM\Table(name: 'MyTable')]
#[ORM\Entity]
#[ApiResource(
    shortName: 'My Api',
    description: '...',
    operations: [
        new GetCollection(uriTemplate: '/test'),
        new Get(uriTemplate: '/test/{id}'),
    ],
    formats: [
        'jsonld',
        'json',
        'html',
        'jsonhal',
        'csv' => 'text/csv'
    ],
    paginationItemsPerPage: 10
)]
#[ApiFilter(BooleanFilter::class, properties: ['sent'])]
#[ApiFilter(SearchFilter::class, strategy: 'exact', properties: ['element'])]
class DocumentsQue {...}

This is perfectly working. Is it because this is an Entity? or because the other uses CustomStateProvider? Can't figure it out.

Regular with filters: enter image description here

Custom no filters: enter image description here

I'm sure i'm missing somthing obvius but i've spend so much time. Anything helps at this point. Thanks in advance

1

There are 1 best solutions below

0
SpicyTacos23 On

After several hours of try/error i've found the solution.

#[ApiResource(
    shortName: 'APIS TEST',
    description: '...',
    operations: [
        new GetCollection(
            uriTemplate: 'test',
            openapiContext: [
                "parameters" => [
                    [
                        "name" => 'field1',
                        "in" => 'query',
                        "description" => '...',
                        "schema" => [
                            "type" => "string"
                        ]
                    ],
                    [
                        "name" => 'field2',
                        "in" => 'query',
                        "description" => '...',
                        "schema" => [
                            "type" => "string"
                        ]
                    ]

                ]
            ],
            class: MyApiDataClass::class,
            paginationItemsPerPage: 5,
            description: '...',
        ),
    ],
    formats: [
        'jsonld',
        'json',
        'html',
        'csv' => 'text/csv'],
    paginationItemsPerPage: 5,
    provider: CustomStateProvider::class,
    extraProperties: ['field1', 'field2']
)]
#[ApiFilter(SearchFilter::class, properties: ['field1' => 'partial', 'field2' => 'exact'])]

Since ApiFilter doesn't work when using Custom State Providers. Manually configuring openapiContext will do the trick.

Hope i can help anyboy facing the same issue. It was a really simple thing that it took me long enough.

I got the solution from this post. znizzardini 's answer. Cheers!