diff --git a/app/src/Lib/Match/MatchService.php b/app/src/Lib/Match/MatchService.php index cf33fb5eb..3c4d59184 100644 --- a/app/src/Lib/Match/MatchService.php +++ b/app/src/Lib/Match/MatchService.php @@ -972,7 +972,59 @@ public function searchReferenceId(string $sor, string $sorid, AttributeManager $ // We use a psuedo-rule name $potentialMatches->add($downgraded['attrs'], $downgraded['rule']); } - + + // Check for any potential matches which should be dropped due to Invalidate mode + if ($potentialMatches->count() > 0) { + $results = $potentialMatches->getRawResults(); + + // Check if any Attribute Rules in "Invalidate" mode will demote this result. + foreach($results as $rowId => $attrs) { + // Find the rule that generated this match. + $rulename = $potentialMatches->getRuleForResult($rowId); + + foreach($this->mgConfig->potential_rules as $rule) { + if($rule->name == $rulename) { + // This is the correct rule, check the Rule Attributes. Note there could + // be more than one Rule Attribute with Search Type "Invalidate". + + foreach($rule->rule_attributes as $ruleAttribute) { + if($ruleAttribute->search_type == SearchTypeEnum::Invalidate) { + // The name of the attribute for this Rule Attribute, eg "dob". + // This is the column name, not the API name. + $ruleAttributeName = $ruleAttribute->attribute->name; + + // The value in the search request + $searchValue = $attributes->getValueByAttribute($ruleAttribute->attribute); + // The value in the matched row + $rowValue = $results[$rowId][$ruleAttributeName]; + + // We only perform the validation check if both values are not empty. + if(!empty($searchValue) + && !empty($rowValue) + && ($searchValue !== $rowValue)) { + // The returned value does not match, invalidate the request and drop to no match + // by removing the result from the potential match results + Log::write('debug', $sor . "/" . $sorid . " Invalidate mode for $ruleAttributeName ($rulename) removing result ". $rowId . "\t" . $results[$rowId]['sorid']); + + // remove the result from potentialMatches ResultManager object + $found = $potentialMatches->remove($rowId); + if (!$found) { + Log::write('warning', $sor . "/" . $sorid . " Invalidate mode - error occurred removing result from potential match result set ". $rowId . "\t" . $results[$rowId]['sorid']); + } + + // No need to continue with any loop + break 2; + } + } + } + + // We found the rule we're looking for, no need to continue with the loop + break; + } + } + } + } + // The calling code generally checks to see if any rules successfully ran, // since if there were no valid attributes or rules we treat that as an error. // If no potential rules ran, we return the canonicalMatches result instead. diff --git a/app/src/Lib/Match/ResultManager.php b/app/src/Lib/Match/ResultManager.php index 313e15ccf..f0467f8f7 100644 --- a/app/src/Lib/Match/ResultManager.php +++ b/app/src/Lib/Match/ResultManager.php @@ -106,6 +106,44 @@ public function add(array $attributes, string $rule=null) { $this->rawResults[$rowId] = $attributes; } + + /** + * Remove a Matchgrid result. + * + * @since COmanage Match v1.3.0 + * @param int $rowId Row ID to remove + * @return bool True if deleted, false if not found + */ + public function remove(int $rowId): bool { + $found = false; + + // Remove from $this->results + foreach ($this->results as $referenceId => $sorRow) { + if (isset($sorRow[$rowId])) { + unset($this->results[$referenceId][$rowId]); + // If no more results for this referenceId, remove the referenceId key + if (empty($this->results[$referenceId])) { + unset($this->results[$referenceId]); + } + $found = true; + break; // Assuming rowId is unique across referenceIds within $this->results structure + } + } + + // Remove from $this->resultRules + if (isset($this->resultRules[$rowId])) { + unset($this->resultRules[$rowId]); + $found = true; // Mark as found even if only found here (though it should be in results too) + } + + // Remove from $this->rawResults + if (isset($this->rawResults[$rowId])) { + unset($this->rawResults[$rowId]); + $found = true; // Mark as found even if only found here + } + + return $found; + } /** * Obtain the number of results.