Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 8 additions & 14 deletions src/Doctrine/Odm/Filter/IriFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,17 @@ public function apply(Builder $aggregationBuilder, string $resourceClass, ?Opera
$method = $classMetadata->isSingleValuedAssociation($leafProperty) ? 'references' : 'includesReferenceTo';

if (is_iterable($value)) {
$value = \is_array($value) ? $value : iterator_to_array($value);

if ([] === $value) {
$match->{$operator}($aggregationBuilder->matchExpr()->field($matchField)->in([]));

return;
}

$or = $aggregationBuilder->matchExpr();

foreach ($value as $v) {
if (!\is_object($v)) {
continue;
}

$or->addOr($aggregationBuilder->matchExpr()->field($matchField)->{$method}($v));
}

Expand All @@ -107,16 +111,6 @@ public function apply(Builder $aggregationBuilder, string $resourceClass, ?Opera
return;
}

// The IRI did not resolve to a resource: emit an always-false clause so the query
// returns no result rather than attempting to match against a raw IRI string.
if (!\is_object($value)) {
$match->{$operator}(
$aggregationBuilder->matchExpr()->field($matchField)->in([])
);

return;
}

$match
->{$operator}(
$aggregationBuilder
Expand Down
54 changes: 17 additions & 37 deletions src/State/ParameterProvider/IriConverterParameterProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public function __construct(
public function provide(Parameter $parameter, array $parameters = [], array $context = []): ?Operation
{
$operation = $context['operation'] ?? null;
if (!($value = $parameter->getValue()) || $value instanceof ParameterNotFound) {
$value = $parameter->getValue();
if (null === $value || $value instanceof ParameterNotFound) {
return $operation;
}

Expand All @@ -46,47 +47,26 @@ public function provide(Parameter $parameter, array $parameters = [], array $con
'map_resource' => $extraProperties['map_resource'] ?? (null === $parameter->getFilter()),
];

if (\is_array($value)) {
$entities = [];
foreach ($value as $v) {
try {
$entities[] = $this->iriConverter->getResourceFromIri($v, $iriConverterContext);
} catch (InvalidArgumentException|ItemNotFoundException $exception) {
if ($exception instanceof ItemNotFoundException && true === ($extraProperties['throw_not_found'] ?? false)) {
throw $exception;
}

$this->logger->error(
message: 'Operation failed due to an invalid argument or a missing item',
context: [
'exception' => $exception->getMessage(),
]
);

break;
$resources = [];
foreach (\is_array($value) ? $value : [$value] as $iri) {
try {
$resources[] = $this->iriConverter->getResourceFromIri((string) $iri, $iriConverterContext);
} catch (InvalidArgumentException $exception) {
if ($exception instanceof ItemNotFoundException && true === ($extraProperties['throw_not_found'] ?? false)) {
throw $exception;
}
}

$parameter->setValue($entities);

return $operation;
}

try {
$parameter->setValue($this->iriConverter->getResourceFromIri($value, $iriConverterContext));
} catch (InvalidArgumentException|ItemNotFoundException $exception) {
if ($exception instanceof ItemNotFoundException && true === ($extraProperties['throw_not_found'] ?? false)) {
throw $exception;
$this->logger->notice(
message: 'Unable to resolve an IRI parameter value',
context: [
'exception' => $exception->getMessage(),
]
);
}

$this->logger->error(
message: 'Operation failed due to an invalid argument or a missing item',
context: [
'exception' => $exception->getMessage(),
]
);
}

$parameter->setValue(\is_array($value) || [] === $resources ? $resources : $resources[0]);

return $operation;
}
}
7 changes: 7 additions & 0 deletions tests/Functional/Parameters/IriFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ public function testIriFilter(): void
$this->assertCount(0, $res['member']);
}

public function testIriFilterWithUnresolvableIri(): void
{
$res = self::createClient()->request('GET', '/chickens?chickenCoop=/invalid/iri')->toArray(false);
$this->assertResponseIsSuccessful();
$this->assertCount(0, $res['member']);
}

public function testIriFilterMultiple(): void
{
$iris = $this->getIris();
Expand Down
Loading