You are here

public function EREFNodeTitles::generateOptions in Entity Reference Exposed Filters 8

Helper function that generates the options.

2 calls to EREFNodeTitles::generateOptions()
EREFNodeTitles::getValueOptions in src/Plugin/views/filter/EREFNodeTitles.php
Child classes should be used to override this function and set the 'value options', unless 'options callback' is defined as a valid function or static public method to generate these values.
EREFNodeTitles::submitExtraOptionsForm in src/Plugin/views/filter/EREFNodeTitles.php
Perform any necessary changes to the form values prior to storage. There is no need for this function to actually store the data.

File

src/Plugin/views/filter/EREFNodeTitles.php, line 300

Class

EREFNodeTitles
Filters by given list of related content title options.

Namespace

Drupal\entity_reference_exposed_filters\Plugin\views\filter

Code

public function generateOptions() {
  $res = [];
  $relationships = $this->getRelationships;
  $relationship_fields = array_keys($relationships);
  if (!empty($relationships) && isset($relationship_fields[0])) {

    // Get the relationship of this Views handler
    $relationship = $this->view
      ->getHandler($this->view->current_display, 'filter', $this->options['id']);
    if (isset($relationship['relationship']) && $relationship['relationship'] != 'none') {
      $relationship_field_name = $relationship['relationship'];
    }
    else {

      // We need this as a default.
      $relationship_field_name = $relationship_fields[0];
    }

    // Get the base view. we need it for bundle info and field defs.
    $entity_type_id = explode('__', $relationships[$relationship_field_name]['table'])[0];

    // Get bundles from a field name.
    $all_bundles = $this->entityTypeBundleInfo
      ->getBundleInfo($entity_type_id);

    // If that didn't work, attempt again as an entity revision reference table
    if (empty($all_bundles)) {
      $entity_type_id = rtrim($entity_type_id, '_revision');
      $all_bundles = $this->entityTypeBundleInfo
        ->getBundleInfo($entity_type_id);
    }

    // Run through the bundles.
    foreach (array_keys($all_bundles) as $bundle) {
      foreach ($this->entityFieldManager
        ->getFieldDefinitions($entity_type_id, $bundle) as $field_definition) {
        if ($field_definition
          ->getType() == 'entity_reference' && $field_definition
          ->getName() == $relationship_field_name) {
          if ($field_definition
            ->getName() == 'uid') {
            continue;
          }
          $field_obj = FieldConfig::loadByName($entity_type_id, $bundle, $field_definition
            ->getName());
          $target_entity_type_id = explode(':', $field_obj
            ->getSetting('handler'));

          // Convert an entity reference view to node or user.
          if (in_array('views', $target_entity_type_id)) {
            $target_entity_type_id = [
              'default',
              $entity_type_id,
            ];
          }

          // Will tell us node, user etc.
          if ($target_entity_type_id[0] == 'default') {
            $target_entity_type_id = $target_entity_type_id[1];
          }

          // Filter out entity reference views.
          if (($handler_settings = $field_obj
            ->getSetting('handler_settings')) && !empty($handler_settings['view'])) {
            \Drupal::messenger()
              ->addError($this
              ->t('This is targeting a field filtered by a view. Cannot get bundle.'), 'error');
            \Drupal::messenger()
              ->addError($this
              ->t('Please use a field filtered by content type only.'), 'error');
            return [];
          }

          // Get all the targets (content types etc) that this might hit.
          foreach (array_keys($field_obj
            ->getSetting('handler_settings')['target_bundles']) as $bundle) {
            $target_bundles[] = $bundle;
          }
          $bundles_needed[] = $bundle;

          // Get the options together.
          $gen_options = [];
          $gen_options = [
            'field' => $field_definition
              ->getName(),
            'entity_type_id' => $entity_type_id,
            'bundle' => $bundles_needed,
            'target_entity_type_id' => $target_entity_type_id,
            'target_bundles' => $target_bundles,
          ];
        }
      }
    }

    // Run the query.
    $get_entity = $this->entityTypeManager
      ->getStorage($gen_options['target_entity_type_id']);
    $relatedContentQuery = $this->entityTypeManager
      ->getStorage($gen_options['target_entity_type_id'])
      ->getQuery()
      ->condition('type', $gen_options['target_bundles'], 'IN')
      ->sort('type', $this->sortBundleOrder[$this->options['sort_bundle_order']]);

    // Leave this for any debugging ->sort('title', 'ASC');.
    if ($this->options['get_unpublished'] != 2) {
      $relatedContentQuery
        ->condition('status', $this->options['get_unpublished']);
    }
    $relatedContentQuery
      ->sort($this->sortByOptions[$this->options['sort_by']], $this->sortOrderOptions[$this->options['sort_order']]);

    // Returns an array of node ID's.
    $relatedContentIds = $relatedContentQuery
      ->execute();
    if (empty($relatedContentIds)) {
      return [];
    }

    // Remove empty options if desired.
    if ($this->options['get_filter_no_results'] == 0) {
      $db = $this->Connection;
      $query = $db
        ->select($entity_type_id . '__' . $relationship_field_name, 'x')
        ->fields('x', [
        $relationship_field_name . '_target_id',
      ])
        ->condition('x.' . $relationship_field_name . '_target_id', $relatedContentIds, 'IN');
      $ids_w_content = array_unique($query
        ->execute()
        ->fetchAll(\PDO::FETCH_COLUMN));

      // Keep the sort order of the original query.
      $relatedContentIds = array_intersect($relatedContentIds, $ids_w_content);
    }

    // Get the titles.
    foreach ($relatedContentIds as $contentId) {

      // Building an array with nid as key and title as value.
      $res[$contentId] = \Drupal::service('entity.repository')
        ->getTranslationFromContext($get_entity
        ->load($contentId))
        ->getTitle();
    }
  }
  return $res;
}