Problem/Motivation
Views exposed filters allow multiple selections using the "Allow multiple selections" checkbox.
This can for example be tested using a filter on a node content type, which then allows filtering using multiple checkboxes for the different node types.
In the form this leads to an array structure like
type[] = article
type[] = page
using GET to submit the form, you can even make that visible.
The problem is that Views Exposed Filters expect the given parameter "type" to be an array (type[]
) and nothing else (e.g. type=
) and fails with an exception indirectly:
LogicException: Cannot create key "article" on non-array value. in Drupal\Component\Utility\NestedArray::setValue() (line 154 of core/lib/Drupal/Component/Utility/NestedArray.php).
LogicException: Cannot create key "article" on non-array value. in Drupal\Component\Utility\NestedArray::setValue() (line 154 of core/lib/Drupal/Component/Utility/NestedArray.php).
Drupal\Core\Form\FormBuilder->handleInputElement() (Line: 999)
Drupal\Core\Form\FormBuilder->doBuildForm() (Line: 1069)
Drupal\Core\Form\FormBuilder->doBuildForm() (Line: 1069)
Drupal\Core\Form\FormBuilder->doBuildForm() (Line: 579)
Drupal\Core\Form\FormBuilder->processForm() (Line: 326)
Drupal\Core\Form\FormBuilder->buildForm() (Line: 134)
Drupal\views\Plugin\views\exposed_form\ExposedFormPluginBase->renderExposedForm() (Line: 1297)
Drupal\views\ViewExecutable->build() (Line: 393)
Drupal\views\Plugin\views\display\PathPluginBase->execute() (Line: 198)
Drupal\views\Plugin\views\display\Page->execute() (Line: 1689)
Drupal\views\ViewExecutable->executeDisplay() (Line: 81)
Drupal\views\Element\View::preRenderViewElement()
call_user_func_array() (Line: 113)
Drupal\Core\Render\Renderer->doTrustedCallback() (Line: 870)
Drupal\Core\Render\Renderer->doCallback() (Line: 432)
Drupal\Core\Render\Renderer->doRender() (Line: 248)
Drupal\Core\Render\Renderer->render() (Line: 238)
Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 638)
Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 231)
Drupal\Core\Render\MainContent\HtmlRenderer->prepare() (Line: 128)
Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse() (Line: 90)
Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray()
call_user_func() (Line: 111)
Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 186)
Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 53)
Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 50)
Drupal\ban\BanMiddleware->handle() (Line: 48)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 36)
Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 49)
Drupal\remove_http_headers\StackMiddleware\RemoveHttpHeadersMiddleware->handle() (Line: 51)
Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 741)
Drupal\Core\DrupalKernel->handle() (Line: 19)
Such exceptions then fill up the logs and can be provoked from third party by URL.
The following URL would be the correct URL:
https://www.example.com/search?search=test&type[]=article
The following URL leads to the described exception:
https://www.example.com/search?search=test&type=article
Steps to reproduce
See above
Proposed resolution
Having a scalar value instead of the expected array should be handled more gracefully.
Ensure to validate the given value to be an array in form validation or other input validation, so it's not getting processed on lower levels running into lower level exceptions.
Also consider that when using a GET form, the parameter might also be changed / manipulated on the user-side. (intentionally or unintentionally)
We could also discuss if a scalar value is given, it should just be transformed into an array value to simplify handling, but I'm not sure if that's a good or a bad idea.
Remaining tasks
- Discuss
- Implement a fix
- Write test
- Review
- Release
User interface changes
None
API changes
None
Data model changes
None
Release notes snippet