Estoy usando Symfony 5 y la plataforma API.
Una clase mía tiene una de sus propiedades configuradas a través de un oyente postLoad . La propiedad solo se establece bajo ciertas condiciones (de lo contrario, es NULL ), y me gustaría permitir que el usuario de la API REST filtre los recursos en función de si esta propiedad es nula o tiene un valor.
Debido a que la propiedad virtual no se conserva en la base de datos, asumo que ningún filtro de Doctrine, por ejemplo, ExistsFilter , funcionará en esta propiedad.
¿Cómo puedo crear funcionalidades de filtrado para propiedades virtuales usando Symfony 5 y la plataforma API?
Puede crear sus propios filtros ORM personalizados .
Un ejemplo extremadamente simple para mostrar cómo se haría:
Suponiendo una clase:
Foo { public int $weight; public function isHeavy(): bool { return $this->weight > 40; } } Dado que heavy es una propiedad "virtual", no puede filtrar por ella directamente.
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter; use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface; use Doctrine\ORM\QueryBuilder; class HeavyFilter extends AbstractContextAwareFilter { public function getDescription(string $resourceClass): array { // I'm making the filter available only if (Foo::class !== $resourceClass) { return []; } if (!$this->properties) { return []; } $description = []; $description['heavySearch'] = [ 'property' => 'heavy', 'type' => 'bool', 'required' => false, 'swagger' => [ 'description' => 'Search for heavy foos', 'name' => 'Heavey Search', 'type' => 'bool', ], ]; return $description; } protected function filterProperty( string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null ): void { if ('heavySearch' !== $property) { return; } if ($value === true) { $queryBuilder ->andWhere('o.weigth > 40'); } else { $queryBuilder ->andWhere('o.weight <= 40'); } } }Todavía no he probado esto, solo lo escribí sobre la marcha aquí, pero la idea base es correcta. Tendría que hacer ajustes a su propia situación y tendría un filtro personalizado que incluso está disponible en los documentos de Open Api.