From c32d812ce5d39e7065bb7f063fe45391e5f11e65 Mon Sep 17 00:00:00 2001 From: Sebastian Krupinski Date: Sun, 21 Jun 2026 12:24:17 -0400 Subject: [PATCH] feat: implement wild card search Signed-off-by: Sebastian Krupinski --- lib/Store/Personal/Store.php | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/lib/Store/Personal/Store.php b/lib/Store/Personal/Store.php index 0afcb22..76a6ce6 100644 --- a/lib/Store/Personal/Store.php +++ b/lib/Store/Personal/Store.php @@ -47,6 +47,20 @@ class Store { 'tags' => 'data.tags', ]; + /** + * Document paths searched by the wildcard "*" (search-all) entity filter + * attribute (CAPABILITY_ENTITY_FILTER_ALL). + * + * Name fields only for now: emails and organizations are stored as keyed + * objects, which a plain find() cannot regex-match without an aggregation + * expression — deferred to a later pass. + */ + protected array $_EntityFilterWildcardFields = [ + 'data.names.given', + 'data.names.family', + 'data.label', + ]; + public function __construct( protected readonly DataStore $_store ) { } @@ -55,10 +69,26 @@ class Store { $mongoFilter = []; foreach ($filter->conditions() as $entry) { + // Wildcard "*" search-all: expand a LIKE/NLIKE into an $or regex + // across the human-searchable name fields. Only meaningful for + // entity queries; collection filters never carry the "*" attribute. + if ($entry['attribute'] === '*' && $map === $this->_EntityFilterAttributeMap) { + $value = $entry['value']; + $comparator = $entry['comparator'] ?? FilterComparisonOperator::LIKE; + $condition = match ($comparator) { + FilterComparisonOperator::NLIKE => ['$not' => ['$regex' => $value, '$options' => 'i']], + default => ['$regex' => $value, '$options' => 'i'], + }; + foreach ($this->_EntityFilterWildcardFields as $field) { + $mongoFilter['$or'][] = [$field => $condition]; + } + continue; + } + if (!isset($map[$entry['attribute']])) { continue; } - + $attribute = $map[$entry['attribute']]; $value = $entry['value']; $comparator = $entry['comparator'] ?? FilterComparisonOperator::EQ;