Browse Source

Allow page view derived Advanced Search blocks on any page (#843)

* Allow page view derived Advanced Search blocks on any page

Allows the Advanced Search block to be used on pages
where its corresponding view is not present. Now it
will redirect to the route associated with the view
it was generated from.

This is not valid for Advanced Search blocks that
are derived from non-page based views, as there is
no known location in which to redirect the query.

* Fix for undefined index warning.

* Documented Exposed form style settings requirement for Advanced Search.
pull/846/head
Nigel Banks 3 years ago committed by GitHub
parent
commit
0c0dd67334
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      modules/islandora_advanced_search/README.md
  2. BIN
      modules/islandora_advanced_search/docs/basic-input.png
  3. 9
      modules/islandora_advanced_search/js/islandora_advanced_search.form.js
  4. 15
      modules/islandora_advanced_search/src/AdvancedSearchQuery.php
  5. 51
      modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php
  6. 2
      modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php

21
modules/islandora_advanced_search/README.md

@ -7,6 +7,7 @@
- [Configuring Solr](#configuring-solr) - [Configuring Solr](#configuring-solr)
- [Configure Collection Search](#configure-collection-search) - [Configure Collection Search](#configure-collection-search)
- [Configure Views](#configure-views) - [Configure Views](#configure-views)
- [Exposed Form](#exposed-form)
- [Collection Search](#collection-search) - [Collection Search](#collection-search)
- [Paging](#paging) - [Paging](#paging)
- [Sorting](#sorting) - [Sorting](#sorting)
@ -96,6 +97,21 @@ the [Drupal Documentation](https://www.drupal.org/docs/8/core/modules/views), as
well as the well as the
[Search API Documentation](https://www.drupal.org/docs/contributed-modules/search-api). [Search API Documentation](https://www.drupal.org/docs/contributed-modules/search-api).
### Exposed Form
Solr views allow the user to configure an exposed form (_optionally as a
block_). This form / block is **different** from the
[Advanced Search Block](#advanced-search-block). This module does not make any
changes to the form, but this form can cause the Advanced Search Block to not
function if configured incorrectly.
The Advanced Search Block requires that if present the Exposed forms
`Exposed form style` is set to `Basic` rather than `Input Required`. As
`Input Required` will prevent any search from occurring unless the user puts an
additional query in the Exposed form as well.
![Form Style](./docs/basic-input.png)
### Collection Search ### Collection Search
That being said it will be typical that you require the following That being said it will be typical that you require the following
@ -194,6 +210,11 @@ checkbox.
![image](./docs/advanced_search_block_settings.png) ![image](./docs/advanced_search_block_settings.png)
> N.B. Be aware that the Search views [Exposed Form](#exposed-form) can have an
> affect on the function of the
> [Advanced Search Block](#advanced-search-block). Please refer to that section
> to learn more.
## Documentation ## Documentation
Further documentation for this module is available on the Further documentation for this module is available on the

BIN
modules/islandora_advanced_search/docs/basic-input.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

9
modules/islandora_advanced_search/js/islandora_advanced_search.form.js

@ -7,7 +7,8 @@
// Gets current parameters minus ones provided by the form. // Gets current parameters minus ones provided by the form.
function getParams(query_parameter, recurse_parameter) { function getParams(query_parameter, recurse_parameter) {
var params = Drupal.Views.parseQueryString(window.location.href); const url_search_params = new URLSearchParams(window.location.search);
const params = Object.fromEntries(url_search_params.entries());
// Remove Advanced Search Query Parameters. // Remove Advanced Search Query Parameters.
const param_match = "query\\[\\d+\\]\\[.+\\]".replace("query", query_parameter); const param_match = "query\\[\\d+\\]\\[.+\\]".replace("query", query_parameter);
const param_regex = new RegExp(param_match, "g"); const param_regex = new RegExp(param_match, "g");
@ -97,6 +98,11 @@
// //
// Logic server side / client side should match to generate the // Logic server side / client side should match to generate the
// appropriate URL with javascript enabled or disable. // appropriate URL with javascript enabled or disable.
//
// If a route is set for the view display that this form is derived
// from, and we are not on the same page as that route, rely on the
// normal submit which will redirect to the appropriate page.
if (!settings.islandora_advanced_search_form.redirect) {
$form.submit(function (e) { $form.submit(function (e) {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
@ -104,6 +110,7 @@
const href = url(inputs, settings.islandora_advanced_search_form); const href = url(inputs, settings.islandora_advanced_search_form);
window.history.pushState(null, document.title, href); window.history.pushState(null, document.title, href);
}); });
}
// Reset should trigger refresh of AJAX Blocks / Views. // Reset should trigger refresh of AJAX Blocks / Views.
$form.find('input[data-drupal-selector = "edit-reset"]').mousedown(function (e) { $form.find('input[data-drupal-selector = "edit-reset"]').mousedown(function (e) {
const inputs = []; const inputs = [];

15
modules/islandora_advanced_search/src/AdvancedSearchQuery.php

@ -3,6 +3,8 @@
namespace Drupal\islandora_advanced_search; namespace Drupal\islandora_advanced_search;
use Drupal\block\Entity\Block; use Drupal\block\Entity\Block;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Url; use Drupal\Core\Url;
use Drupal\islandora_advanced_search\Form\SettingsForm; use Drupal\islandora_advanced_search\Form\SettingsForm;
use Drupal\islandora_advanced_search\Plugin\Block\AdvancedSearchBlock; use Drupal\islandora_advanced_search\Plugin\Block\AdvancedSearchBlock;
@ -223,9 +225,18 @@ class AdvancedSearchQuery {
* @return \Drupal\Core\Url * @return \Drupal\Core\Url
* Url for the given request combined with search query parameters. * Url for the given request combined with search query parameters.
*/ */
public function toUrl(Request $request, array $terms, bool $recurse) { public function toUrl(Request $request, array $terms, bool $recurse, $route = NULL) {
$url = Url::createFromRequest($request);
$query_params = $request->query->all(); $query_params = $request->query->all();
if ($route) {
$url = Url::fromRoute($route);
// The form that built the url may use AJAX, but we are redirecting to a
// new page, so it should be disabled.
unset($query_params[FormBuilderInterface::AJAX_FORM_REQUEST]);
unset($query_params[MainContentViewSubscriber::WRAPPER_FORMAT]);
}
else {
$url = Url::createFromRequest($request);
}
unset($query_params[$this->queryParameter]); unset($query_params[$this->queryParameter]);
foreach ($terms as $term) { foreach ($terms as $term) {
$query_params[$this->queryParameter][] = $term->toQueryParams(); $query_params[$this->queryParameter][] = $term->toQueryParams();

51
modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php

@ -5,10 +5,15 @@ namespace Drupal\islandora_advanced_search\Form;
use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\islandora_advanced_search\AdvancedSearchQuery; use Drupal\islandora_advanced_search\AdvancedSearchQuery;
use Drupal\islandora_advanced_search\AdvancedSearchQueryTerm; use Drupal\islandora_advanced_search\AdvancedSearchQueryTerm;
use Drupal\islandora_advanced_search\GetConfigTrait; use Drupal\islandora_advanced_search\GetConfigTrait;
use Drupal\views\DisplayPluginCollection;
use Drupal\views\Entity\View;
use Drupal\views\Plugin\views\display\PathPluginBase;
use Drupal\views\Views;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
@ -46,11 +51,19 @@ class AdvancedSearchForm extends FormBase {
*/ */
protected $request; protected $request;
/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $currentRouteMatch;
/** /**
* Class constructor. * Class constructor.
*/ */
public function __construct(Request $request) { public function __construct(Request $request, RouteMatchInterface $current_route_match) {
$this->request = $request; $this->request = $request;
$this->currentRouteMatch = $current_route_match;
} }
/** /**
@ -58,7 +71,8 @@ class AdvancedSearchForm extends FormBase {
*/ */
public static function create(ContainerInterface $container) { public static function create(ContainerInterface $container) {
return new static( return new static(
$container->get('request_stack')->getMasterRequest() $container->get('request_stack')->getMasterRequest(),
$container->get('current_route_match')
); );
} }
@ -186,13 +200,39 @@ class AdvancedSearchForm extends FormBase {
return [$recursive, $term_values]; return [$recursive, $term_values];
} }
/**
* Gets the route name for the view display used to derive this forms block.
*
* @return string|null
* The route name for the view display that was used to create this
* forms block.
*/
protected function getRouteName(FormStateInterface $form_state) {
$view = $form_state->get('view');
$display = $form_state->get('display');
$display_handlers = new DisplayPluginCollection($view->getExecutable(), Views::pluginManager('display'));
$display_handler = $display_handlers->get($display['id']);
if ($display_handler instanceof PathPluginBase) {
return $display_handler->getRouteName();
}
return NULL;
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function buildForm(array $form, FormStateInterface $form_state, array $fields = [], string $context_filter = NULL) { public function buildForm(array $form, FormStateInterface $form_state, View $view = NULL, array $display = [], array $fields = [], string $context_filter = NULL) {
// Keep reference to view and display as the submit handler may use them
// to redirect the user to the search page.
$form_state->set('view', $view);
$form_state->set('display', $display);
$route_name = $this->getRouteName($form_state);
$requires_redirect = $route_name ? $this->currentRouteMatch->getRouteName() !== $route_name : FALSE;
$form['#attached']['library'][] = 'islandora_advanced_search/advanced.search.form'; $form['#attached']['library'][] = 'islandora_advanced_search/advanced.search.form';
$form['#attached']['drupalSettings']['islandora_advanced_search_form'] = [ $form['#attached']['drupalSettings']['islandora_advanced_search_form'] = [
'id' => Html::getId($this->getFormId()), 'id' => Html::getId($this->getFormId()),
'redirect' => $requires_redirect,
'query_parameter' => AdvancedSearchQuery::getQueryParameter(), 'query_parameter' => AdvancedSearchQuery::getQueryParameter(),
'recurse_parameter' => AdvancedSearchQuery::getRecurseParameter(), 'recurse_parameter' => AdvancedSearchQuery::getRecurseParameter(),
'mapping' => [ 'mapping' => [
@ -352,9 +392,10 @@ class AdvancedSearchForm extends FormBase {
$terms[] = AdvancedSearchQueryTerm::fromUserInput($term); $terms[] = AdvancedSearchQueryTerm::fromUserInput($term);
} }
$terms = array_filter($terms); $terms = array_filter($terms);
$recurse = filter_var($values['recursive'], FILTER_VALIDATE_BOOLEAN); $recurse = filter_var(isset($values['recursive']) ? $values['recursive'] : FALSE, FILTER_VALIDATE_BOOLEAN);
$route = $this->getRouteName($form_state);
$advanced_search_query = new AdvancedSearchQuery(); $advanced_search_query = new AdvancedSearchQuery();
return $advanced_search_query->toUrl($this->request, $terms, $recurse); return $advanced_search_query->toUrl($this->request, $terms, $recurse, $route);
} }
/** /**

2
modules/islandora_advanced_search/src/Plugin/Block/AdvancedSearchBlock.php

@ -371,7 +371,7 @@ class AdvancedSearchBlock extends BlockBase implements ContainerFactoryPluginInt
foreach ($this->configuration[self::SETTING_FIELDS] as $identifier) { foreach ($this->configuration[self::SETTING_FIELDS] as $identifier) {
$configured_fields[$identifier] = $fields[$identifier]; $configured_fields[$identifier] = $fields[$identifier];
} }
return $this->formBuilder->getForm('Drupal\islandora_advanced_search\Form\AdvancedSearchForm', $configured_fields, $this->configuration[self::SETTING_CONTEXTUAL_FILTER]); return $this->formBuilder->getForm('Drupal\islandora_advanced_search\Form\AdvancedSearchForm', $this->view, $this->display, $configured_fields, $this->configuration[self::SETTING_CONTEXTUAL_FILTER]);
} }
/** /**

Loading…
Cancel
Save