You can create your own custom ORM filters.
An extremely simple example to show how would it be done:
Assuming a class:
Foo {
public int $weight;
public function isHeavy(): bool {
return $this->weight > 40;
}
}
Since heavy
is a "virtual" property, you couldn't filter by it directly.
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');
}
}
}
Haven't actually tested this yet, just wrote it on the fly here, but the base idea is correct. You'd need to make adjustments to your own situation, and you'd have a custom filter that's even available on the Open Api docs.