View source
<?php
namespace Drupal\better_exposed_filters\Plugin\better_exposed_filters\sort;
use Drupal\better_exposed_filters\BetterExposedFiltersHelper;
use Drupal\better_exposed_filters\Plugin\BetterExposedFiltersWidgetBase;
use Drupal\better_exposed_filters\Plugin\BetterExposedFiltersWidgetInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
abstract class SortWidgetBase extends BetterExposedFiltersWidgetBase implements BetterExposedFiltersWidgetInterface {
use StringTranslationTrait;
protected $sortElements = [
'sort_bef_combine',
'sort_by',
'sort_order',
];
public function defaultConfiguration() {
return parent::defaultConfiguration() + [
'advanced' => [
'collapsible' => FALSE,
'collapsible_label' => $this
->t('Sort options'),
'combine' => FALSE,
'combine_rewrite' => '',
'is_secondary' => FALSE,
'reset' => FALSE,
'reset_label' => '',
],
];
}
public static function isApplicable($handler = NULL, array $options = []) {
return TRUE;
}
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = [];
$form['advanced'] = [
'#type' => 'details',
'#title' => $this
->t('Advanced sort options'),
];
$form['advanced']['combine'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Combine sort order with sort by'),
'#default_value' => !empty($this->configuration['advanced']['combine']),
'#description' => $this
->t('Combines the sort by options and order (ascending or decending) into a single list. Use this to display "Option1 (ascending)", "Option1 (descending)", "Option2 (ascending)", "Option2 (descending)" in a single form element. Sort order should first be exposed by selecting <em>Allow people to choose the sort order</em>.'),
'#states' => [
'enabled' => [
':input[name="exposed_form_options[expose_sort_order]"]' => [
'checked' => TRUE,
],
],
],
];
$form['advanced']['combine_rewrite'] = [
'#type' => 'textarea',
'#title' => $this
->t('Rewrite the text displayed'),
'#default_value' => $this->configuration['advanced']['combine_rewrite'],
'#description' => $this
->t('Use this field to rewrite the text displayed for combined sort options and sort order. Use the format of current_text|replacement_text, one replacement per line. For example: <pre>
Post date Asc|Oldest first
Post date Desc|Newest first
Title Asc|A -> Z
Title Desc|Z -> A</pre> Leave the replacement text blank to remove an option altogether. The order the options appear will be changed to match the order of options in this field.'),
'#states' => [
'visible' => [
':input[name="exposed_form_options[bef][sort][configuration][advanced][combine]"]' => [
'checked' => TRUE,
],
],
],
];
$form['advanced']['reset'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Include a "Reset sort" option'),
'#default_value' => !empty($this->configuration['advanced']['reset']),
'#description' => $this
->t('Adds a "Reset sort" link; Views will use the default sort order.'),
];
$form['advanced']['reset_label'] = [
'#type' => 'textfield',
'#title' => $this
->t('"Reset sort" label'),
'#default_value' => $this->configuration['advanced']['reset_label'],
'#description' => $this
->t('This cannot be left blank if the above option is checked'),
'#states' => [
'visible' => [
':input[name="exposed_form_options[bef][sort][configuration][advanced][reset]"]' => [
'checked' => TRUE,
],
],
'required' => [
':input[name="exposed_form_options[bef][sort][configuration][advanced][reset]"]' => [
'checked' => TRUE,
],
],
],
];
$form['advanced']['collapsible'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Make sort options collapsible'),
'#default_value' => !empty($this->configuration['advanced']['collapsible']),
'#description' => $this
->t('Puts the sort options in a collapsible details element.'),
];
$form['advanced']['collapsible_label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Collapsible details element title'),
'#default_value' => $this->configuration['advanced']['collapsible_label'],
'#description' => $this
->t('This cannot be left blank or there will be no way to show/hide sort options.'),
'#states' => [
'visible' => [
':input[name="exposed_form_options[bef][sort][configuration][advanced][collapsible]"]' => [
'checked' => TRUE,
],
],
'required' => [
':input[name="exposed_form_options[bef][sort][configuration][advanced][collapsible]"]' => [
'checked' => TRUE,
],
],
],
];
$form['advanced']['is_secondary'] = [
'#type' => 'checkbox',
'#title' => $this
->t('This is a secondary option'),
'#default_value' => !empty($this->configuration['advanced']['is_secondary']),
'#states' => [
'visible' => [
':input[name="exposed_form_options[bef][general][allow_secondary]"]' => [
'checked' => TRUE,
],
],
],
'#description' => $this
->t('Places this element in the secondary options portion of the exposed form.'),
];
return $form;
}
public function exposedFormAlter(array &$form, FormStateInterface $form_state) {
$is_collapsible = $this->configuration['advanced']['collapsible'] && !empty($this->configuration['advanced']['collapsible_label']);
$is_secondary = !empty($form['secondary']) && $this->configuration['advanced']['is_secondary'];
if ($this->configuration['advanced']['combine'] && !empty($form['sort_order'])) {
$options = [];
$selected = '';
foreach ($form['sort_by']['#options'] as $by_key => $by_val) {
foreach ($form['sort_order']['#options'] as $order_key => $order_val) {
$options[$by_key . '_' . $order_key] = "{$by_val} {$order_val}";
if ($form['sort_order']['#default_value'] === $order_key && empty($selected)) {
$selected = $by_key . '_' . $order_key;
}
}
}
if (!empty($this->configuration['advanced']['combine_rewrite'])) {
$options = BetterExposedFiltersHelper::rewriteOptions($options, $this->configuration['advanced']['combine_rewrite'], TRUE);
if (!isset($options[$selected])) {
$selected = NULL;
}
}
if ($this->configuration['advanced']['reset']) {
$options = [
' ' => $this->configuration['advanced']['reset_label'],
] + $options;
}
$form['sort_bef_combine'] = [
'#type' => 'select',
'#options' => $options,
'#default_value' => $selected,
'#title' => $form['sort_by']['#title'],
];
$form['#submit'][] = [
$this,
'sortCombineSubmitForm',
];
$form['#info']['sort-sort_bef_combine'] = [
'value' => 'sort_bef_combine',
];
unset($form['sort_by']);
unset($form['sort_order']);
}
else {
if ($this->configuration['advanced']['reset']) {
array_unshift($form['sort_by']['#options'], $this->configuration['advanced']['reset_label']);
}
}
if ($is_collapsible) {
$form['bef_sort_options'] = [
'#type' => 'details',
'#title' => $this->configuration['advanced']['collapsible_label'],
];
if ($is_secondary) {
$form['bef_sort_options']['#group'] = 'secondary';
}
}
foreach ($this->sortElements as $element) {
if (empty($form[$element])) {
continue;
}
if ($is_collapsible) {
$this
->addElementToGroup($form, $form_state, $element, 'bef_sort_options');
}
elseif ($is_secondary) {
$this
->addElementToGroup($form, $form_state, $element, 'secondary');
}
$this
->addContext($form[$element]);
}
}
public function sortCombineSubmitForm(array $form, FormStateInterface $form_state) {
$sort_by = $sort_order = '';
$combined = $form_state
->getValue('sort_bef_combine');
if (!empty($combined)) {
$parts = explode('_', $combined);
$sort_order = trim(array_pop($parts));
$sort_by = trim(implode('_', $parts));
}
$form_state
->setValue('sort_by', $sort_by);
$form_state
->setValue('sort_order', $sort_order);
}
}