diff --git a/views/src/Plugin/views/filter/EntityReference.php b/views/src/Plugin/views/filter/EntityReference.php index fb98612..ede7726 100644 --- a/views/src/Plugin/views/filter/EntityReference.php +++ b/views/src/Plugin/views/filter/EntityReference.php @@ -108,9 +108,63 @@ class EntityReference extends ManyToOne { '#options' => $bundle_options, '#default_value' => $this->options['target_bundles'], '#required' => TRUE, + '#ajax' => [ + 'callback' => 'Drupal\views\Plugin\views\filter\EntityReference::ajaxSortCallback', + 'wrapper' => 'sort-field', + ], ]; } + $target_bundles = $form_state->getValue(['options', 'target_bundles']); + if (empty($target_bundles)) { + // Fallback to default target bundles. + $target_bundles = $this->options['target_bundles']; + } + + $bundle_fields = []; + if (isset($target_bundles)) { + $bundle_fields = ['_none' => "- None -"]; + $sortable_field_types = ['integer', 'timestamp', 'string']; + + // Let other modules to alter the field types. + $alter_id = 'views_filter_entityreference_sortable_field_types'; + \Drupal::moduleHandler()->alter($alter_id, $sortable_field_types); + + // Get the sortable bundle fields. + foreach ($target_bundles as $bundle) { + if ($bundle !== 0) { + $fields_definitions = \Drupal::service('entity_field.manager') + ->getFieldDefinitions('node', $bundle); + foreach ($fields_definitions as $field_id => $field_definition) { + if (in_array($field_definition->getType(), $sortable_field_types)) { + $bundle_fields[$field_id] = $field_definition->getLabel(); + } + } + } + } + } + ksort($bundle_fields); + + $form['sort_field'] = [ + '#type' => 'select', + '#title' => 'Sort field', + '#options' => $bundle_fields, + '#default_value' => $this->options['sort_field'], + '#prefix' => '
', + '#suffix' => '
', + ]; + + $form['direction'] = [ + '#type' => 'select', + '#title' => 'Direction', + '#options' => [ + 'ASC' => 'ASC', + 'DESC' => 'DESC' + ], + '#default_value' => $this->options['direction'], + ]; + + $form['type'] = [ '#type' => 'radios', '#title' => $this->t('Selection type'), @@ -123,6 +177,21 @@ class EntityReference extends ManyToOne { } /** + * Ajax callback for sorting options. + * + * @param array $form + * From render array. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * Current state of form. + * + * @return array + * Color selection section of the form. + */ + public function ajaxSortCallback(array &$form, FormStateInterface $form_state) { + return $form['options']['sort_field']; + } + + /** * {@inheritdoc} */ public function validateExtraOptionsForm($form, FormStateInterface $form_state) { @@ -156,12 +225,12 @@ class EntityReference extends ManyToOne { } $form['value'] = array( - '#title' => $this->t('Select %entity_types', ['%entity_types' => $referenced_type->getPluralLabel()]), - '#type' => 'entity_autocomplete', - '#default_value' => EntityAutocomplete::getEntityLabels($entities), - '#tags' => TRUE, - '#process_default_value' => FALSE, - ) + $this->getHandlerOptions(); + '#title' => $this->t('Select %entity_types', ['%entity_types' => $referenced_type->getPluralLabel()]), + '#type' => 'entity_autocomplete', + '#default_value' => EntityAutocomplete::getEntityLabels($entities), + '#tags' => TRUE, + '#process_default_value' => FALSE, + ) + $this->getHandlerOptions(); } else { $entities = $this->selectionPluginManager->getInstance($this->getHandlerOptions())->getReferenceableEntities(); @@ -329,7 +398,8 @@ class EntityReference extends ManyToOne { $referenced_bundles = $this->getReferencedBundles(); $options['type'] = ['default' => self::AUTO_COMPLETE_TYPE]; $options['target_bundles'] = ['default' => array_combine($referenced_bundles, $referenced_bundles)]; - $options['sort'] = ['default' => []]; + $options['direction'] = ['default' => 'ASC']; + $options['sort_field'] = ['default' => '_none']; return $options; } @@ -383,7 +453,12 @@ class EntityReference extends ManyToOne { $options = [ $prefix . 'target_type' => $this->getReferencedEntityType()->id(), - $settings_key => ['sort' => $this->options['sort']], + $settings_key => [ + 'sort' => [ + 'field' => $this->options['sort_field'], + 'direction' => $this->options['direction'], + ] + ] ]; // Some entities don't have bundles. Appending an empty array to the diff --git a/views/views.api.php b/views/views.api.php index c21b9c5..5399316 100644 --- a/views/views.api.php +++ b/views/views.api.php @@ -1262,6 +1262,21 @@ function hook_views_plugins_sort_alter(array &$plugins) { } /** + * Modify the list of sortable field types. + * + * This hook may be used to modify the field types defining the sortable fields. + * + * @param array $sortable_field_types + * An array of field types. + * + * @see \Drupal\views\Plugin\ViewsHandlerManager + */ +function hook_views_filter_entityreference_sortable_field_types_alter($sortable_field_types) { + // Do not sort by fields, type of timestamp. + unset($sortable_field_types['timestamp']); +} + +/** * @} End of "addtogroup hooks". */