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

Adding more fuzzy matching #15

Open
sgtwinters opened this issue Jan 10, 2018 · 3 comments
Open

Adding more fuzzy matching #15

sgtwinters opened this issue Jan 10, 2018 · 3 comments

Comments

@sgtwinters
Copy link
Contributor

Well, another one @johannesschobel :)

When working with the custom filters you now have the possibility to filter on strings 'starting with' using the String* filter. I have a lot of cases where I need a bit more fuzzy matching, for example matching a part of a string: 'A beautiful song I wrote'.

I would suggest expanding the createEvaluationRule method, listening for *String*, to fit this purpose?

private function createEvaluationRule($key, $operator, $value)
    {
        // first, check the operator type!
        if ($operator == '=') {
            $operator = '==';
        }

        // escaping
        $key = addslashes($key);

        $rule = "'%s' %s '%s'"; // key, operator, value
        $rule = sprintf($rule, $key, $operator, $value);

        // now check if the operator was "(not) like"?
        if (strpos($operator, 'like') !== false) {

            // check for %value% to perform a more fuzzy match
            if (preg_match('/%(.*).{1,}?%/', $value)) {

                $value = str_replace('%', '', $value);
                $rule = "%sis_int(stripos('%s', '%s')) ? true : false";

                $expectedResult = '';

                if (stripos($operator, 'not') !== false) {
                    // it is a NOT LIKE operator
                    $expectedResult = '!';
                }

                $rule = sprintf($rule, $expectedResult, $key, $value);

            } else {
                $value = str_replace('%', '', $value);    
                $rule = "substr('%s', 0, strlen('%s')) %s '%s'"; // haystack, $needle, $comparable, $needle

                $expectedResult = '===';

                if (stripos($operator, 'not') !== false) {
                    // it is a NOT LIKE operator
                    $expectedResult = '!==';
                }

                $rule = sprintf($rule, $key, $value, $expectedResult, $value);
            }  
        }

        return $rule;
    }

If you like the idea I can send in another PR?

@johannesschobel
Copy link
Owner

Hey man.. thank you very much for your additional input on this package ;)
I remember, that i implemented some kind of like filter back then.. It works like this:
/users?name=john*..

However, i am not sure if it works in "both" ways, like this /users?name=*oh*

@sgtwinters
Copy link
Contributor Author

Hey @johannesschobel. Yes you did build the like filtering indeed, it works for 'a string starting with'. My code suggestion posted above adds a filtering rule (matching *string*) so that makes it work both ways :). Would like to review my suggestion (I can PR if you want)?

Thanks again!

@johannesschobel
Copy link
Owner

Hey man.. haha, maybe i was just to lazy to implement it on my own back then.. ^^
sure, submti a PR, so we can discuss the changes.. That would be great! Thank you very much!

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

No branches or pull requests

2 participants