commit
091e2995d4
9 changed files with 552 additions and 0 deletions
@ -0,0 +1,6 @@ |
|||||||
|
services: |
||||||
|
islandora_batch_action.commands: |
||||||
|
class: Drupal\islandora_batch_action\Commands\BatchActionCommands |
||||||
|
arguments: ['@entity_type.manager', '@database'] |
||||||
|
tags: |
||||||
|
- { name: drush.command } |
||||||
@ -0,0 +1,5 @@ |
|||||||
|
name: Islandora Batch Action |
||||||
|
description: Provides a Drush command to run a batch action on a list of nodes. |
||||||
|
package: Custom |
||||||
|
type: module |
||||||
|
core_version_requirement: ^8 || ^9 || ^10 |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
islandora_batch_action_create_media: |
||||||
|
title: 'Add missing derivatives' |
||||||
|
description: 'Add missing media by Media use and node Model' |
||||||
|
route_name: islandora_batch_action.missing_derivatives_fm |
||||||
|
parent: system.admin_config_media |
||||||
|
menu_name: administration |
||||||
|
weight: 10 |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
islandora_batch_action.missing_derivatives_fm: |
||||||
|
path: '/islandora-batch-action/missing-derivatives-fm' |
||||||
|
defaults: |
||||||
|
_title: 'Missing Derivatives' |
||||||
|
_form: 'Drupal\islandora_batch_action\Form\MissingDerivativesFm' |
||||||
|
requirements: |
||||||
|
_permission: 'administer media' |
||||||
@ -0,0 +1,14 @@ |
|||||||
|
services: |
||||||
|
islandora_batch_action.commands: |
||||||
|
class: Drupal\islandora_batch_action\Commands\BatchActionCommands |
||||||
|
arguments: ['@entity_type.manager'] |
||||||
|
tags: |
||||||
|
- { name: drush.command } |
||||||
|
|
||||||
|
islandora_batch_action.utils: |
||||||
|
class: Drupal\islandora_batch_action\IslandoraBatchActionUtils |
||||||
|
arguments: ['@database', '@entity_type.manager', '@logger.channel.islandora', '@islandora.utils'] |
||||||
|
|
||||||
|
islandora_batch_action.node_action_batch: |
||||||
|
class: 'Drupal\islandora_batch_action\Batch\NodeActionBatch' |
||||||
|
arguments: ['@entity_type.manager', '@plugin.manager.action'] |
||||||
@ -0,0 +1,76 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Drupal\islandora_batch_action\Batch; |
||||||
|
|
||||||
|
use Drupal\Core\Batch\BatchBuilder; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides a batch job to perform a Drupal Action on a list of node IDs. |
||||||
|
*/ |
||||||
|
final class NodeActionBatch { |
||||||
|
|
||||||
|
/** |
||||||
|
* Executes the batch job. |
||||||
|
* |
||||||
|
* @param array $node_ids |
||||||
|
* An array of node IDs. |
||||||
|
* @param string $action_id |
||||||
|
* The action plugin ID to perform on each node. |
||||||
|
*/ |
||||||
|
public function run(array $node_ids, string $action_id): void { |
||||||
|
$batch_builder = new BatchBuilder(); |
||||||
|
|
||||||
|
$batch_builder->setTitle(t('Performing batch action on nodes.')) |
||||||
|
->setInitMessage(t('Starting the batch action.')) |
||||||
|
->setProgressMessage(t('Processing @current out of @total.')) |
||||||
|
->setErrorMessage(t('An error occurred.')); |
||||||
|
|
||||||
|
// Register the operation for each node. |
||||||
|
foreach ($node_ids as $node_id) { |
||||||
|
$batch_builder->addOperation([__CLASS__, 'processNode'], [$node_id, $action_id]); |
||||||
|
} |
||||||
|
|
||||||
|
batch_set($batch_builder->toArray()); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes an individual node for the batch operation. |
||||||
|
* |
||||||
|
* @param int $node_id |
||||||
|
* The node ID to process. |
||||||
|
* @param string $action_id |
||||||
|
* The action plugin ID. |
||||||
|
* @param array $context |
||||||
|
* The batch context array. |
||||||
|
*/ |
||||||
|
public static function processNode(int $node_id, string $action_id, array &$context): void { |
||||||
|
$entityTypeManager = \Drupal::service('entity_type.manager'); |
||||||
|
$node = $entityTypeManager->getStorage('node')->load($node_id); |
||||||
|
if (!$node) { |
||||||
|
$context['results']['failed'][] = $node_id; |
||||||
|
return; |
||||||
|
} |
||||||
|
$action_storage = $entityTypeManager->getStorage('action'); |
||||||
|
$configured_action = $action_storage->load($action_id); |
||||||
|
|
||||||
|
if (!$configured_action) { |
||||||
|
$context['results']['failed'][] = $node_id; |
||||||
|
return; |
||||||
|
} |
||||||
|
try { |
||||||
|
$configured_action->execute([$node]); |
||||||
|
$context['results']['processed'][] = $node_id; |
||||||
|
} |
||||||
|
catch (\Exception $e) { |
||||||
|
\Drupal::logger('islandora_batch_action')->error('Batch action failed for node @nid: @message', [ |
||||||
|
'@nid' => $node_id, |
||||||
|
'@message' => $e->getMessage(), |
||||||
|
]); |
||||||
|
$context['results']['failed'][] = $node_id; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,193 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
namespace Drupal\islandora_batch_action\Commands; |
||||||
|
|
||||||
|
use Drupal\node\Entity\Node; |
||||||
|
use Drush\Commands\DrushCommands; |
||||||
|
use Drupal\Core\Entity\EntityTypeManagerInterface; |
||||||
|
use Drupal\Core\Database\Connection; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides Drush commands for batch actions on nodes. |
||||||
|
*/ |
||||||
|
class BatchActionCommands extends DrushCommands { |
||||||
|
|
||||||
|
protected $entityTypeManager; |
||||||
|
protected $database; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructs the BatchActionCommands object. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager |
||||||
|
* The entity type manager service. |
||||||
|
* @param \Drupal\Core\Database\Connection $database |
||||||
|
* The database connection. |
||||||
|
*/ |
||||||
|
public function __construct(EntityTypeManagerInterface $entity_type_manager, Connection $database) { |
||||||
|
$this->entityTypeManager = $entity_type_manager; |
||||||
|
$this->database = $database; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Runs a batch action on a list of nodes. |
||||||
|
* |
||||||
|
* @command batch:action |
||||||
|
* @param string $action_id |
||||||
|
* The machine name of the action to run. |
||||||
|
* |
||||||
|
* @usage drush batch:action my_custom_action |
||||||
|
*/ |
||||||
|
public function runBatchAction($action_id) { |
||||||
|
$action = $this->entityTypeManager->getStorage("action")->load($action_id); |
||||||
|
|
||||||
|
if (!$action) { |
||||||
|
$this->logger()->error("Action not found: $action_id"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$node_ids = $this->generateNodeList(); |
||||||
|
|
||||||
|
if (empty($node_ids)) { |
||||||
|
$this->logger()->notice("No nodes found to process."); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
$batch = [ |
||||||
|
'title' => t('Running action on nodes'), |
||||||
|
'operations' => [], |
||||||
|
'finished' => [__CLASS__, 'batchFinished'], |
||||||
|
]; |
||||||
|
|
||||||
|
foreach ($node_ids as $nid) { |
||||||
|
$batch['operations'][] = [ |
||||||
|
[__CLASS__, 'processNode'], |
||||||
|
[$nid, $action_id], |
||||||
|
]; |
||||||
|
} |
||||||
|
|
||||||
|
batch_set($batch); |
||||||
|
drush_backend_batch_process(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates a list of node IDs that do not have 'Intermediate File' media. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* An array of node IDs. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates a list of node IDs that do not have 'Intermediate File' media |
||||||
|
* but have the model field set to 'Image'. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* An array of node IDs. |
||||||
|
*/ |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates a list of node IDs that do not have 'Intermediate File' media |
||||||
|
* but have the model field set to 'Image'. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* An array of node IDs. |
||||||
|
*/ |
||||||
|
protected function generateNodeList() { |
||||||
|
// Subquery to get the TID for the term 'Image'. |
||||||
|
$image_tid_query = $this->database->select('taxonomy_term_field_data', 't') |
||||||
|
->fields('t', ['tid']) |
||||||
|
->condition('t.name', 'Image') |
||||||
|
->condition('t.vid', 'islandora_models') |
||||||
|
->execute() |
||||||
|
->fetchField(); |
||||||
|
|
||||||
|
if (!$image_tid_query) { |
||||||
|
$this->logger()->error("Taxonomy term 'Image' not found."); |
||||||
|
return []; |
||||||
|
} |
||||||
|
$this->logger()->notice("Taxonomy term 'Image' is $image_tid_query."); |
||||||
|
// Subquery to get nids with 'Intermediate File' media. |
||||||
|
$subquery = $this->database->select('node', 'n') |
||||||
|
->fields('n', ['nid']); |
||||||
|
|
||||||
|
$subquery->innerJoin('media__field_media_of', 'mo', 'n.nid = mo.field_media_of_target_id'); |
||||||
|
$subquery->innerJoin('media__field_media_use', 'mu', 'mu.entity_id = mo.entity_id'); |
||||||
|
$subquery->innerJoin('taxonomy_term_field_data', 't', 'mu.field_media_use_target_id = t.tid'); |
||||||
|
$subquery->condition('t.name', 'Intermediate File'); |
||||||
|
|
||||||
|
// Main query to get all nids excluding the subquery result, |
||||||
|
// and where field_model_target_id is equal to the TID of 'Image' using EXISTS. |
||||||
|
$query = $this->database->select('node', 'n') |
||||||
|
->fields('n', ['nid']) |
||||||
|
->condition('n.nid', $subquery, 'NOT IN'); |
||||||
|
|
||||||
|
// Adding the EXISTS condition for field_model_target_id. |
||||||
|
$query->exists( |
||||||
|
$this->database->select('node__field_model', 'fm') |
||||||
|
->fields('fm', ['entity_id']) |
||||||
|
->condition('fm.entity_id', 'n.nid', '=') |
||||||
|
->condition('fm.field_model_target_id', $image_tid_query) |
||||||
|
); |
||||||
|
|
||||||
|
return $query->execute()->fetchCol(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Processes an individual node in the batch. |
||||||
|
* |
||||||
|
* @param int $nid |
||||||
|
* The node ID. |
||||||
|
* @param string $action_id |
||||||
|
* The action ID. |
||||||
|
* @param array $context |
||||||
|
* The batch context. |
||||||
|
*/ |
||||||
|
public static function processNode($nid, $action_id, array &$context) { |
||||||
|
$node = Node::load($nid); |
||||||
|
$action = \Drupal::entityTypeManager()->getStorage("action")->load($action_id); |
||||||
|
|
||||||
|
if (!$node) { |
||||||
|
$context['results']['errors'][] = "Node not found: $nid"; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
if (!$action) { |
||||||
|
$context['results']['errors'][] = "Action not found: $action_id"; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
try { |
||||||
|
$action->execute([$node]); |
||||||
|
$context['results']['processed'][] = "Processed action on node $nid"; |
||||||
|
} |
||||||
|
catch (\Exception $e) { |
||||||
|
$context['results']['errors'][] = "Error processing node $nid: " . $e->getMessage(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Callback for batch finished. |
||||||
|
* |
||||||
|
* @param bool $success |
||||||
|
* Whether the batch completed successfully. |
||||||
|
* @param array $results |
||||||
|
* An array of results. |
||||||
|
* @param array $operations |
||||||
|
* The list of operations. |
||||||
|
*/ |
||||||
|
public static function batchFinished($success, array $results, array $operations) { |
||||||
|
if ($success) { |
||||||
|
\Drupal::messenger()->addMessage("Batch process completed successfully."); |
||||||
|
|
||||||
|
if (!empty($results['processed'])) { |
||||||
|
\Drupal::messenger()->addMessage("Processed nodes: " . implode(', ', $results['processed'])); |
||||||
|
} |
||||||
|
if (!empty($results['errors'])) { |
||||||
|
\Drupal::messenger()->addError("Errors encountered: " . implode(', ', $results['errors'])); |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
\Drupal::messenger()->addError("Batch process encountered an error."); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,185 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Drupal\islandora_batch_action\Form; |
||||||
|
|
||||||
|
use Drupal\Core\Form\FormBase; |
||||||
|
use Drupal\Core\Form\FormStateInterface; |
||||||
|
use Drupal\Core\Entity\EntityTypeManagerInterface; |
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface; |
||||||
|
use Drupal\islandora_batch_action\IslandoraBatchActionUtils; |
||||||
|
use Drupal\islandora_batch_action\Batch\NodeActionBatch; |
||||||
|
use Drupal\Core\Action\ActionManager; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides a form for sending a message in Islandora Batch Action. |
||||||
|
*/ |
||||||
|
final class MissingDerivativesFm extends FormBase { |
||||||
|
|
||||||
|
/** |
||||||
|
* The entity type manager service. |
||||||
|
* |
||||||
|
* @var \Drupal\Core\Entity\EntityTypeManagerInterface |
||||||
|
*/ |
||||||
|
protected EntityTypeManagerInterface $entityTypeManager; |
||||||
|
|
||||||
|
/** |
||||||
|
* The Batch Action Utils service. |
||||||
|
* |
||||||
|
* @var \Drupal\islandora_batch_action\IslandoraBatchActionUtils |
||||||
|
*/ |
||||||
|
protected IslandoraBatchActionUtils $islandoraBatchActionUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* The batch job service. |
||||||
|
* |
||||||
|
* @var \Drupal\islandora_batch_action\Batch\NodeActionBatch |
||||||
|
*/ |
||||||
|
protected NodeActionBatch $batchJob; |
||||||
|
|
||||||
|
/** |
||||||
|
* The plugin manager for actions. |
||||||
|
* |
||||||
|
* @var \Drupal\Core\Action\ActionManager |
||||||
|
*/ |
||||||
|
protected ActionManager $actionPluginManager; |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructs the form object with dependency injection. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager |
||||||
|
* The entity type manager service. |
||||||
|
* @param \Drupal\islandora_batch_action\IslandoraBatchActionUtils $islandoraBatchActionUtils |
||||||
|
* The Batch Action utils. |
||||||
|
* @param \Drupal\islandora_batch_action\Batch\NodeActionBatch $batchJob |
||||||
|
* The batch job service. |
||||||
|
* @param \Drupal\Core\Action\ActionManager $actionPluginManager |
||||||
|
* The action plugin manager. |
||||||
|
*/ |
||||||
|
public function __construct( |
||||||
|
EntityTypeManagerInterface $entityTypeManager, |
||||||
|
IslandoraBatchActionUtils $islandoraBatchActionUtils, |
||||||
|
NodeActionBatch $batchJob, |
||||||
|
ActionManager $actionPluginManager) { |
||||||
|
$this->entityTypeManager = $entityTypeManager; |
||||||
|
$this->islandoraBatchActionUtils = $islandoraBatchActionUtils; |
||||||
|
$this->batchJob = $batchJob; |
||||||
|
$this->actionPluginManager = $actionPluginManager; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public static function create(ContainerInterface $container) { |
||||||
|
return new static( |
||||||
|
$container->get('entity_type.manager'), |
||||||
|
$container->get('islandora_batch_action.utils'), |
||||||
|
$container->get('islandora_batch_action.node_action_batch'), |
||||||
|
$container->get('plugin.manager.action'), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function getFormId(): string { |
||||||
|
return 'islandora_batch_action_missing_derivatives_fm'; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function buildForm(array $form, FormStateInterface $form_state): array { |
||||||
|
$actions = $this->getDerivativeActions(); |
||||||
|
$form['model'] = [ |
||||||
|
'#type' => 'select', |
||||||
|
'#title' => $this->t('Node Type'), |
||||||
|
'#options' => $this->getVocabularyOptions('islandora_models'), |
||||||
|
'#required' => TRUE, |
||||||
|
]; |
||||||
|
$form['usage'] = [ |
||||||
|
'#type' => 'select', |
||||||
|
'#title' => $this->t('Derivative Type'), |
||||||
|
'#options' => $this->getVocabularyOptions('islandora_media_use'), |
||||||
|
'#required' => TRUE, |
||||||
|
]; |
||||||
|
$form['actions_id'] = [ |
||||||
|
'#type' => 'select', |
||||||
|
'#title' => $this->t('Derivative Actions'), |
||||||
|
'#options' => $this->getDerivativeActions(), |
||||||
|
'#required' => TRUE, |
||||||
|
]; |
||||||
|
|
||||||
|
$form['actions'] = [ |
||||||
|
'#type' => 'actions', |
||||||
|
'submit' => [ |
||||||
|
'#type' => 'submit', |
||||||
|
'#value' => $this->t('Send'), |
||||||
|
], |
||||||
|
]; |
||||||
|
|
||||||
|
return $form; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* {@inheritdoc} |
||||||
|
*/ |
||||||
|
public function submitForm(array &$form, FormStateInterface $form_state): void { |
||||||
|
$model = $form_state->getValue('model'); |
||||||
|
$usage = $form_state->getValue('usage'); |
||||||
|
$action_id = $form_state->getValue('actions_id'); |
||||||
|
$nids = $this->islandoraBatchActionUtils->generateNodeList($model, $usage); |
||||||
|
if (empty($nids)) { |
||||||
|
$this->messenger()->addWarning($this->t('No nodes found for the selected model and usage.')); |
||||||
|
return; |
||||||
|
} |
||||||
|
$this->batchJob->run($nids, $action_id); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates an options array from a taxonomy vocabulary. |
||||||
|
* |
||||||
|
* @param string $vocabulary |
||||||
|
* The machine name of the taxonomy vocabulary. |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* An associative array of term IDs and term names. |
||||||
|
*/ |
||||||
|
public function getVocabularyOptions(string $vocabulary): array { |
||||||
|
$options = []; |
||||||
|
|
||||||
|
$terms = $this->entityTypeManager |
||||||
|
->getStorage('taxonomy_term') |
||||||
|
->loadTree($vocabulary); |
||||||
|
|
||||||
|
foreach ($terms as $term) { |
||||||
|
$options[$term->tid] = $term->name; |
||||||
|
} |
||||||
|
|
||||||
|
return $options; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* Gets filtered actions. |
||||||
|
*/ |
||||||
|
public function getDerivativeActions(): array { |
||||||
|
$options = []; |
||||||
|
$user_actions = $this->entityTypeManager |
||||||
|
->getStorage('action') |
||||||
|
->loadMultiple(); |
||||||
|
|
||||||
|
foreach ($user_actions as $action) { |
||||||
|
if ($action_plugin = $action->getPlugin()) { |
||||||
|
if (method_exists($action_plugin, 'getConfiguration')) { |
||||||
|
$config = $action_plugin->getConfiguration(); |
||||||
|
if (isset($config['event'])&& $config['event'] == 'Generate Derivative') { |
||||||
|
$options[$action->id()] = $action->label(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return $options; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
<?php |
||||||
|
|
||||||
|
declare(strict_types=1); |
||||||
|
|
||||||
|
namespace Drupal\islandora_batch_action; |
||||||
|
|
||||||
|
use Drupal\Core\Database\Connection; |
||||||
|
use Drupal\Core\Entity\EntityTypeManagerInterface; |
||||||
|
use Drupal\Core\Logger\LoggerChannelInterface; |
||||||
|
|
||||||
|
/** |
||||||
|
* Provides utility functions for bulk derivative actions in Islandora. |
||||||
|
*/ |
||||||
|
final class IslandoraBatchActionUtils { |
||||||
|
|
||||||
|
/** |
||||||
|
* Constructs an IslandoraBatchActionUtils object. |
||||||
|
* |
||||||
|
* @param \Drupal\Core\Database\Connection $connection |
||||||
|
* The database connection service. |
||||||
|
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager |
||||||
|
* The entity type manager service. |
||||||
|
* @param \Drupal\Core\Logger\LoggerChannelInterface $loggerChannelIslandora |
||||||
|
* The logger channel for Islandora. |
||||||
|
*/ |
||||||
|
public function __construct( |
||||||
|
private readonly Connection $connection, |
||||||
|
private readonly EntityTypeManagerInterface $entityTypeManager, |
||||||
|
private readonly LoggerChannelInterface $loggerChannelIslandora, |
||||||
|
) {} |
||||||
|
|
||||||
|
/** |
||||||
|
* Generates a list of node IDs without the specified media type. |
||||||
|
* |
||||||
|
* @param string $model_tid |
||||||
|
* The taxonomy term ID of the model (e.g., Image). |
||||||
|
* @param string $media_use_tid |
||||||
|
* The taxonomy term ID of the media use type (e.g., Intermediate File). |
||||||
|
* |
||||||
|
* @return array |
||||||
|
* Array of node IDs that match the model type but exclude the media type. |
||||||
|
*/ |
||||||
|
public function generateNodeList(string $model_tid, string $media_use_tid): array { |
||||||
|
// Subquery to get NIDs with the specified media type. |
||||||
|
$mediaQuery = $this->connection->select('media__field_media_of', 'mo'); |
||||||
|
$mediaQuery->fields('mo', ['field_media_of_target_id']); |
||||||
|
$mediaQuery->innerJoin('media__field_media_use', 'mu', 'mu.entity_id = mo.entity_id'); |
||||||
|
$mediaQuery->condition('mu.field_media_use_target_id', $media_use_tid); |
||||||
|
|
||||||
|
// Query to get NIDs of the specified model, excluding those in subquery. |
||||||
|
$mainQuery = $this->connection->select('node', 'n'); |
||||||
|
$mainQuery->fields('n', ['nid']); |
||||||
|
$mainQuery->innerJoin('node__field_model', 'fm', 'n.nid = fm.entity_id'); |
||||||
|
$mainQuery->condition('fm.field_model_target_id', $model_tid); |
||||||
|
$mainQuery->condition('n.nid', $mediaQuery, 'NOT IN'); |
||||||
|
return $mainQuery->execute()->fetchCol(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
Loading…
Reference in new issue