protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
if (null === $value || !$this->isPropertyEnabled($property) || !$this->isPropertyMapped($property, $resourceClass, true)) {
return;
}
$alias = 'o';
$field = $property;
if ($this->isPropertyNested($property)) {
list($alias, $field, $associations) = $this->addJoinsForNestedProperty($property, $alias, $queryBuilder, $queryNameGenerator);
$metadata = $this->getNestedMetadata($resourceClass, $associations);
} else {
$metadata = $this->getClassMetadata($resourceClass);
}
$values = $this->normalizeValues((array) $value);
if (empty($values)) {
$this->logger->notice('Invalid filter ignored', ['exception' => new InvalidArgumentException(sprintf('At least one value is required, multiple values should be in "%1$s[]=firstvalue&%1$s[]=secondvalue" format', $property))]);
return;
}
$caseSensitive = true;
if ($metadata->hasField($field)) {
if ('id' === $field) {
$values = array_map([$this, 'getIdFromValue'], $values);
}
$strategy = $this->properties[$property] ?? self::STRATEGY_EXACT;
// prefixing the strategy with i makes it case insensitive
if (strpos($strategy, 'i') === 0) {
$strategy = substr($strategy, 1);
$caseSensitive = false;
}
if (1 === count($values)) {
$this->addWhereByStrategy($strategy, $queryBuilder, $queryNameGenerator, $alias, $field, $values[0], $caseSensitive);
return;
}
if (self::STRATEGY_EXACT !== $strategy) {
$this->logger->notice('Invalid filter ignored', ['exception' => new InvalidArgumentException(sprintf('"%s" strategy selected for "%s" property, but only "%s" strategy supports multiple values', $strategy, $property, self::STRATEGY_EXACT))]);
return;
}
$wrapCase = $this->createWrapCase($caseSensitive);
$valueParameter = $queryNameGenerator->generateParameterName($field);
$queryBuilder->andWhere(sprintf($wrapCase('%s.%s') . ' IN (:%s)', $alias, $field, $valueParameter))->setParameter($valueParameter, $caseSensitive ? $values : array_map('strtolower', $values));
}
// metadata doesn't have the field, nor an association on the field
if (!$metadata->hasAssociation($field)) {
return;
}
$values = array_map([$this, 'getIdFromValue'], $values);
$association = $field;
$valueParameter = $queryNameGenerator->generateParameterName($association);
$associationAlias = $this->addJoinOnce($queryBuilder, $queryNameGenerator, $alias, $association);
if (1 === count($values)) {
$queryBuilder->andWhere(sprintf('%s.id = :%s', $associationAlias, $valueParameter))->setParameter($valueParameter, $values[0]);
} else {
$queryBuilder->andWhere(sprintf('%s.id IN (:%s)', $associationAlias, $valueParameter))->setParameter($valueParameter, $values);
}
}