Jump to content

[Solved] Selectors As Arrays - Help with OR-groups


ethanbeyer
 Share

Recommended Posts

I'm trying to build a Search Template. The way I had been doing it was by constructing a Selector one string at a time in an array, and then imploding that array with ", " in order to create a Selector that was passed to $pages->find($selectorStr). This is a bare-bones example of what I was doing:

$search = $sanitizer->selectorValue($input->get('s'));

$selector[] = 'template=member';
$selector[] = "field1|field2|field3%={$search}";
$selector[] = "(repeaterField.fieldX|repeaterField.fieldZ%={$search})";

$selectorStr = implode($selector, ", ");

$results = $pages->find($selectorStr);

This worked as expected, and I was able to utilize OR-groups within the Selector. There is a problem, though: for whatever reason, despite sanitizing the incoming value, if the user input a string like "test,foo", ProcessWire threw this error:

Exception: Unknown Selector operator: '' -- was your selector value properly escaped? field='foo', value='', selector: 'include=all, children.count>0, title%=test,foo' (in /var/www/public/wire/core/Selectors.php line 378)

 

 

So I moved on to Selector Arrays, and now I'm having trouble with OR-groups. I found out about Selector Arrays (not documented at all as far as I can see in the API Reference) through a ProcessWire blog post about 3.0.13.

Here's the code (using the actual field names, unlike above):

$selectorArray = [];
// template
$selectorArray[] = ['template', 'directory-member'];
// basic fields
$selectorArray[] = [
    'field' => [
        'dm_firstName',
        'dm_middleName',
        'dm_lastName',
        'email',
        'dm_ficmTitle',
        'dm_addressStreet',
        'dm_addressCity',
        'dm_addressState',
        'dm_addressPostalCode',
        'dm_birthday',
        'dm_phone1',
        'dm_phone2'
    ],
    'operator' => '%=',
    'value' => $searchStr
];
//repeaters
$selectorArray[] = [
    'field' => [
        'dm_contactREP.dm_contactMethod',
        'dm_contactREP.dm_contactValue'
    ],
    'operator' => '%=',
    'value' => $searchStr,
    'group' => 'repeaters'
];
// search the parent's name
$selectorArray[] = [
    'group' => 'parentTitle',
    'field' => 'parent.title',
    'operator' => '%=',
    'value' => $searchStr,
];
// sort
$selectorArray[] = ['sort', 'dm_lastName'];
$selectorArray[] = ['sort', 'dm_firstName'];

The problem is that the Selector is rendered like this (clauses broken into Newlines):

template=directory-member,
dm_firstName|dm_middleName|dm_lastName|email|dm_ficmTitle|dm_addressStreet|dm_addressCity|dm_addressState|dm_addressPostalCode|dm_birthday|dm_phone1|dm_phone2%=test,
repeaters@dm_contactREP.dm_contactMethod|dm_contactREP.dm_contactValue%=(test),
parentTitle@parent.title%=(test),
sort=dm_lastName, 
sort=dm_firstName,
status<1024

 

For OR-groups, the whole clause should be wrapped in parentheses - not just the value I'm searching for!

So, two questions:

Why would a comma in the search value break things that are supposed to be sanitized, and two, how do I get the OR-groups to work as intended?

Link to comment
Share on other sites

16 hours ago, ethanbeyer said:

There is a problem, though: for whatever reason, despite sanitizing the incoming value, if the user input a string like "test,foo", ProcessWire threw this error:

Exception: Unknown Selector operator: '' -- was your selector value properly escaped? field='foo', value='', selector: 'include=all, children.count>0, title%=test,foo' (in /var/www/public/wire/core/Selectors.php line 378)

Put quote marks around your search string so PW can distinguish between the selector string and the search string, e.g.

$selector[] = "(repeaterField.fieldX|repeaterField.fieldZ%='{$search}')";

 

16 hours ago, ethanbeyer said:

So I moved on to Selector Arrays, and now I'm having trouble with OR-groups.

That is a more advanced usage than what is covered in the blog post. You'll need to use the "verbose" version of a selector array. Ryan gives an example of a verbose selector array this in this GitHub comment. And for more details and the specifics of OR-groups in a selector array see the comments in Selectors.php here and here.

TBH you might find it easier to stick with selector strings for such things until we have proper documentation for selector arrays. 

  • Like 2
Link to comment
Share on other sites

5 hours ago, Robin S said:

Put quote marks around your search string so PW can distinguish between the selector string and the search string, e.g.


$selector[] = "(repeaterField.fieldX|repeaterField.fieldZ%='{$search}')";

Well, I feel a bit silly. I didn't think that needed to be done because of the call to $sanitizer->selectorValue($input->get('s')); .

Anyhow, you solved my problem - and I think you're right: String Selectors are probably an easier method to go with than Array Selectors until they've been documented better.

  • Like 1
Link to comment
Share on other sites

  • ethanbeyer changed the title to [Solved] Selectors As Arrays - Help with OR-groups

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...