Skip to content

Commit

Permalink
Merge pull request #5266 from neos/5265-nullHandlingInSearchTermMatcher
Browse files Browse the repository at this point in the history
BUGFIX: 5265 - Ignore null values in SearchTermMatcher
  • Loading branch information
nezaniel authored Sep 26, 2024
2 parents 918e651 + bfa5c95 commit 333c4dd
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Neos\ContentRepository\Core\Feature\NodeModification\Dto\SerializedPropertyValues;
use Neos\ContentRepository\Core\Projection\ContentGraph\Node;
use Neos\ContentRepository\Core\SharedModel\Node\NodeAggregateId;

/**
* Performs search term check against the nodes properties
Expand All @@ -16,41 +17,47 @@ class SearchTermMatcher
{
public static function matchesNode(Node $node, SearchTerm $searchTerm): bool
{
return static::matchesSerializedPropertyValues($node->properties->serialized(), $searchTerm);
return static::matchesSerializedPropertyValues($node->properties->serialized(), $searchTerm, $node->aggregateId);
}

public static function matchesSerializedPropertyValues(SerializedPropertyValues $serializedPropertyValues, SearchTerm $searchTerm): bool
public static function matchesSerializedPropertyValues(SerializedPropertyValues $serializedPropertyValues, SearchTerm $searchTerm, ?NodeAggregateId $nodeAggregateId = null): bool
{
if ($searchTerm->term === '') {
return true;
}
foreach ($serializedPropertyValues as $serializedPropertyValue) {
if (self::matchesValue($serializedPropertyValue->value, $searchTerm)) {
foreach ($serializedPropertyValues as $propertyName => $serializedPropertyValue) {
if (self::matchesValue($serializedPropertyValue->value, $searchTerm, $propertyName, $nodeAggregateId)) {
return true;
}
}
return false;
}

private static function matchesValue(mixed $value, SearchTerm $searchTerm): bool
private static function matchesValue(mixed $value, SearchTerm $searchTerm, string $propertyName, ?NodeAggregateId $nodeAggregateId): bool
{
if (is_array($value) || $value instanceof \ArrayObject) {
foreach ($value as $subValue) {
if (self::matchesValue($subValue, $searchTerm)) {
if (self::matchesValue($subValue, $searchTerm, $propertyName, $nodeAggregateId)) {
return true;
}
}
return false;
}

return match (true) {
$value === null => false,
is_string($value) => mb_stripos($value, $searchTerm->term) !== false,
// the following behaviour might seem odd, but is implemented after how the doctrine adapter filtering is currently implemented
is_int($value),
is_float($value) => str_contains((string)$value, $searchTerm->term),
$value === true => str_contains('true', $searchTerm->term),
$value === false => str_contains('false', $searchTerm->term),
default => throw new \InvalidArgumentException(sprintf('Handling for type %s is not implemented.', get_debug_type($value))),
default => throw new \InvalidArgumentException(sprintf(
'Handling for type %s within property "%s" of node "%s" is not implemented.',
get_debug_type($value),
$propertyName,
$nodeAggregateId?->value ?: 'unknown'
)),
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ public function notMatchingExamples(): iterable
yield 'array with unmatched string' => ['hello', self::value(['hi'])];
yield 'array key is not considered matching' => ['key', self::value(['key' => 'foo'])];
yield 'nested array key is not considered matching' => ['key', self::value([['key' => 'foo']])];
yield 'array with null value' => ['foo', self::value([null])];
}

/**
Expand Down

0 comments on commit 333c4dd

Please sign in to comment.