Skip to content
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

Filter on multiple string values containing commas #229

Closed
AlexanderLindkjaer opened this issue Apr 4, 2019 · 6 comments
Closed

Filter on multiple string values containing commas #229

AlexanderLindkjaer opened this issue Apr 4, 2019 · 6 comments
Labels
enhancement New feature or request

Comments

@AlexanderLindkjaer
Copy link

I have a big database with cars where I want to be able to do exact filtering on multiple model names. I do not have control over the formatting of these names. Some model names contains commas:
"911 RS 2, 2.7 lightweight", "911R", "550 Spyder"

Filtering on the multiple modal names by comma separation works as expected.
https://car-api/cars?filter[model]=911R%2C550%20Spyder -> "911R","550 Spyder"

Except for when the name contains a comma
https://car-api/cars?filter[model]=911%20RS%202%2C%202.7%20lightweight
-> "911 RS 2, 2.7 lightweight"
It searches for two separate values.
select * from cars where model in (?, ?) and....

I know this is expected behavior, and it works as intended.

I tried escaping the non-value-separating commas with \, / %5C%2C

I tried following #139 but don’t want to lose the ability to do filtering on multiple variables. Is there a way to have individual variable containing commas, and still be filterable?

@AlexVanderbist
Copy link
Member

Interesting problem! I think the nicest solution would probably be to allow a different delimiter to be configured. In that case you could do something like this:

// in an app service provider
QueryBuilderRequest::setArrayDelimiter('|');

// GET /cars?filter[model]=911 RS 2, 2.7 lightweight|911R|550 Spyder

Alternatively we could make the delimiter configurable per filter - but that might overcomplicate things...

What do you think?

@AlexVanderbist AlexVanderbist added question Questions on how to use the package enhancement New feature or request and removed question Questions on how to use the package labels Apr 16, 2019
@aphofstede
Copy link

aphofstede commented Sep 26, 2019

An alternative approach is exploding the filter values (QueryBuilderRequest.php:96) in a way that ignores the common case where a spatie comes after the comma in most natural usage. Would that help?

Example from an older project that had similar issues:

/**
 * @param string $comma_separated_string e.g. "a,b, c"
 * @return array The values between the comma's in the given string, ignoring any white space between values/separators
 */
function explode_ignoring_whitespace(string $comma_separated_string): array
{
	// Cheeky way to explode only "a" and "b, c" from "a,b, c"
	return preg_split('/,(?=\S)/', $comma_separated_string, null, PREG_SPLIT_NO_EMPTY);
}

// Test
var_dump(explode_ignoring_whitespace("a,b,c")); // array(3) { [0]=> string(1) "a" [1]=> string(1) "b" [2]=> string(1) "c" }
var_dump(explode_ignoring_whitespace("a,b, c")); // array(2) { [0]=> string(1) "a" [1]=> string(4) "b, c" }
var_dump(explode_ignoring_whitespace("911 RS 2, 2.7 lightweight,911R,550 Spyder")); // array(3) { [0]=> string(25) "911 RS 2, 2.7 lightweight" [1]=> string(4) "911R" [2]=> string(10) "550 Spyder" }

@AlexVanderbist
Copy link
Member

@aphofstede thanks for the proposal but I feel like that might be too much "magic" for the default behaviour. If you need this specific exploding behaviour I think it's more appropriate to keep the filter value as a string and parse it down in a custom filter class.

@dominikb
Copy link
Contributor

Would a feature PR be welcome that introduces the possibility to use custom delimiters for multiple values?

This was referenced Oct 29, 2019
@AlexVanderbist
Copy link
Member

PR looks solid as usual, thanks a lot! Gonna close this and merge the PR soon.

@btxtiger
Copy link
Contributor

btxtiger commented Jan 6, 2020

It seems the custom array delimiter is also set for includes, is this the wanted behaviour?
This makes the handling really complicated as I just wanted to be able to find this string in my database EL63PB1024Z8/24PB15X3PR0,3.482+999.

It might be easier to pass a custom delimiter to AllowedFilter::exact as parameter to be more flexible:

AllowedFilter::exact('id', 'ref_id', true, '|'),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants