- @svendecabooter opened merge request.
- Status changed to Needs review
over 1 year ago 2:07pm 2 May 2023 - 🇧🇪Belgium svendecabooter Gent
I created a MR to incorporate the suggested solution by robin.ingelbrecht into the FAC module.
Right now you have to configure your view, with filters, sorts, ... and your FAC (with filters, sort) separately. In my case this causes a different result set on my search page and in the results in FAC. This doesn't make sense at all. The result should be the same no matter where you execute it.
Provide an extra FAC search plugin "Views Search API search plugin".
I have created a new search plugin in a custom project of mine, where you just can select a view and a display, the settings will then be inherited which results in consistent result sets in the search views and FAC.
namespace Drupal\my_module\Plugin\Search;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\fac\FacConfigInterface;
use Drupal\fac\SearchBase;
use Drupal\search_api\SearchApiException;
use Drupal\views\Entity\View;
/**
* Provides a ViewsApiSearch plugin.
*
* @Search(
* id = "ViewsApiSearch",
* name = @Translation("Views Search API search plugin"),
* )
*/
class ViewsApiSearch extends SearchBase {
use StringTranslationTrait;
use DependencySerializationTrait;
/**
* The parse mode manager.
*
* @var \Drupal\search_api\ParseMode\ParseModePluginManager|null
*/
protected $parseModeManager;
/**
* {@inheritdoc}
*/
public function getConfigForm(array $plugin_config, FormStateInterface $form_state) {
$form = [];
$options = [];
foreach (array_filter(View::loadMultiple(), function (View $view) {
return $view->get('base_field') === 'search_api_id';
}) as $view) {
$options[$view->id()] = $view->label();
}
$form['view'] = [
'#type' => 'select',
'#title' => $this->t('Select the Search API view to use'),
'#options' => $options,
'#empty_option' => $this->t('- Select -'),
'#required' => TRUE,
'#default_value' => $plugin_config['view'] ?? NULL,
'#ajax' => [
'callback' => '::pluginSelection',
'wrapper' => 'plugin-subform',
'event' => 'change',
'effect' => 'fade',
'progress' => [
'message' => $this->t('Loading search plugin options...'),
],
],
];
$form['view_display'] = [
'#type' => 'container',
'#attributes' => [
'id' => 'fac-view-displays',
],
];
if (!$view_id = $form_state->getValue(['plugin', 'config', 'view'])) {
$view_id = $plugin_config['view'] ?? NULL;
}
if ($view_id) {
$options = [];
$view = View::load($view_id);
foreach (array_filter($view->get('display'), function (array $display) {
return $display['display_plugin'] !== 'default';
}) as $display) {
$options[$display['id']] = $display['display_title'];
}
$form['view_display'] = [
'#type' => 'select',
'#title' => $this->t('Display'),
'#options' => $options,
'#empty_option' => $this->t('- Select -'),
'#default_value' => $plugin_config['view_display'] ?? NULL,
'#required' => TRUE,
'#attributes' => [
'id' => 'fac-view-displays',
],
];
}
return $form;
}
/**
* {@inheritdoc}
*/
public function getResults(FacConfigInterface $fac_config, $langcode, $key) {
$plugin_config = $fac_config->getSearchPluginConfig();
/** @var \Drupal\views\Entity\View $view */
if (!$view = View::load($plugin_config['view'])) {
return [];
}
$executable = $view->getExecutable();
$executable->setDisplay($plugin_config['view_display']);
$executable->build();
/** @var \Drupal\search_api\Plugin\views\query\SearchApiQuery $search_api_query */
$search_api_query = $executable->query;
/** @var \Drupal\search_api\Query\QueryInterface $query */
$query = $search_api_query->getSearchApiQuery();
$query->addTag('fac');
$query->addTag('fac_' . $fac_config->id());
$query->keys($key);
$query->range(0, $fac_config->getNumberOfResults());
$filters = $executable->display_handler->getOption('filters');
foreach ($filters as $filter) {
if ($filter['id'] !== 'search_api_fulltext') {
continue;
}
if (!empty($filter['fields'])) {
// Set full text fields.
$query->setFulltextFields($filter['fields']);
}
if (!empty($filter['parse_mode'])) {
/** @var \Drupal\search_api\ParseMode\ParseModeInterface $parse_mode */
$parse_mode = $this->getParseModeManager()
->createInstance($filter['parse_mode']);
$query->setParseMode($parse_mode);
}
$operator = $filter['operator'];
// If the operator was set to OR or NOT, set OR as the conjunction. It is
// also set for NOT since otherwise it would be "not all of these words".
if ($operator != 'and') {
$query->getParseMode()->setConjunction('OR');
}
}
$results = [];
try {
$items = $query->execute()->getResultItems();
foreach ($items as $item) {
$entity = $item->getOriginalObject()->getValue();
$results[] = [
'entity_type' => $entity->getEntityTypeId(),
'entity_id' => $entity->id(),
];
}
} catch (SearchApiException $e) {
return $results;
}
return $results;
}
/**
* Retrieves the parse mode manager.
*
* @return \Drupal\search_api\ParseMode\ParseModePluginManager
* The parse mode manager.
*/
public function getParseModeManager() {
return $this->parseModeManager ?: \Drupal::service('plugin.manager.search_api.parse_mode');
}
}
Create patch.
Needs review
2.0
Code
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
I created a MR to incorporate the suggested solution by robin.ingelbrecht into the FAC module.