Skip to content

Implement Invalidate search type for Potential Match rules (CO-2690) #70

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
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
54 changes: 53 additions & 1 deletion app/src/Lib/Match/MatchService.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
38 changes: 38 additions & 0 deletions app/src/Lib/Match/ResultManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down