You are here

class ManageSortFieldsForm in Search API Sorts Widget 1.x

Provides a form for managing sort fields for a search api display.

Hierarchy

Expanded class hierarchy of ManageSortFieldsForm

1 string reference to 'ManageSortFieldsForm'
search_api_sorts_widget.routing.yml in ./search_api_sorts_widget.routing.yml
search_api_sorts_widget.routing.yml

File

src/Form/ManageSortFieldsForm.php, line 22

Namespace

Drupal\search_api_sorts_widget\Form
View source
class ManageSortFieldsForm extends FormBase {
  use ConfigIdEscapeTrait;

  /**
   * The search_api display plugin manager.
   *
   * @var \Drupal\search_api\Display\DisplayPluginManagerInterface
   */
  protected $displayPluginManager;

  /**
   * The language manager.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * The module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * The search api sorts field storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $searchApiSortsFieldStorage;

  /**
   * The search api sorts widget storage.
   *
   * @var \Drupal\Core\Entity\EntityStorageInterface
   */
  protected $searchApiSortsWidgetStorage;

  /**
   * The index this search api display is attached to.
   *
   * @var string
   */
  protected $index;

  /**
   * The search api display used by the form.
   *
   * @var string
   */
  protected $display;

  /**
   * Constructs the DisplaySortsForm object.
   *
   * @param \Drupal\search_api\Display\DisplayPluginManagerInterface $display_plugin_manager
   *   The search_api display plugin manager.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity manager.
   * @param \Drupal\Core\Language\LanguageManagerInterface $languageManager
   *   The language manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The module handler.
   */
  public function __construct(DisplayPluginManagerInterface $display_plugin_manager, EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $languageManager, ModuleHandlerInterface $moduleHandler) {
    $this->displayPluginManager = $display_plugin_manager;
    $this->languageManager = $languageManager;
    $this->moduleHandler = $moduleHandler;
    $this->searchApiSortsFieldStorage = $entity_type_manager
      ->getStorage('search_api_sorts_field');
    $this->searchApiSortsWidgetStorage = $entity_type_manager
      ->getStorage('search_api_sorts_widget');
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('plugin.manager.search_api.display'), $container
      ->get('entity_type.manager'), $container
      ->get('language_manager'), $container
      ->get('module_handler'));
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'search_api_sorts_widget_display_sorts_form';
  }
  private function getSettings() {
    $display_id = $this
      ->getEscapedConfigId($this->display
      ->getPluginId());
    $search_api_sorts_widget = $this->searchApiSortsWidgetStorage
      ->load($display_id);
    if (empty($search_api_sorts_widget)) {
      $search_api_sorts_widget = SearchApiSortsWidget::create([
        'langcode' => $this->languageManager
          ->getDefaultLanguage()
          ->getId(),
        'id' => $display_id,
      ]);
      $search_api_sorts_widget
        ->save();
    }
    return $search_api_sorts_widget;
  }

  /**
   * {@inheritdoc}
   * @throws \Drupal\Component\Plugin\Exception\PluginException
   */
  public function buildForm(array $form, FormStateInterface $form_state, IndexInterface $search_api_index = NULL, $search_api_display = NULL) {
    $original_search_api_display = $this
      ->getOriginalConfigId($search_api_display);
    $this->display = $this->displayPluginManager
      ->createInstance($original_search_api_display);
    $this->index = $search_api_index;
    $settings = $this
      ->getSettings();
    if ($disabled = empty($this->index
      ->status())) {
      $this
        ->messenger()
        ->addWarning($this
        ->t('Since the index for this display is at the moment disabled, no sorts can be activated.'));
    }
    $form['#title'] = $this
      ->t('Manage sort widgets for %label', [
      '%label' => $this->display
        ->label(),
    ]);
    if ($this->languageManager
      ->getDefaultLanguage()
      ->getId() !== $this->languageManager
      ->getCurrentLanguage()
      ->getId()) {
      $form['translation_message'] = [
        '#theme' => 'status_messages',
        '#message_list' => [
          MessengerInterface::TYPE_WARNING => [
            $this
              ->t('You are currently editing the %language version of the search api sorts widgets.', [
              '%language' => $this->languageManager
                ->getDefaultLanguage()
                ->getName(),
            ]),
          ],
        ],
      ];
    }
    $form['widget'] = [
      '#type' => 'fieldset',
      '#title' => $this
        ->t('Widget settings'),
    ];
    $form['widget']['status'] = array(
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Active'),
      '#default_value' => $settings
        ->get('status'),
    );
    $form['widget']['autosubmit'] = array(
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Autosubmit'),
      '#description' => $this
        ->t('Automatically submit the form once an element is changed.'),
      '#default_value' => $settings
        ->get('autosubmit'),
    );
    $form['widget']['autosubmit_hide'] = array(
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Hide submit button'),
      '#description' => $this
        ->t('Hide submit button if javascript is enabled.'),
      '#default_value' => $settings
        ->get('autosubmit_hide'),
    );
    $header = [
      $this
        ->t('Weight'),
      $this
        ->t('Field'),
      $this
        ->t('Label: Ascending'),
      $this
        ->t('Label: Descending'),
    ];
    $sorts_widget_are_translatable = $this->moduleHandler
      ->moduleExists('config_translation') && $this->languageManager
      ->isMultilingual();
    if ($sorts_widget_are_translatable) {
      $header[] = $this
        ->t('Translate');
    }
    $form['sorts'] = [
      '#type' => 'table',
      '#header' => $header,
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'search-api-sort-order-weight',
        ],
      ],
      '#empty' => $this
        ->t('There are currently no fields for which sorts can be displayed.'),
    ];
    $fields = $this
      ->getSearchApiSortsFieldsValues();
    $sorts = $settings
      ->get('sorts');
    uasort($sorts, [
      'Drupal\\Component\\Utility\\SortArray',
      'sortByWeightElement',
    ]);
    foreach ($fields as $key => $sort) {
      $field = $fields[$key] ?? NULL;
      if (empty($field) || !$field['status']) {
        continue;
      }
      $form['sorts'][$key]['#attributes']['class'][] = 'draggable';
      $form['sorts'][$key]['weight'] = [
        '#type' => 'weight',
        '#default_value' => $sorts[$key]['weight'] ?? 0,
        '#delta' => 100,
        '#attributes' => [
          'class' => [
            'search-api-sort-order-weight',
          ],
        ],
      ];
      $form['sorts'][$key]['field'] = [
        '#markup' => Html::escape($field['field']),
      ];
      $form['sorts'][$key]['label_asc'] = array(
        '#type' => 'textfield',
        '#default_value' => $sorts[$key]['label_asc'] ?? '',
      );
      $form['sorts'][$key]['label_desc'] = array(
        '#type' => 'textfield',
        '#default_value' => $sorts[$key]['label_desc'] ?? '',
      );
      if ($sorts_widget_are_translatable) {
        $form['sorts'][$key]['translate'] = [
          '#type' => 'link',
          '#title' => $this
            ->t('Translate'),
          '#url' => Url::fromRoute('entity.search_api_sorts_widget.config_translation_overview', [
            'search_api_sorts_widget' => $this
              ->getEscapedConfigId($this->display
              ->getPluginId()) . '_' . $key,
          ]),
        ];
      }
    }
    $form['submit'] = [
      '#type' => 'submit',
      '#value' => $this
        ->t('Save settings'),
    ];
    return $form;
  }

  /**
   * Returns an array of all saved search api sorts fields.
   *
   * @return array
   *   An array of fields, filled with values from the index.
   */
  protected function getSearchApiSortsFieldsValues() {
    $fields = $this
      ->buildSearchApiSortsFieldsDefaultValues();
    $this
      ->fillSearchApiSortsFieldsValues($fields);
    return $fields;
  }

  /**
   * An array of sortable fields with default values.
   *
   * @return array
   *   An array of fields.
   */
  private function buildSearchApiSortsFieldsDefaultValues() {

    // Add our dummy relevance field.
    $fields = [
      'search_api_relevance' => [
        'status' => FALSE,
        'default_sort' => FALSE,
        'default_order' => 'desc',
        'field' => 'Relevance',
        'type' => 'decimal',
        'label' => $this
          ->t('Relevance'),
        'weight' => 0,
      ],
    ];
    foreach ($this->index
      ->getFields() as $field) {

      // Skip fulltext or multi-value, you cannot sort them.
      if ($field
        ->getType() == 'text' || strpos($field
        ->getType(), 'list<') !== FALSE) {
        continue;
      }
      $fields[$field
        ->getFieldIdentifier()] = [
        'status' => FALSE,
        'default_sort' => FALSE,
        'default_order' => 'asc',
        'field' => $field
          ->getLabel(),
        'type' => $field
          ->getType(),
        'label' => $field
          ->getLabel(),
        'weight' => 0,
      ];
    }
    return $fields;
  }

  /**
   * Fills the array build by buildDefaultFieldValues().
   *
   * @param array $fields
   *   An array of fields, filled with data from the index.
   */
  private function fillSearchApiSortsFieldsValues(array &$fields) {
    $search_api_sorts_fields = $this->searchApiSortsFieldStorage
      ->loadByProperties([
      'display_id' => $this
        ->getEscapedConfigId($this->display
        ->getPluginId()),
    ]);
    foreach ($search_api_sorts_fields as $search_api_sorts_field) {
      if (isset($fields[$search_api_sorts_field
        ->getFieldIdentifier()])) {
        $fields[$search_api_sorts_field
          ->getFieldIdentifier()]['status'] = $search_api_sorts_field
          ->getStatus();
        $fields[$search_api_sorts_field
          ->getFieldIdentifier()]['default_sort'] = $search_api_sorts_field
          ->getDefaultSort();
        $fields[$search_api_sorts_field
          ->getFieldIdentifier()]['default_order'] = $search_api_sorts_field
          ->getDefaultOrder();
        $fields[$search_api_sorts_field
          ->getFieldIdentifier()]['label'] = $search_api_sorts_field
          ->getLabel();
        $fields[$search_api_sorts_field
          ->getFieldIdentifier()]['weight'] = $search_api_sorts_field
          ->getWeight();
      }
    }

    // Sort the fields by the weight element.
    uasort($fields, [
      'Drupal\\Component\\Utility\\SortArray',
      'sortByWeightElement',
    ]);
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $form_state
      ->cleanValues();
    $status = $form_state
      ->getValue('status');
    foreach ($form_state
      ->getValue('sorts') as $key => $v) {
      if ($status) {
        $this
          ->validateLabel($form_state, 'label_asc', $key, $v);
        $this
          ->validateLabel($form_state, 'label_desc', $key, $v);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $status = $form_state
      ->getValue('status');
    $autosubmit = $form_state
      ->getValue('autosubmit');
    $autosubmit_hide = $form_state
      ->getValue('autosubmit_hide');
    $display_id = $this
      ->getEscapedConfigId($this->display
      ->getPluginId());
    $search_api_sorts_widget = $this
      ->getSettings();
    $search_api_sorts_widget
      ->set('id', $display_id);
    $search_api_sorts_widget
      ->set('display_id', $display_id);
    $search_api_sorts_widget
      ->set('status', $status);
    $search_api_sorts_widget
      ->set('autosubmit', $autosubmit);
    $search_api_sorts_widget
      ->set('autosubmit_hide', $autosubmit_hide);
    $search_api_sorts_widget
      ->set('sorts', $form_state
      ->getValue('sorts'));
    $search_api_sorts_widget
      ->save();

    // foreach ($form_state->getValue('sorts') as $key => $v) {
    //   $config_id = $this->getEscapedConfigId($this->display->getPluginId()) . '_' . $key;
    //   $search_api_sorts_widget = NULL;
    //   if (isset($search_api_sorts_widgets[$config_id])) {
    //     // If the field sort is not enabled, delete the config if it exists.
    //     if ($v['status'] == 0) {
    //       $search_api_sorts_widgets[$config_id]->delete();
    //     }
    //     else {
    //       $search_api_sorts_widget = $search_api_sorts_widgets[$config_id];
    //     }
    //   }
    //   else {
    //     // Create configs only for enabled sort fields.
    //     if ($v['status'] == 1) {
    //       $search_api_sorts_widget = SearchApiSortsField::create(['langcode' => $this->languageManager->getDefaultLanguage()->getId()]);
    //       $search_api_sorts_widget->set('id', $config_id);
    //       $search_api_sorts_widget->set('field_identifier', $key);
    //       $search_api_sorts_widget->set('display_id', $this->getEscapedConfigId($this->display->getPluginId()));
    //     }
    //   }
    //   // Set all fields from the form to enabled configs only and save the
    //   // config.
    //   if ($v['status'] == 1) {
    //     $search_api_sorts_widget->set('status', $v['status']);
    //     $search_api_sorts_widget->set('default_sort', $form_state->getValue('default_sort') == $key);
    //     $search_api_sorts_widget->set('default_order', $v['default_order']);
    //     $search_api_sorts_widget->set('label', $v['label']);
    //     $search_api_sorts_widget->set('weight', $v['weight']);
    //     $search_api_sorts_widget->save();
    //   }
    // }
    $this
      ->messenger()
      ->addStatus($this
      ->t('The changes were successfully saved.'));
  }

  /**
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   * @param string $field_name
   * @param $key
   * @param $v
   */
  private function validateLabel(FormStateInterface $form_state, string $field_name, $key, $v) : void {
    if (strlen($v[$field_name]) > 80) {
      $form_state
        ->setErrorByName("sorts][{$key}][{$field_name}", $this
        ->t('Labels cannot be longer than 80 characters, but "@label" is @count characters long.', [
        '@label' => $v[$field_name],
        '@count' => strlen($v[$field_name]),
      ]));
    }
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 3
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 3
FormBase::container private function Returns the service container.
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route.
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
ManageSortFieldsForm::$display protected property The search api display used by the form.
ManageSortFieldsForm::$displayPluginManager protected property The search_api display plugin manager.
ManageSortFieldsForm::$index protected property The index this search api display is attached to.
ManageSortFieldsForm::$languageManager protected property The language manager.
ManageSortFieldsForm::$moduleHandler protected property The module handler.
ManageSortFieldsForm::$searchApiSortsFieldStorage protected property The search api sorts field storage.
ManageSortFieldsForm::$searchApiSortsWidgetStorage protected property The search api sorts widget storage.
ManageSortFieldsForm::buildForm public function Overrides FormInterface::buildForm
ManageSortFieldsForm::buildSearchApiSortsFieldsDefaultValues private function An array of sortable fields with default values.
ManageSortFieldsForm::create public static function Instantiates a new instance of this class. Overrides FormBase::create
ManageSortFieldsForm::fillSearchApiSortsFieldsValues private function Fills the array build by buildDefaultFieldValues().
ManageSortFieldsForm::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
ManageSortFieldsForm::getSearchApiSortsFieldsValues protected function Returns an array of all saved search api sorts fields.
ManageSortFieldsForm::getSettings private function
ManageSortFieldsForm::submitForm public function Form submission handler. Overrides FormInterface::submitForm
ManageSortFieldsForm::validateForm public function Form validation handler. Overrides FormBase::validateForm
ManageSortFieldsForm::validateLabel private function
ManageSortFieldsForm::__construct public function Constructs the DisplaySortsForm object.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.