-
-
Notifications
You must be signed in to change notification settings - Fork 824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
dev/core#1659: Fix Case.get API returning Case Clients As Part of Related Contacts #16837
dev/core#1659: Fix Case.get API returning Case Clients As Part of Related Contacts #16837
Conversation
(Standard links)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This fix looks like it's headed in the right direction, but also needs a unit test.
CRM/Case/BAO/Case.php
Outdated
$params = [ | ||
1 => [$caseID, 'Integer'], | ||
2 => [implode(',', $caseInfo['client_id']), 'String'], | ||
2 => [implode(',', $caseInfo['client_id']), $clientIdType], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks to me like you're also trying to handle the scenario where $caseInfo['client_id']
is an empty string. But in that case it would get injected into a sql query like AND cc.id NOT IN ("")
which is bad if not invalid SQL. Is that a real possibility? In that case we'd need to handle it better, probably by altering the query to omit that clause.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@colemanw , It is a possibility, when I changed the param type to CommaSeparatedIntegers
directly, I got an error emanating from the civirules module. I described the error under the Proposed solution in the section here: https://lab.civicrm.org/dev/core/issues/1659, so the issue had always been there and the query will run apparently when $caseInfo['client_id']
is an empty string but it's bad SQL.
I can update the PR to check for this and exclude the condition from the SQL and also add a test. Can you point me to a test similar to what I need to add for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fortunately, that clause is literally the last line in the query. So you could delete that line from the query, and also delete key 2
from the $params
array, then do a conditional afterwards:
if (!empty($caseInfo['client_id'])) {
$query .= <<<HERESQL
AND cc.id NOT IN (%2)
HERESQL;
$params[2] = [implode(',', $caseInfo['client_id']), 'CommaSeparatedIntegers'];
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@colemanw
The clause is actually in two places in the Query. Here #16837 and #16837.
Was thinking of fixing like this:
$caseClientCondition = !empty($caseInfo['client_id']) ? "AND cc.id NOT IN (%2)" : '';
$query = <<<HERESQL
SELECT cc.display_name as name, cc.sort_name as sort_name, cc.id, cr.relationship_type_id, crt.label_b_a as role, crt.name_b_a as role_name, ce.email, cp.phone
FROM civicrm_relationship cr
JOIN civicrm_relationship_type crt
ON crt.id = cr.relationship_type_id
JOIN civicrm_contact cc
ON cc.id = cr.contact_id_a
AND cc.is_deleted <> 1
LEFT JOIN civicrm_email ce
ON ce.contact_id = cc.id
AND ce.is_primary= 1
LEFT JOIN civicrm_phone cp
ON cp.contact_id = cc.id
AND cp.is_primary= 1
WHERE cr.case_id = %1
AND cr.is_active
{$caseClientCondition}
UNION
SELECT cc.display_name as name, cc.sort_name as sort_name, cc.id, cr.relationship_type_id, crt.label_a_b as role, crt.name_a_b as role_name, ce.email, cp.phone
FROM civicrm_relationship cr
JOIN civicrm_relationship_type crt
ON crt.id = cr.relationship_type_id
JOIN civicrm_contact cc
ON cc.id = cr.contact_id_b
AND cc.is_deleted <> 1
LEFT JOIN civicrm_email ce
ON ce.contact_id = cc.id
AND ce.is_primary= 1
LEFT JOIN civicrm_phone cp
ON cp.contact_id = cc.id
AND cp.is_primary= 1
WHERE cr.case_id = %1
AND cr.is_active
{$caseClientCondition}
HERESQL;
if ($caseClientCondition) {
$params[2] = array(implode(',', $caseInfo['client_id']), 'CommaSeparatedIntegers');
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense
Unit tests for the Case api are here: https://github.com/civicrm/civicrm-core/blob/master/tests/phpunit/api/v3/CaseTest.php#L779 - that's the only one that mentions multi-client cases. |
@colemanw , Can you check this again? Thanks |
@colemanw Bump. |
Looks good. There's some comments about the added test but doesn't affect the patch itself.
|
Agree the test isn't ideal, but the other tests in that class are bad patterns so the problem isn't originating here. |
…d Contacts Included in CiviCRM 5.26 PR: civicrm#16837
…d Contacts Included in CiviCRM 5.26 PR: civicrm#16837
Overview
The Case.get API returns case clients as part of related contacts. The case clients are not supposed to be returned as part of the related contacts.
Before
After
The Case.get API no longer returns case clients as part of related contacts. They are excluded.
The condition here: https://github.com/civicrm/civicrm-core/blob/master/CRM/Case/BAO/Case.php#L1160 is meant to exclude case clients but when the clients are more than one for a case, the parameter here is treated as a String rather than
CommaSeparatedIntegers
, so the SQL end up having conditions likeNOT IN ('2,3')
rather thanNOT IN (2,3)
.The fix was to treat the Case clients as
CommaSeparatedIntegers