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

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

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions modules/islandora_advanced_search/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Configuring Solr](#configuring-solr)
- [Configure Collection Search](#configure-collection-search)
- [Configure Views](#configure-views)
- [Exposed Form](#exposed-form)
- [Collection Search](#collection-search)
- [Paging](#paging)
- [Sorting](#sorting)
Expand Down Expand Up @@ -96,6 +97,21 @@ the [Drupal Documentation](https://www.drupal.org/docs/8/core/modules/views), as
well as the
[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

That being said it will be typical that you require the following
Expand Down Expand Up @@ -194,6 +210,11 @@ checkbox.

![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

Further documentation for this module is available on the
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

// Gets current parameters minus ones provided by the form.
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.
const param_match = "query\\[\\d+\\]\\[.+\\]".replace("query", query_parameter);
const param_regex = new RegExp(param_match, "g");
Expand Down Expand Up @@ -97,13 +98,19 @@
//
// Logic server side / client side should match to generate the
// appropriate URL with javascript enabled or disable.
$form.submit(function (e) {
e.preventDefault();
e.stopPropagation();
const inputs = $form.serializeArray();
const href = url(inputs, settings.islandora_advanced_search_form);
window.history.pushState(null, document.title, href);
});
//
// 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) {
e.preventDefault();
e.stopPropagation();
const inputs = $form.serializeArray();
const href = url(inputs, settings.islandora_advanced_search_form);
window.history.pushState(null, document.title, href);
});
}
// Reset should trigger refresh of AJAX Blocks / Views.
$form.find('input[data-drupal-selector = "edit-reset"]').mousedown(function (e) {
const inputs = [];
Expand Down
15 changes: 13 additions & 2 deletions modules/islandora_advanced_search/src/AdvancedSearchQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace Drupal\islandora_advanced_search;

use Drupal\block\Entity\Block;
use Drupal\Core\EventSubscriber\MainContentViewSubscriber;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Url;
use Drupal\islandora_advanced_search\Form\SettingsForm;
use Drupal\islandora_advanced_search\Plugin\Block\AdvancedSearchBlock;
Expand Down Expand Up @@ -223,9 +225,18 @@ public function alterView(Request $request, ViewExecutable $view, $display_id) {
* @return \Drupal\Core\Url
* Url for the given request combined with search query parameters.
*/
public function toUrl(Request $request, array $terms, bool $recurse) {
$url = Url::createFromRequest($request);
public function toUrl(Request $request, array $terms, bool $recurse, $route = NULL) {
$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]);
foreach ($terms as $term) {
$query_params[$this->queryParameter][] = $term->toQueryParams();
Expand Down
51 changes: 46 additions & 5 deletions modules/islandora_advanced_search/src/Form/AdvancedSearchForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
use Drupal\Component\Utility\Html;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\islandora_advanced_search\AdvancedSearchQuery;
use Drupal\islandora_advanced_search\AdvancedSearchQueryTerm;
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\HttpFoundation\Request;

Expand Down Expand Up @@ -46,19 +51,28 @@ class AdvancedSearchForm extends FormBase {
*/
protected $request;

/**
* The current route match.
*
* @var \Drupal\Core\Routing\RouteMatchInterface
*/
protected $currentRouteMatch;

/**
* Class constructor.
*/
public function __construct(Request $request) {
public function __construct(Request $request, RouteMatchInterface $current_route_match) {
$this->request = $request;
$this->currentRouteMatch = $current_route_match;
}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('request_stack')->getMasterRequest()
$container->get('request_stack')->getMasterRequest(),
$container->get('current_route_match')
);
}

Expand Down Expand Up @@ -186,13 +200,39 @@ protected function processInput(FormStateInterface $form_state, array $term_defa
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}
*/
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']['drupalSettings']['islandora_advanced_search_form'] = [
'id' => Html::getId($this->getFormId()),
'redirect' => $requires_redirect,
'query_parameter' => AdvancedSearchQuery::getQueryParameter(),
'recurse_parameter' => AdvancedSearchQuery::getRecurseParameter(),
'mapping' => [
Expand Down Expand Up @@ -352,9 +392,10 @@ protected function buildUrl(FormStateInterface $form_state) {
$terms[] = AdvancedSearchQueryTerm::fromUserInput($term);
}
$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();
return $advanced_search_query->toUrl($this->request, $terms, $recurse);
return $advanced_search_query->toUrl($this->request, $terms, $recurse, $route);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ public function build() {
foreach ($this->configuration[self::SETTING_FIELDS] as $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]);
}

/**
Expand Down