api-platform / api-platform

🕸️ Create REST and GraphQL APIs, scaffold Jamstack webapps, stream changes in real-time.
https://api-platform.com
MIT License
8.68k stars 961 forks source link

Custom Filter on yaml not working #1564

Open Vilsafur opened 4 years ago

Vilsafur commented 4 years ago

Hi,

I've create a custom filter. It's working when I implement him with annotation but not when implementing in YAML (with or without App\Filter\CritereFilter declaration).

The SearchFilter working in YAML and Annotation.

The Yaml implementation :

services:
    App\Filter\CritereFilter:
        arguments: 
            $managerRegistry: '@doctrine'
            $requestStack: ~
            $iriConverter: '@api_platform.iri_converter'
            $propertyAccessor: '@api_platform.property_accessor'
            $logger: '@logger'
            $identifiersExtractor: '@?api_platform.identifiers_extractor.cached'
            $nameConverter: '@?api_platform.name_converter'
        public: false
        abstract: true
    entity.searchFilter:
        parent: 'api_platform.doctrine.orm.search_filter'
        tags: [ { name: 'api_platform.filter', id: 'entity.searchFilter' } ]
        arguments: [  { 'field1': "exact" } ]
        autowire: false
        autoconfigure: false
    entity.critereFilter:
        parent: 'App\Filter\CritereFilter'
        tags: [ { name: 'api_platform.filter', id: 'entity.critereFilter' } ]
        arguments: 
            $properties: 
                'field2.field': "exact"
        autowire: false
        autoconfigure: false
App\Entity\Entity:
    normalization_context:
        groups:
            api_rpc_reponse
    collectionOperations:
        get:
            filters: 
                - 'entity.searchFilter'
                - 'entity.critereFilter'

    itemOperations:
        - get

The Annotation implementation:

/**
 * @ApiFilter(
 *      CritereFilter::class,
 *      properties={
 *          "garanties.franchise": "exact"
 *      }
 * )
 */
class CritereFilter extends SearchFilter
{
    public function __construct(
        ManagerRegistry $managerRegistry,
        ?RequestStack $requestStack,
        IriConverterInterface $iriConverter,
        PropertyAccessorInterface $propertyAccessor = null,
        LoggerInterface $logger = null,
        array $properties = null,
        IdentifiersExtractorInterface $identifiersExtractor = null,
        NameConverterInterface $nameConverter = null
    ) {
        // ... code
        parent::__construct(
            $managerRegistry,
            $requestStack,
            $iriConverter,
            $propertyAccessor,
            $logger,
            $properties,
            $identifiersExtractor,
            $nameConverter
        );
    }
}

Have you an idea what's wrong with the YAML's configuration ?

mcn-fredw commented 4 years ago

For our working custom filter, the differences I see are your arguments to the base service App\Filter\CritereFilter.

        arguments:
            $managerRegistry: '@doctrine'
            $requestStack: null
            $iriConverter: '@api_platform.iri_converter'
            $propertyAccessor: '@api_platform.property_accessor'
            $logger: '@logger'
            $identifiersExtractor: '@api_platform.identifiers_extractor.cached'
            $nameConverter: '@api_platform.name_converter'
Vilsafur commented 4 years ago

Thank you for that answer, but after trying, it doesn't work.

The filter doesn't appear.

mcn-fredw commented 4 years ago

You don't need the constructor in your class unless you are doing some logic there with the parameters. Don't see an apply() or getDescription() method there, so I assumed you just stripped them out for the issue post. "Doesn't appear" sounds like you don't have a description for the filter class. Does bin/console cache:clear report any errors? api-platform silently ignores filters that don't load for some reason.

Vilsafur commented 4 years ago

Sorry for the late reply.

Unfortunnately, it's same. I don't have apply() or getDescription() methods because I extend of SearchFilter class who have this methods. The command bin/console cache:clear have no error and, in log, I don't have ignored filters. It's just like i don't have filter.

mcn-fredw commented 4 years ago

In your actual service declaration, do you have the same property name as in the annotation declaration?

    entity.critereFilter:
        parent: 'App\Filter\CritereFilter'
        tags: [ { name: 'api_platform.filter', id: 'entity.critereFilter' } ]
        arguments: 
            $properties: 
                'garanties.franchise': "exact"
        autowire: false
        autoconfigure: false