Commit 4653c457 authored by ChristianAdamski's avatar ChristianAdamski Committed by borisson_

Issue #2645128 by ChristianAdamski, borisson_: Clean up facet schema / class

parent 645ef745
......@@ -28,7 +28,20 @@ facets.facet.*:
label: 'Query Type Name'
widget:
type: string
label: 'Field identifier'
label: 'Widget identifier'
empty_behavior:
type: mapping
label: 'Empty behavior'
mapping:
behavior:
type: string
label: 'The empty behavior identifier'
text_format:
type: string
label: 'Text format'
text:
type: string
label: 'Text'
widget_configs:
type: sequence
label: 'Widget plugin configurations'
......@@ -56,3 +69,9 @@ facets.facet.*:
label: 'The processor''s weight for this stage'
settings:
type: plugin.plugin_configuration.facets_processor.[%parent.processor_id]
facet_configs:
type: sequence
label: 'Facet plugin-specific options'
sequence:
type: plugin.plugin_configuration.facets_facet_options.[%key]
label: 'Facet plugin options'
......@@ -45,6 +45,9 @@ use Drupal\facets\FacetInterface;
* "widget_configs",
* "options",
* "only_visible_when_facet_source_is_visible",
* "processor_configs",
* "empty_behavior",
* "facet_configs",
* },
* links = {
* "canonical" = "/admin/config/search/facets",
......@@ -177,6 +180,20 @@ class Facet extends ConfigEntityBase implements FacetInterface {
*/
protected $processors;
/**
* Configuration for the processors. This is an array of arrays.
*
* @var array
*/
protected $processor_configs;
/**
* Additional facet configurations.
*
* @var array
*/
protected $facet_configs;
/**
* Is the facet only visible when the facet source is only visible.
*
......@@ -187,6 +204,13 @@ class Facet extends ConfigEntityBase implements FacetInterface {
*/
protected $only_visible_when_facet_source_is_visible;
/**
* The no-result configuration.
*
* @var string[];
*/
protected $empty_behavior;
/**
* The widget plugin manager.
*
......@@ -444,20 +468,19 @@ class Facet extends ConfigEntityBase implements FacetInterface {
if (!isset($this->processors)) {
/* @var $processor_plugin_manager \Drupal\facets\Processor\ProcessorPluginManager */
$processor_plugin_manager = \Drupal::service('plugin.manager.facets.processor');
$processor_settings = $this->getOption('processors', []);
foreach ($processor_plugin_manager->getDefinitions() as $name => $processor_definition) {
if (class_exists($processor_definition['class']) && empty($this->processors[$name])) {
// Create our settings for this processor.
$settings = empty($processor_settings[$name]['settings']) ? [] : $processor_settings[$name]['settings'];
foreach ($processor_plugin_manager->getDefinitions() as $processor_id => $processor_definition) {
if (class_exists($processor_definition['class']) && empty($this->processors[$processor_id])) {
$settings = empty($this->processor_configs[$processor_id]['settings']) ? [] : $this->processor_configs[$processor_id]['settings'];
$settings['enabled'] = empty($this->processor_configs[$processor_id]) ? FALSE : TRUE;
$settings['facet'] = $this;
/* @var $processor \Drupal\facets\Processor\ProcessorInterface */
$processor = $processor_plugin_manager->createInstance($name, $settings);
$this->processors[$name] = $processor;
$processor = $processor_plugin_manager->createInstance($processor_id, $settings);
$this->processors[$processor_id] = $processor;
}
elseif (!class_exists($processor_definition['class'])) {
\Drupal::logger('facets')->warning('Processor @id specifies a non-existing @class.', array('@id' => $name, '@class' => $processor_definition['class']));
\Drupal::logger('facets')->warning('Processor @id specifies a non-existing @class.', array('@id' => $processor_id, '@class' => $processor_definition['class']));
}
}
}
......@@ -549,7 +572,7 @@ class Facet extends ConfigEntityBase implements FacetInterface {
// Filter processors by status if required. Enabled processors are those
// which have settings in the "processors" option.
if ($only_enabled) {
$processors_settings = $this->getOption('processors', array());
$processors_settings = !empty($this->processor_configs) ? $this->processor_configs : [];
$processors = array_intersect_key($processors, $processors_settings);
}
......@@ -561,7 +584,7 @@ class Facet extends ConfigEntityBase implements FacetInterface {
*/
public function getProcessorsByStage($stage, $only_enabled = TRUE) {
$processors = $this->loadProcessors();
$processor_settings = $this->getOption('processors', array());
$processor_settings = $this->processor_configs;
$processor_weights = array();
// Get a list of all processors meeting the criteria (stage and, optionally,
......@@ -602,4 +625,68 @@ class Facet extends ConfigEntityBase implements FacetInterface {
return $this->only_visible_when_facet_source_is_visible;
}
/**
* {@inheritdoc}
*/
public function addProcessor(array $processor) {
$this->processor_configs[$processor['processor_id']] = [
'processor_id' => $processor['processor_id'],
'weights' => $processor['weights'],
'settings' => $processor['settings'],
];
// Sort the processors so we won't have unnecessary changes.
ksort($this->processor_configs);
}
/**
* {@inheritdoc}
*/
public function removeProcessor($processor_id) {
unset($this->processor_configs[$processor_id]);
}
/**
* {@inheritdoc}
*/
public function getEmptyBehavior() {
return $this->empty_behavior;
}
/**
* {@inheritdoc}
*/
public function setEmptyBehavior($empty_behavior) {
$this->empty_behavior = $empty_behavior;
}
/**
* {@inheritdoc}
*/
public function setWidgetConfigs(array $widget_configs) {
$this->widget_configs = $widget_configs;
}
/**
* {@inheritdoc}
*/
public function getWidgetConfigs() {
return $this->widget_configs;
}
/**
* {@inheritdoc}
*/
public function setFacetConfigs(array $facet_configs) {
$this->facet_configs = $facet_configs;
}
/**
* {@inheritdoc}
*/
public function getFacetConfigs() {
return $this->facet_configs;
}
}
......@@ -286,4 +286,61 @@ interface FacetInterface extends ConfigEntityInterface {
*/
public function getOnlyVisibleWhenFacetSourceIsVisible();
/**
* Enabled a processor for this facet.
*
* @param array $processor
*/
public function addProcessor(array $processor);
/**
* Disable a processor for this facet.
*
* @param string $processor_id
*/
public function removeProcessor($processor_id);
/**
* Define the no-results behavior.
*
* @param array $behavior
*/
public function setEmptyBehavior($behavior);
/**
* Return the defined no-results behavior or NULL if none defined.
*
* @return array|NULL
*/
public function getEmptyBehavior();
/**
* Return the configuration of the selected widget.
*
* @return array
*/
public function getWidgetConfigs();
/**
* Set the configuration for the widget of this facet.
*
* @param array $widget_config
*/
public function setWidgetConfigs(array $widget_config);
/**
* Get any additional configuration for this facet, no defined above.
*
* @return array
*/
public function getFacetConfigs();
/**
* Define any additional configuration for this facet not defined above.
*
* @param array $facet_config
*/
public function setFacetConfigs(array $facet_config);
}
......@@ -294,7 +294,7 @@ class DefaultFacetManager {
// No results behavior handling. Return a custom text or false depending on
// settings.
if (empty($facet->getResults())) {
$empty_behavior = $facet->getOption('empty_behavior');
$empty_behavior = $facet->getEmptyBehavior();
if ($empty_behavior['behavior'] == 'text') {
return ['#markup' => $empty_behavior['text']];
}
......
......@@ -11,6 +11,8 @@ use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Facets\FacetInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Defines a base class from which other facet sources may extend.
......@@ -102,4 +104,13 @@ abstract class FacetSourcePluginBase extends PluginBase implements FacetSourcePl
return $this->keys;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(FormStateInterface $form_state, FacetInterface &$facet) {
$facet_source_id = $facet->getFacetSourceId();
$field_identifier = $form_state->getValue('facet_source_configs')[$facet_source_id]['field_identifier'];
$facet->setFieldIdentifier($field_identifier);
}
}
......@@ -35,6 +35,14 @@ interface FacetSourcePluginInterface {
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state, FacetInterface $facet, FacetSourcePluginInterface $facet_source);
/**
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current form state.
* @param \Drupal\facets\FacetInterface $facet
* The facet being edited.
*/
public function submitConfigurationForm(FormStateInterface $form_state, FacetInterface &$facet);
/**
* Fill in facet data in to the configured facets.
*
......
......@@ -195,6 +195,7 @@ class FacetDisplayForm extends EntityForm {
else {
$all_processors = $form_state->get('processors');
}
$enabled_processors = $facet->getProcessors(TRUE);
$stages = $this->processorPluginManager->getProcessingStages();
$processors_by_stage = array();
......@@ -202,8 +203,6 @@ class FacetDisplayForm extends EntityForm {
$processors_by_stage[$stage] = $facet->getProcessorsByStage($stage, FALSE);
}
$processor_settings = $facet->getOption('processors');
$form['#tree'] = TRUE;
$form['#attached']['library'][] = 'search_api/drupal.search_api.index-active-formatters';
$form['#title'] = $this->t('Manage processors for facet %label', array('%label' => $facet->label()));
......@@ -225,7 +224,7 @@ class FacetDisplayForm extends EntityForm {
$form['facet_settings'][$processor_id]['status'] = array(
'#type' => 'checkbox',
'#title' => (string) $processor->getPluginDefinition()['label'],
'#default_value' => $processor->isLocked() || !empty($processor_settings[$processor_id]),
'#default_value' => $processor->isLocked() || !empty($processor->configuration['enabled']),
'#description' => $processor->getDescription(),
'#attributes' => array(
'class' => array(
......@@ -281,7 +280,7 @@ class FacetDisplayForm extends EntityForm {
$form['facet_sorting'][$processor_id]['status'] = array(
'#type' => 'checkbox',
'#title' => (string) $processor->getPluginDefinition()['label'],
'#default_value' => $processor->isLocked() || !empty($processor_settings[$processor_id]),
'#default_value' => $processor->isLocked() || !empty($enabled_processors[$processor_id]),
'#description' => $processor->getDescription(),
'#attributes' => array(
'class' => array(
......@@ -328,7 +327,7 @@ class FacetDisplayForm extends EntityForm {
];
// Behavior for empty facets.
$empty_behavior_config = $facet->getOption('empty_behavior');
$empty_behavior_config = $facet->getEmptyBehavior();
$form['facet_settings']['empty_behavior'] = [
'#type' => 'radios',
'#title' => t('Empty facet behavior'),
......@@ -470,7 +469,6 @@ class FacetDisplayForm extends EntityForm {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$values = $form_state->getValues();
$new_settings = array();
// Store processor settings.
// @todo Go through all available processors, enable/disable with method on
......@@ -483,16 +481,17 @@ class FacetDisplayForm extends EntityForm {
foreach ($processors as $processor_id => $processor) {
$form_container_key = $processor instanceof WidgetOrderProcessorInterface ? 'facet_sorting' : 'facet_settings';
if (empty($values[$form_container_key][$processor_id]['status'])) {
$facet->removeProcessor($processor_id);
continue;
}
$new_settings[$processor_id] = array(
$new_settings = array(
'processor_id' => $processor_id,
'weights' => array(),
'settings' => array(),
);
$processor_values = $values[$form_container_key][$processor_id];
if (!empty($processor_values['weights'])) {
$new_settings[$processor_id]['weights'] = $processor_values['weights'];
$new_settings['weights'] = $processor_values['weights'];
}
if (isset($form[$form_container_key][$processor_id]['settings'])) {
$processor_form_state = new SubFormState(
......@@ -500,16 +499,14 @@ class FacetDisplayForm extends EntityForm {
array($form_container_key, $processor_id, 'settings')
);
$processor->submitConfigurationForm($form[$form_container_key][$processor_id]['settings'], $processor_form_state, $facet);
$new_settings[$processor_id]['settings'] = $processor->getConfiguration();
$new_settings['settings'] = $processor->getConfiguration();
}
$facet->addProcessor($new_settings);
}
// Sort the processors so we won't have unnecessary changes.
ksort($new_settings);
$facet->setOption('processors', $new_settings);
$facet->setWidget($form_state->getValue('widget'));
$facet->set('widget_configs', $form_state->getValue('widget_configs'));
$facet->set('only_visible_when_facet_source_is_visible', $form_state->getValue(['facet_settings', 'only_visible_when_facet_source_is_visible']));
$facet->setWidgetConfigs($form_state->getValue('widget_configs'));
$facet->setOnlyVisibleWhenFacetSourceIsVisible($form_state->getValue(['facet_settings', 'only_visible_when_facet_source_is_visible']));
$empty_behavior_config = [];
$empty_behavior = $form_state->getValue(['facet_settings', 'empty_behavior']);
......@@ -528,7 +525,7 @@ class FacetDisplayForm extends EntityForm {
'value',
]);
}
$facet->setOption('empty_behavior', $empty_behavior_config);
$facet->setEmptyBehavior($empty_behavior_config);
$facet->save();
drupal_set_message(t('Facet %name has been updated.', ['%name' => $facet->getName()]));
......
......@@ -285,7 +285,6 @@ class FacetForm extends EntityForm {
if ($is_new) {
// On facet creation, enable all locked processors by default, using their
// default settings.
$initial_settings = [];
$stages = $this->getProcessorPluginManager()->getProcessingStages();
$processors_definitions = $this->getProcessorPluginManager()->getDefinitions();
......@@ -297,39 +296,38 @@ class FacetForm extends EntityForm {
$weights[$stage_id] = $processor['stages'][$stage_id];
}
}
$initial_settings[$processor_id] = array(
$facet->addProcessor([
'processor_id' => $processor_id,
'weights' => $weights,
'settings' => [],
);
]);
}
}
$facet->setOption('processors', $initial_settings);
// Set a default widget for new facets.
$facet->setWidget('links');
// Set default empty behaviour.
$facet->setOption('empty_behavior', ['behavior' => 'none']);
$facet->setEmptyBehavior(['behavior' => 'none']);
$facet->setOnlyVisibleWhenFacetSourceIsVisible(TRUE);
}
// Make sure the field identifier is copied from within the facet source
// config to the facet object and saved there.
$facet_source = $form_state->getValue('facet_source_id');
$field_identifier = $form_state->getValue('facet_source_configs')[$facet_source]['field_identifier'];
$facet->setFieldIdentifier($field_identifier);
$facet_source_id = $form_state->getValue('facet_source_id');
if (!is_null($facet_source_id) && $facet_source_id !== '') {
/** @var \Drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source */
$facet_source = $this->getFacetSourcePluginManager()->createInstance($facet_source_id);
$facet_source->submitConfigurationForm($form_state, $facet);
}
$facet->save();
// Ensure that the caching of the view display is disabled, so the search
// correctly returns the facets. This is a temporary fix, until the cache
// metadata is correctly stored on the facet block. Only apply this when the
// facet source type is actually something this is related to views.
list($type,) = explode(':', $facet_source);
list($type,) = explode(':', $facet_source_id);
if ($type === 'search_api_views') {
list(, $view_id, $display) = explode(':', $facet_source);
list(, $view_id, $display) = explode(':', $facet_source_id);
}
if (isset($view_id)) {
......
......@@ -48,7 +48,7 @@ class CheckboxWidget implements WidgetInterface {
$results = $facet->getResults();
$items = [];
$configuration = $facet->get('widget_configs');
$configuration = $facet->getWidgetConfigs();
$show_numbers = (bool) $configuration['show_numbers'];
foreach ($results as $result) {
......
......@@ -48,7 +48,7 @@ class LinksWidget implements WidgetInterface {
$results = $facet->getResults();
$items = [];
$configuration = $facet->get('widget_configs');
$configuration = $facet->getWidgetConfigs();
$show_numbers = (bool) $configuration['show_numbers'];
foreach ($results as $result) {
......
......@@ -78,10 +78,10 @@ class CountLimitProcessorTest extends UnitTestCase {
public function testNoFilter() {
$facet = new Facet([], 'facet');
$facet->setResults($this->originalResults);
$facet->setOption('processors', [
'count_limit' => [
'settings' => ['minimum_items' => 4],
],
$facet->addProcessor([
'processor_id' => 'count_limit',
'weights' => [],
'settings' => ['minimum_items' => 4],
]);
$this->processor->setConfiguration(['minimum_items' => 4]);
$sorted_results = $this->processor->build($facet, $this->originalResults);
......@@ -99,10 +99,10 @@ class CountLimitProcessorTest extends UnitTestCase {
public function testMinEqualsValue() {
$facet = new Facet([], 'facet');
$facet->setResults($this->originalResults);
$facet->setOption('processors', [
'count_limit' => [
'settings' => ['minimum_items' => 5],
],
$facet->addProcessor([
'processor_id' => 'count_limit',
'weights' => [],
'settings' => ['minimum_items' => 5],
]);
$this->processor->setConfiguration(['minimum_items' => 5]);
......@@ -121,8 +121,10 @@ class CountLimitProcessorTest extends UnitTestCase {
public function testBetweenMinAndMaxValue() {
$facet = new Facet([], 'facet');
$facet->setResults($this->originalResults);
$facet->setOption('processors', [
'count_limit' => [],
$facet->addProcessor([
'processor_id' => 'count_limit',
'weights' => [],
'settings' => [],
]);
$this->processor->setConfiguration(['minimum_items' => 6, 'maximum_items' => 14]);
......@@ -145,8 +147,10 @@ class CountLimitProcessorTest extends UnitTestCase {
public function testMaxValue() {
$facet = new Facet([], 'facet');
$facet->setResults($this->originalResults);
$facet->setOption('processors', [
'count_limit' => [],
$facet->addProcessor([
'processor_id' => 'count_limit',
'weights' => [],
'settings' => [],
]);
$this->processor->setConfiguration(['maximum_items' => 14]);
......@@ -173,10 +177,10 @@ class CountLimitProcessorTest extends UnitTestCase {
public function testFilterResults() {
$facet = new Facet([], 'facet');
$facet->setResults($this->originalResults);
$facet->setOption('processors', [
'count_limit' => [
'settings' => ['minimum_items' => 8],
],
$facet->addProcessor([
'processor_id' => 'count_limit',
'weights' => [],
'settings' => ['minimum_items' => 8],
]);
$this->processor->setConfiguration(['minimum_items' => 8]);
......
......@@ -91,6 +91,14 @@ class ExcludeSpecifiedItemsProcessorTest extends UnitTestCase {
],
],
]);
$facet->addProcessor([
'processor_id' => 'exclude_specified_items',
'weights' => [],
'settings' => [
'exclude' => 'alpaca',
'regex' => 0,
],
]);
$this->processor->setConfiguration([
'exclude' => 'alpaca',
'regex' => 0,
......@@ -114,6 +122,14 @@ class ExcludeSpecifiedItemsProcessorTest extends UnitTestCase {
],
],
]);
$facet->addProcessor([
'processor_id' => 'exclude_specified_items',
'weights' => [],
'settings' => [
'exclude' => 'alpaca',
'regex' => 0,
],
]);
$this->processor->setConfiguration([
'exclude' => 'llama',
'regex' => 0,
......@@ -143,6 +159,14 @@ class ExcludeSpecifiedItemsProcessorTest extends UnitTestCase {
],
],
]);
$facet->addProcessor([
'processor_id' => 'exclude_specified_items',
'weights' => [],
'settings' => [
'exclude' => 'alpaca',
'regex' => 0,
],
]);
$this->processor->setConfiguration([
'exclude' => $regex,
'regex' => 1,
......
......@@ -96,7 +96,7 @@ class CheckboxWidgetTest extends UnitTestCase {
public function testShowAmount() {
$facet = new Facet([], 'facet');
$facet->setResults($this->originalResults);
$facet->set('widget_configs', ['show_numbers' => 1]);
$facet->setWidgetConfigs(['show_numbers' => 1]);
$output = $this->widget->build($facet);
......
......@@ -73,7 +73,7 @@ class LinksWidgetTest extends UnitTestCase {
public function testNoFilterResults() {
$facet = new Facet([], 'facet');
$facet->setResults($this->originalResults);
$facet->set('widget_configs', ['show_numbers' => 1]);
$facet->setWidgetConfigs(['show_numbers' => 1]);
$output = $this->widget->build($facet);
......@@ -95,7 +95,7 @@ class LinksWidgetTest extends UnitTestCase {
$facet = new Facet([], 'facet');
$facet->setResults($original_results);
$facet->set('widget_configs', ['show_numbers' => 1]);
$facet->setWidgetConfigs(['show_numbers' => 1]);
$output = $this->widget->build($facet);
......@@ -118,7 +118,7 @@ class LinksWidgetTest extends UnitTestCase {
$facet = new Facet([], 'facet');
$facet->setResults($original_results);
$facet->set('widget_configs', ['show_numbers' => 1]);
$facet->setWidgetConfigs(['show_numbers' => 1]);
$output = $this->widget->build($facet);
......@@ -145,7 +145,7 @@ class LinksWidgetTest extends UnitTestCase {
$facet = new Facet([], 'facet');
$facet->setResults($original_results);
$facet->set('widget_configs', ['show_numbers' => 0]);
$facet->setWidgetConfigs(['show_numbers' => 0]);
$output = $this->widget->build($facet);
......@@ -159,7 +159,7 @@ class LinksWidgetTest extends UnitTestCase {
// Enable the 'show_numbers' setting again to make sure that the switch
// between those settings works.
$facet->set('widget_configs', ['show_numbers' => 1]);
$facet->setWidgetConfigs(['show_numbers' => 1]);
$output = $this->widget->build($facet);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment