-
Notifications
You must be signed in to change notification settings - Fork 2
Page Auto Complete not working correctly with OR-groups in selector string #1374
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
Comments
I'm working around the problem using the suggestion here to hook As a general thing I don't understand why the selector string defined for the Page Reference field ever needs to pass through user input for PageAutocomplete fields. It seems to me that only the field and edited page need to be identified via the AJAX request and then PW can go to the field settings to securely get the selector string. This would avoid these kinds of issues. |
@ryancramerdesign - if you do dive into this, could you also please consider this (#550) at the same time ? |
PageAutocomplete uses ProcessPageSearch as its AJAX source/endpoint, and the URL-based API for that is not built to support the full scope of everything that you can do in selectors, and it likely never will — it would be too complex and difficult to keep secure. Instead, I'd like to rewrite PageAutocomplete to use its own AJAX source eventually, but that's basically a full rewrite of the module and likely not going to happen soon. Now there's a good alternative. If you have the need to use things like OR-groups in ajax search results (or literally anything else), the new InputfieldTextTags can do it for Page fields, as you have full control over the selector since it's your own code that ultimately performs the find(). |
@ryancramerdesign, what I'm proposing doesn't require massive changes - just relatively simple logic added to ProcessPageSearch to get the selector directly from the Field settings when it receives a request from a PageAutocomplete inputfield that is associated with a Field. As a demo I've done this using hooks as much as possible with only minimal changes to core code. Although if you were updating the core to accommodate this it would be even cleaner. The core changes needed to make the below hooks work:
var ajaxURL;
if($value.hasClass('has_field')) {
ajaxURL = url + '&term=' + term;
} else {
ajaxURL = url + '&' + searchField + operator + term;
} Hooks: $wire->addHookAfter('InputfieldPageAutocomplete::renderReadyHook', function(HookEvent $event) {
/** @var InputfieldPageAutocomplete $inputfield */
$inputfield = $event->object;
$field = $inputfield->hasField;
$page = $inputfield->hasPage;
// Add class to inputfield so JS can identify that is associated with a Field
if($field && $page) $inputfield->addClass('has_field');
});
$wire->addHookAfter('InputfieldPageAutocomplete::getAjaxUrl', function(HookEvent $event) {
/** @var InputfieldPageAutocomplete $inputfield */
$inputfield = $event->object;
$field = $inputfield->hasField;
$page = $inputfield->hasPage;
// AJAX URL only needs to convey the field, page and search term
// Selector and other field settings never pass through user input
if($field && $page) $event->return = $event->wire()->config->urls->admin . "page/search/for?autocomplete=1&field={$field->id}&page={$page->id}";
});
$wire->addHookAfter('ProcessPageSearch::findReady', function(HookEvent $event) {
$input = $event->wire()->input;
$field_id = (int) $input->get('field');
$page_id = (int) $input->get('page');
// If this is an PageAutocomplete request associated with a Field...
if($input->get('autocomplete') && $field_id && $page_id) {
// Get the Field (in context in case it matters) and Page objects
$field = $event->wire()->fields->get($field_id);
$page = $event->wire()->pages->get($page_id);
$field = $field->getContext($page);
// Get selector directly from Field settings
$selector = $field->findPagesSelector;
// Do any "page." replacements
$selector = InputfieldPage::getFindPagesSelector($page, $selector);
// Get search term sanitized for use in selector
$term = $input->get->selectorValue('term');
// Get search fields string and add to selector
$search_fields = $field->searchFields;
if(strpos($search_fields, ' ') !== false) {
$search_fields = implode('|', array_filter(explode(' ', $search_fields)));
}
$selector .= ", {$search_fields}{$field->operator}{$term}";
// Add limit if no custom limit defined
if(strpos($selector, 'limit=') === false) $selector .= ', limit=25';
$event->return = $selector;
}
}); It seems to me that this is more secure because the selector and other Field settings never need to pass through user input, and it's also quite a bit simpler than needing to send the Field settings on a roundtrip to the inputfield and back again via URL parameters (which requires some translation back and forth due to the limits of what can be passed in a URL). This would also solve issue #550 and avoid the need for workarounds like the ones discussed in issue #584 Things I haven't accounted for here but hopefully are not tricky:
|
@Toutouwai, there were some updates for InputfieldPageAutocomplete, getAjaxUrl() is hookable since 3.0.223, issue 550 is closed now, getFindPagesSelector is now populateFindPagesSelector, but stil not public. How all this does affect this issue? |
@matjazpotocnik @Toutouwai I think the OR groups actually may be supported now, as PageAutocomplete now does something very similar to what Toutouwai described above. |
@ryancramerdesign, I already tested, it's working here, but wanted confirmation from Robin, so that I don't miss something. |
Thanks, I tested and OR-groups are working for PageAutocomplete now. |
Short description of the issue
I have this page structure:
And this selector string for selectable pages:
(I know this specific selector doesn't need to use OR-groups but this is just for demo purposes)
This works fine if my inputfield type is "Select":
But if I change the inputfield type to "Page Auto Complete" it seems that the selector string is ignored and any page in the site becomes selectable.
Setup/Environment
The text was updated successfully, but these errors were encountered: