From b8f0b9c96601d952d69a7e067ac614568d78154c Mon Sep 17 00:00:00 2001 From: Rosie Le Faive Date: Thu, 16 May 2024 17:12:26 -0300 Subject: [PATCH] Allow NodeHasMediaUse view filter to work on views with node relationships. (#1010) * Adjust addition of where clause. * Bit of other paranoia with aliases. * Dependency injection in NodeHasMediaUse views filter. --------- Co-authored-by: Adam Vessey --- src/Plugin/views/filter/NodeHasMediaUse.php | 74 +++++++++++++++++---- 1 file changed, 62 insertions(+), 12 deletions(-) diff --git a/src/Plugin/views/filter/NodeHasMediaUse.php b/src/Plugin/views/filter/NodeHasMediaUse.php index 3c69bddd5..1686c4217 100644 --- a/src/Plugin/views/filter/NodeHasMediaUse.php +++ b/src/Plugin/views/filter/NodeHasMediaUse.php @@ -2,8 +2,13 @@ namespace Drupal\islandora\Plugin\views\filter; +use Drupal\Core\Database\Connection; +use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; +use Drupal\islandora\IslandoraUtils; use Drupal\views\Plugin\views\filter\FilterPluginBase; +use Psr\Log\LoggerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Views Filter on Having Media of a Type. @@ -14,6 +19,48 @@ */ class NodeHasMediaUse extends FilterPluginBase { + /** + * Islandora's utility service. + * + * @var \Drupal\islandora\IslandoraUtils + */ + protected IslandoraUtils $utils; + + /** + * Drupal's entity type manager service. + * + * @var \Drupal\Core\Entity\EntityTypeManagerInterface + */ + protected EntityTypeManagerInterface $entityTypeManager; + + /** + * Drupal's database connection service. + * + * @var \Drupal\Core\Database\Connection + */ + protected Connection $connection; + + /** + * Logger service. + * + * @var \Psr\Log\LoggerInterface + */ + protected LoggerInterface $logger; + + /** + * {@inheritDoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition); + + $instance->utils = $container->get('islandora.utils'); + $instance->entityTypeManager = $container->get('entity_type.manager'); + $instance->connection = $container->get('database'); + $instance->logger = $container->get('logger.factory')->get('islanodra'); + + return $instance; + } + /** * {@inheritdoc} */ @@ -29,7 +76,7 @@ protected function defineOptions() { */ public function validateOptionsForm(&$form, FormStateInterface $form_state) { $uri = $form_state->getValues()['options']['use_uri']; - $term = \Drupal::service('islandora.utils')->getTermForUri($uri); + $term = $this->utils->getTermForUri($uri); if (empty($term)) { $form_state->setError($form['use_uri'], $this->t('Could not find term with URI: "%uri"', ['%uri' => $uri])); } @@ -39,7 +86,7 @@ public function validateOptionsForm(&$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { - $terms = \Drupal::entityTypeManager()->getStorage('taxonomy_term')->loadByProperties(['vid' => 'islandora_media_use']); + $terms = $this->entityTypeManager->getStorage('taxonomy_term')->loadByProperties(['vid' => 'islandora_media_use']); $uris = []; foreach ($terms as $term) { foreach ($term->get('field_external_uri')->getValue() as $uri) { @@ -67,7 +114,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { */ public function adminSummary() { $operator = ($this->options['negated']) ? "does not have" : "has"; - $term = \Drupal::service('islandora.utils')->getTermForUri($this->options['use_uri']); + $term = $this->utils->getTermForUri($this->options['use_uri']); $label = (empty($term)) ? 'BROKEN TERM URI' : $term->label(); return "Node {$operator} a '{$label}' media"; } @@ -77,18 +124,21 @@ public function adminSummary() { */ public function query() { $condition = ($this->options['negated']) ? 'NOT IN' : 'IN'; - $utils = \Drupal::service('islandora.utils'); - $term = $utils->getTermForUri($this->options['use_uri']); + $term = $this->utils->getTermForUri($this->options['use_uri']); if (empty($term)) { - \Drupal::logger('islandora')->warning('Node Has Media Filter could not find term with URI: "%uri"', ['%uri' => $this->options['use_uri']]); + $this->logger->warning('Node Has Media Filter could not find term with URI: "%uri"', ['%uri' => $this->options['use_uri']]); return; } - $sub_query = \Drupal::database()->select('media', 'm'); - $sub_query->join('media__field_media_use', 'use', 'm.mid = use.entity_id'); - $sub_query->join('media__field_media_of', 'of', 'm.mid = of.entity_id'); - $sub_query->fields('of', ['field_media_of_target_id']) - ->condition('use.field_media_use_target_id', $term->id()); - $this->query->addWhere(0, 'nid', $sub_query, $condition); + $sub_query = $this->connection->select('media', 'm'); + $use_alias = $sub_query->join('media__field_media_use', 'use', 'm.mid = %alias.entity_id'); + $of_alias = $sub_query->join('media__field_media_of', 'of', 'm.mid = %alias.entity_id'); + $sub_query->fields($of_alias, ['field_media_of_target_id']) + ->condition("{$use_alias}.field_media_use_target_id", $term->id()); + + /** @var \Drupal\views\Plugin\views\query\Sql $query */ + $query = $this->query; + $alias = $query->ensureTable('node_field_data', $this->relationship); + $query->addWhere(0, "{$alias}.nid", $sub_query, $condition); } }