-
-
Notifications
You must be signed in to change notification settings - Fork 814
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
(WIP) 'Contains' operation for searching multi-select custom fields with the API. #6612
Conversation
---------------------------------------- * CRM-17101: civicrm_api3_basic_get does not work for SQL operators on custom fields. https://issues.civicrm.org/jira/browse/CRM-17101
---------------------------------------- * CRM-17101: civicrm_api3_basic_get does not work for SQL operators on custom fields. https://issues.civicrm.org/jira/browse/CRM-17101
This is what I would like to do. ---------------------------------------- * CRM-17096: A 'contains' operation for the api to search multiselect custom values. https://issues.civicrm.org/jira/browse/CRM-17096
---------------------------------------- * CRM-17096: A 'contains' operation for the api to search multiselect custom values. https://issues.civicrm.org/jira/browse/CRM-17096
One question I have about this is what happens if you try to use the CONTAINS operator on a non-multivalued field? |
It won't work. Just like when you use a = operator on a multivalued field, that won't work either. Maybe we should throw an exception in both cases.
When I am interested in entities that have some value selected in a multi-select custom field, I prefer to write
instead of
Besides, the consumer of the API should not have to care about how multi-select custom fields are implemented. IMO, you should be able to use the API without needing CRM_Core_DAO::VALUE_SEPARATOR. |
Absolutely agree. My suggestion was actually to make
work correctly using your code, which would imo make the api a bit more transparent, since you would be able to use the same verb on either single or multi-valued fields, and not have to care about how the api works internally. |
Agree that it's really good to hide |
The semantics of "LIKE=>FI" are different from "CONTAINS=>FI". You would expect that "LIKE=>FI" matches a record with value "FIDO", but "CONTAINS=>FI" should not match "FIDO". |
Using
can cause problems when one option value is a substring of another one. Which seems bad practice, I agree, but it is not impossible to define it like that. |
'sequential' => 1, | ||
)); | ||
|
||
// Clean up first, then assert. |
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 like this deals with the edge-case where the test fails -- you still need to cleanup even if there's a failure.
As a nitpick for future reference (not worth a special project on its own, but something for any readers to note for the future)... there's still a risk that other parts will fail (eg callApiSuccess() in L478 could throw an exception). This pattern should be a bit safer:
function testFoo() {
$this->custom['foo'] = $this->callApiSuccess('CustomField', 'Create', ...);
}
function tearDown() {
foreach (array_reverse($this->custom) as $field) {
$this->callApi('CustomField', 'Delete', ...);
}
}
The PR adds a feature -- and includes unit-tests! What bliss! |
Ok, not trying to hold up this excellent contribution, just think it through a bit. To clarify a minor misconception above, the api does not automatically append wildcards, so if you have a single-valued field
and it would only return fields with value "BE" (not BEE or BEER). Whereas if you entered
you'd get results with any of the three options. Well and good. Now for a multivalued field. Say
So I think this PR fits into that overall picture, adding the 3rd syntax. The others, afaik, are still missing. Note: I've backtracked on using "LIKE" and "CONTAINS" interchangeably because it doesn't carry exactly the same meaning. Thoughts? |
I like the idea of differentiating (a) exact matches (2+5) and (b) partial matches (3+4+6). For exact matches, Or, if we wanted nomenclature that's got more symmetry to it, maybe verbs |
The PR should also implement (4), but I did not test this yet. I did it this way, because usually when you combine filters in the API, they are combined with 'AND'. No matter what syntax we'll end up using, I think the cases @colemanw listed out are a good basis for the documentation of all this. p.s.: I always forget to add wildcards in my sql like-expressions as well ;-) |
As per the 6 cases listed by @colemanw we can resolve the same treating value(s) as pattern for RLIKE eventually, as we are already doing in case of n-nary operators https://github.com/civicrm/civicrm-core/blob/4.6/CRM/Core/BAO/CustomQuery.php#L404, and in this way it will satisfy all the 6 cases as follows :-
5. So as per the changes we don't need to use to wildcard '%' (as value may itself contain '%' though seems peculiar) but the api param should be formatted in way that it will receive '$wildcard = 1' as in https://github.com/civicrm/civicrm-core/blob/4.6/CRM/Core/BAO/CustomQuery.php#L339 |
I am not familiar with rlike, but suppose that custom_2 would have options
And what about
? |
@johanv I have updated case 4 |
@digitlimit would you be interested in reviewing this patch? |
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.
Looks like this PR needs additional work before merging.
@eileenmcnaughton Can we close this as it hasn't progressed from more than a year? Also, one can always re-open this when anyone feels to work on it. |
Yes - I agree - this might be part of apiv4 ....I'll make sure there IS a link on the JIRA so all this good discussion / work is still accessible |
I had to rebase this on my PR for CRM-17101 (#6611).
I implemented a 'contains' operator for searching values in multi-select custom fields.
I'm not sure whether this is a useful enhancement for the API, I'll leave that to you. It covers my use case, so I might as well upload it :-)
(Update: This PR is related to CRM-17096, which might be unclear because I mentioned another issue as well.)