View source
<?php
namespace Drupal\entity_reference_exposed_filters\Plugin\views\filter;
use Drupal\field\Entity\FieldConfig;
use Drupal\views\Plugin\views\display\DisplayPluginBase;
use Drupal\views\Plugin\views\filter\ManyToOne;
use Drupal\views\ViewExecutable;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
use Drupal\Component\Plugin\PluginInspectionInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class EREFNodeTitles extends ManyToOne implements PluginInspectionInterface, ContainerFactoryPluginInterface {
use StringTranslationTrait;
private $sortByOptions;
private $sortOrderOptions;
private $sortBundleOrder;
private $getUnpublishedOptions;
private $getFilterNoResultsOptions;
private $getRelationships;
protected $entityTypeManager;
protected $Connection;
protected $entityFieldManager;
protected $entityTypeBundleInfo;
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, Connection $connection, EntityFieldManagerInterface $entity_field_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->Connection = $connection;
$this->entityFieldManager = $entity_field_manager;
$this->entityTypeBundleInfo = $entity_type_bundle_info;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'), $container
->get('database'), $container
->get('entity_field.manager'), $container
->get('entity_type.bundle.info'));
}
public function validate() {
if (empty($this->getRelationships)) {
$this
->broken();
}
}
public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
parent::init($view, $display, $options);
$this->getRelationships = $this->view
->getHandlers('relationship');
if ($this->getRelationships === NULL) {
$this->getRelationships = [];
}
$invalid_relationships = [
'cid',
'comment_cid',
'last_comment_uid',
'uid',
'vid',
'nid',
];
foreach ($this->getRelationships as $key => $relationship) {
$is_target = strpos($relationship['id'], 'target_id');
if ($relationship['plugin_id'] != 'standard' || in_array($key, $invalid_relationships) || $is_target !== FALSE) {
unset($this->getRelationships[$key]);
}
}
$this->sortByOptions = [
'nid',
'title',
];
$this->sortOrderOptions = [
'DESC',
'ASC',
];
$this->sortBundleOrder = [
'DESC',
'ASC',
];
$this->getUnpublishedOptions = [
'Unpublished',
'Published',
'All',
];
$this->getFilterNoResultsOptions = [
'Yes',
"No",
];
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
if (!isset($this->options['expose']['identifier'])) {
$this->options['expose']['identifier'] = $form_state
->get('id');
}
parent::buildOptionsForm($form, $form_state);
$form['relationship']['#options'] = array_intersect_key($form['relationship']['#options'], $this->getRelationships);
}
public function hasExtraOptions() {
return TRUE;
}
public function buildExtraOptionsForm(&$form, FormStateInterface $form_state) {
$form['sort_by'] = [
'#type' => 'radios',
'#title' => $this
->t('Sort by'),
'#default_value' => $this->options['sort_by'],
'#options' => $this->sortByOptions,
'#description' => $this
->t('On what attribute do you want to sort the node titles?'),
'#required' => TRUE,
];
$form['sort_order'] = [
'#type' => 'radios',
'#title' => $this
->t('Sort by'),
'#default_value' => $this->options['sort_order'],
'#options' => $this->sortOrderOptions,
'#description' => $this
->t('In what order do you want to sort the node titles?'),
'#required' => TRUE,
];
$form['sort_bundle_order'] = [
'#type' => 'radios',
'#title' => $this
->t('Sort bundles'),
'#default_value' => $this->options['sort_bundle_order'],
'#options' => $this->sortOrderOptions,
'#description' => $this
->t('In what order do you want to sort the node bundles? (only relevant if there are multiple)'),
'#required' => TRUE,
];
$form['get_unpublished'] = [
'#type' => 'radios',
'#title' => $this
->t('Published Status'),
'#default_value' => $this->options['get_unpublished'],
'#options' => $this->getUnpublishedOptions,
'#description' => $this
->t('Do you want Published, Unpublished or All?'),
'#required' => TRUE,
];
$form['get_filter_no_results'] = [
'#type' => 'radios',
'#title' => $this
->t('Filter Out Options With No Results'),
'#default_value' => $this->options['get_filter_no_results'],
'#options' => $this->getFilterNoResultsOptions,
'#description' => $this
->t('Do you want to filter out options that will give no results?'),
'#required' => TRUE,
];
}
public function submitExtraOptionsForm($form, FormStateInterface $form_state) {
$this
->defineOptions();
$this
->generateOptions();
}
public function valueForm(&$form, FormStateInterface $form_state) {
parent::valueForm($form, $form_state);
$form['reduce_duplicates']['#default_value'] = 0;
$form['reduce_duplicates'] = [
'#disabled' => TRUE,
];
unset($form['relationship']['#options']['none']);
$form['expose_button'] = [
'#disabled' => TRUE,
];
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['exposed'] = [
'default' => 1,
];
if (isset($this->getRelationships)) {
$relationship_field_names = array_keys($this->getRelationships);
$options['relationship'] = [
'default' => $relationship_field_names[0],
$this->getRelationships,
];
$options['sort_order'] = [
'default' => 0,
];
$options['sort_by'] = [
'default' => 1,
];
$options['get_unpublished'] = [
'default' => 1,
];
$options['get_filter_no_results'] = [
'default' => 1,
];
}
return $options;
}
public function getValueOptions() {
$this->valueOptions = $this
->generateOptions();
return $this->valueOptions;
}
public function generateOptions() {
$res = [];
$relationships = $this->getRelationships;
$relationship_fields = array_keys($relationships);
if (!empty($relationships) && isset($relationship_fields[0])) {
$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 {
$relationship_field_name = $relationship_fields[0];
}
$entity_type_id = explode('__', $relationships[$relationship_field_name]['table'])[0];
$all_bundles = $this->entityTypeBundleInfo
->getBundleInfo($entity_type_id);
if (empty($all_bundles)) {
$entity_type_id = rtrim($entity_type_id, '_revision');
$all_bundles = $this->entityTypeBundleInfo
->getBundleInfo($entity_type_id);
}
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'));
if (in_array('views', $target_entity_type_id)) {
$target_entity_type_id = [
'default',
$entity_type_id,
];
}
if ($target_entity_type_id[0] == 'default') {
$target_entity_type_id = $target_entity_type_id[1];
}
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 [];
}
foreach (array_keys($field_obj
->getSetting('handler_settings')['target_bundles']) as $bundle) {
$target_bundles[] = $bundle;
}
$bundles_needed[] = $bundle;
$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,
];
}
}
}
$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']]);
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']]);
$relatedContentIds = $relatedContentQuery
->execute();
if (empty($relatedContentIds)) {
return [];
}
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));
$relatedContentIds = array_intersect($relatedContentIds, $ids_w_content);
}
foreach ($relatedContentIds as $contentId) {
$res[$contentId] = \Drupal::service('entity.repository')
->getTranslationFromContext($get_entity
->load($contentId))
->getTitle();
}
}
return $res;
}
}