/**
  * Tests processing stages.
  */
 public function testGetProcessingStages()
 {
     $namespaces = new ArrayObject();
     $sut = new ProcessorPluginManager($namespaces, $this->cache, $this->moduleHandler, $this->translator);
     $stages = [ProcessorInterface::STAGE_PRE_QUERY, ProcessorInterface::STAGE_POST_QUERY, ProcessorInterface::STAGE_BUILD];
     $this->assertEquals($stages, array_keys($sut->getProcessingStages()));
 }
Example #2
0
 /**
  * {@inheritdoc}
  */
 public function form(array $form, FormStateInterface $form_state)
 {
     $form['#attached']['library'][] = 'facets/drupal.facets.admin_css';
     /** @var \Drupal\facets\FacetInterface $facet */
     $facet = $this->entity;
     $widget_options = [];
     foreach ($this->getWidgetPluginManager()->getDefinitions() as $widget_id => $definition) {
         $widget_options[$widget_id] = !empty($definition['label']) ? $definition['label'] : $widget_id;
     }
     $form['widget'] = ['#type' => 'radios', '#title' => $this->t('Widget'), '#description' => $this->t('The widget used for displaying this facet.'), '#options' => $widget_options, '#default_value' => $facet->getWidget(), '#required' => TRUE, '#ajax' => ['trigger_as' => ['name' => 'widget_configure'], 'callback' => '::buildAjaxWidgetConfigForm', 'wrapper' => 'facets-widget-config-form', 'method' => 'replace', 'effect' => 'fade']];
     $form['widget_configs'] = ['#type' => 'container', '#attributes' => ['id' => 'facets-widget-config-form'], '#tree' => TRUE];
     $form['widget_configure_button'] = ['#type' => 'submit', '#name' => 'widget_configure', '#value' => $this->t('Configure widget'), '#limit_validation_errors' => [['widget']], '#submit' => ['::submitAjaxWidgetConfigForm'], '#ajax' => ['callback' => '::buildAjaxWidgetConfigForm', 'wrapper' => 'facets-widget-config-form'], '#attributes' => ['class' => ['js-hide']]];
     $this->buildWidgetConfigForm($form, $form_state);
     // Retrieve lists of all processors, and the stages and weights they have.
     if (!$form_state->has('processors')) {
         $all_processors = $facet->getProcessors(FALSE);
         $sort_processors = function (ProcessorInterface $a, ProcessorInterface $b) {
             return strnatcasecmp((string) $a->getPluginDefinition()['label'], (string) $b->getPluginDefinition()['label']);
         };
         uasort($all_processors, $sort_processors);
     } else {
         $all_processors = $form_state->get('processors');
     }
     $enabled_processors = $facet->getProcessors(TRUE);
     $stages = $this->processorPluginManager->getProcessingStages();
     $processors_by_stage = array();
     foreach ($stages as $stage => $definition) {
         $processors_by_stage[$stage] = $facet->getProcessorsByStage($stage, FALSE);
     }
     $form['#tree'] = TRUE;
     $form['#attached']['library'][] = 'facets/drupal.facets.index-active-formatters';
     $form['#title'] = $this->t('Edit %label facet', array('%label' => $facet->label()));
     // Add the list of all other processors with checkboxes to enable/disable
     // them.
     $form['facet_settings'] = array('#type' => 'fieldset', '#title' => $this->t('Facet settings'), '#attributes' => array('class' => array('search-api-status-wrapper')));
     foreach ($all_processors as $processor_id => $processor) {
         if (!$processor instanceof WidgetOrderProcessorInterface && !$processor instanceof UrlProcessorInterface) {
             $clean_css_id = Html::cleanCssIdentifier($processor_id);
             $form['facet_settings'][$processor_id]['status'] = array('#type' => 'checkbox', '#title' => (string) $processor->getPluginDefinition()['label'], '#default_value' => $processor->isLocked() || !empty($enabled_processors[$processor_id]), '#description' => $processor->getDescription(), '#attributes' => array('class' => array('search-api-processor-status-' . $clean_css_id), 'data-id' => $clean_css_id), '#disabled' => $processor->isLocked(), '#access' => !$processor->isHidden());
             $processor_form_state = new SubFormState($form_state, ['facet_settings', $processor_id, 'settings']);
             $processor_form = $processor->buildConfigurationForm($form, $processor_form_state, $facet);
             if ($processor_form) {
                 $form['facet_settings'][$processor_id]['settings'] = array('#type' => 'details', '#title' => $this->t('%processor settings', ['%processor' => (string) $processor->getPluginDefinition()['label']]), '#open' => TRUE, '#attributes' => array('class' => array('facets-processor-settings-' . Html::cleanCssIdentifier($processor_id), 'facets-processor-settings-facet', 'facets-processor-settings')), '#states' => array('visible' => array(':input[name="facet_settings[' . $processor_id . '][status]"]' => array('checked' => TRUE))));
                 $form['facet_settings'][$processor_id]['settings'] += $processor_form;
             }
         }
     }
     // Add the list of widget sort processors with checkboxes to enable/disable
     // them.
     $form['facet_sorting'] = array('#type' => 'fieldset', '#title' => $this->t('Facet sorting'), '#attributes' => array('class' => array('search-api-status-wrapper')));
     foreach ($all_processors as $processor_id => $processor) {
         if ($processor instanceof WidgetOrderProcessorInterface) {
             $clean_css_id = Html::cleanCssIdentifier($processor_id);
             $form['facet_sorting'][$processor_id]['status'] = array('#type' => 'checkbox', '#title' => (string) $processor->getPluginDefinition()['label'], '#default_value' => $processor->isLocked() || !empty($enabled_processors[$processor_id]), '#description' => $processor->getDescription(), '#attributes' => array('class' => array('search-api-processor-status-' . $clean_css_id), 'data-id' => $clean_css_id), '#disabled' => $processor->isLocked(), '#access' => !$processor->isHidden());
             $processor_form_state = new SubFormState($form_state, array('facet_sorting', $processor_id, 'settings'));
             $processor_form = $processor->buildConfigurationForm($form, $processor_form_state, $facet);
             if ($processor_form) {
                 $form['facet_sorting'][$processor_id]['settings'] = array('#type' => 'container', '#open' => TRUE, '#attributes' => array('class' => array('facets-processor-settings-' . Html::cleanCssIdentifier($processor_id), 'facets-processor-settings-sorting', 'facets-processor-settings')), '#states' => array('visible' => array(':input[name="facet_sorting[' . $processor_id . '][status]"]' => array('checked' => TRUE))));
                 $form['facet_sorting'][$processor_id]['settings'] += $processor_form;
             }
         }
     }
     $form['facet_settings']['only_visible_when_facet_source_is_visible'] = ['#type' => 'checkbox', '#title' => $this->t('Hide facet when facet source is not rendered'), '#description' => $this->t('When checked, this facet will only be rendered when the facet source is rendered.  If you want to show facets on other pages too, you need to uncheck this setting.'), '#default_value' => $facet->getOnlyVisibleWhenFacetSourceIsVisible()];
     $form['facet_settings']['show_only_one_result'] = ['#type' => 'checkbox', '#title' => $this->t('Make sure only one result can be shown.'), '#description' => $this->t('When checked, this will make sure that only one result can be selected for this facet at one time.'), '#default_value' => $facet->getShowOnlyOneResult()];
     $form['facet_settings']['url_alias'] = ['#type' => 'machine_name', '#title' => $this->t('Url alias'), '#default_value' => $facet->getUrlAlias(), '#maxlength' => 50, '#required' => TRUE, '#machine_name' => ['exists' => [\Drupal::service('entity_type.manager')->getStorage('facets_facet'), 'load'], 'source' => ['name']]];
     $empty_behavior_config = $facet->getEmptyBehavior();
     $form['facet_settings']['empty_behavior'] = ['#type' => 'radios', '#title' => t('Empty facet behavior'), '#default_value' => $empty_behavior_config['behavior'] ?: 'none', '#options' => ['none' => t('Do not display facet'), 'text' => t('Display text')], '#description' => $this->t('The action to take when a facet has no items.'), '#required' => TRUE];
     $form['facet_settings']['empty_behavior_container'] = ['#type' => 'container', '#states' => array('visible' => array(':input[name="facet_settings[empty_behavior]"]' => array('value' => 'text')))];
     $form['facet_settings']['empty_behavior_container']['empty_behavior_text'] = ['#type' => 'text_format', '#title' => $this->t('Empty text'), '#format' => isset($empty_behavior_config['text_format']) ? $empty_behavior_config['text_format'] : 'plain_text', '#editor' => TRUE, '#default_value' => isset($empty_behavior_config['text_format']) ? $empty_behavior_config['text'] : ''];
     $form['facet_settings']['query_operator'] = ['#type' => 'radios', '#title' => $this->t('Operator'), '#options' => ['OR' => $this->t('OR'), 'AND' => $this->t('AND')], '#description' => $this->t('AND filters are exclusive and narrow the result set. OR filters are inclusive and widen the result set.'), '#default_value' => $facet->getQueryOperator()];
     $form['facet_settings']['exclude'] = ['#type' => 'checkbox', '#title' => $this->t('Exclude'), '#description' => $this->t('Make the search exclude selected facets, instead of restricting it to them.'), '#default_value' => $facet->getExclude()];
     $form['facet_settings']['weight'] = ['#type' => 'number', '#title' => $this->t('Weight'), '#default_value' => $facet->getWeight(), '#maxlength' => 4, '#required' => TRUE];
     $form['weights'] = array('#type' => 'details', '#title' => t('Advanced settings'), '#collapsible' => TRUE, '#collapsed' => TRUE);
     $form['weights']['order'] = ['#markup' => "<h3>" . t('Processor order') . "</h3>"];
     // Order enabled processors per stage, create all the containers for the
     // different stages.
     foreach ($stages as $stage => $description) {
         $form['weights'][$stage] = array('#type' => 'fieldset', '#title' => $description['label'], '#attributes' => array('class' => array('search-api-stage-wrapper', 'search-api-stage-wrapper-' . Html::cleanCssIdentifier($stage))));
         $form['weights'][$stage]['order'] = array('#type' => 'table');
         $form['weights'][$stage]['order']['#tabledrag'][] = array('action' => 'order', 'relationship' => 'sibling', 'group' => 'search-api-processor-weight-' . Html::cleanCssIdentifier($stage));
     }
     $processor_settings = $facet->getProcessorConfigs();
     // Fill in the containers previously created with the processors that are
     // enabled on the facet.
     foreach ($processors_by_stage as $stage => $processors) {
         /** @var \Drupal\facets\Processor\ProcessorInterface $processor */
         foreach ($processors as $processor_id => $processor) {
             $weight = isset($processor_settings[$processor_id]['weights'][$stage]) ? $processor_settings[$processor_id]['weights'][$stage] : $processor->getDefaultWeight($stage);
             if ($processor->isHidden()) {
                 $form['processors'][$processor_id]['weights'][$stage] = array('#type' => 'value', '#value' => $weight);
                 continue;
             }
             $form['weights'][$stage]['order'][$processor_id]['#attributes']['class'][] = 'draggable';
             $form['weights'][$stage]['order'][$processor_id]['#attributes']['class'][] = 'search-api-processor-weight--' . Html::cleanCssIdentifier($processor_id);
             $form['weights'][$stage]['order'][$processor_id]['#weight'] = $weight;
             $form['weights'][$stage]['order'][$processor_id]['label']['#plain_text'] = (string) $processor->getPluginDefinition()['label'];
             $form['weights'][$stage]['order'][$processor_id]['weight'] = array('#type' => 'weight', '#title' => $this->t('Weight for processor %title', array('%title' => (string) $processor->getPluginDefinition()['label'])), '#title_display' => 'invisible', '#default_value' => $weight, '#parents' => array('processors', $processor_id, 'weights', $stage), '#attributes' => array('class' => array('search-api-processor-weight-' . Html::cleanCssIdentifier($stage))));
         }
     }
     // Add vertical tabs containing the settings for the processors. Tabs for
     // disabled processors are hidden with JS magic, but need to be included in
     // case the processor is enabled.
     $form['processor_settings'] = array('#title' => $this->t('Processor settings'), '#type' => 'vertical_tabs');
     return $form;
 }