Skip to content

Instantly share code, notes, and snippets.

@DonRichards
Forked from seth-shaw-unlv/generate-image-derivatives.php
Last active July 17, 2024 16:18
Show Gist options
  • Save DonRichards/cc6025eced330c325b4af96a15bf2cb4 to your computer and use it in GitHub Desktop.
Save DonRichards/cc6025eced330c325b4af96a15bf2cb4 to your computer and use it in GitHub Desktop.
Islandora script for triggering new derivatives (tested on isle-dc and production)

This script adds the ability to use drush to generate missing derivatives. This looks for nodes without a service file (the hint that a derivative wasn't generated) and triggers the derivative actions.

Note: that drush commands that trigger actions should also specify the site url. E.g. drush -l https://islandora.traefik.me scr /var/www/drupal/vendor/drush/drush/src/Utils/generate-image-derivatives.php. Otherwise the messages alpaca receives includes paths like "default/node//media/add/" and it doesn't know what to do with that. I should have mentioned that before.

How to run this script

Super Fast method to run

wget https://gist.githubusercontent.com/DonRichards/cc6025eced330c325b4af96a15bf2cb4/raw/1f6f84b61d76ebf63ab9b148ae45c010f13d58ec/generate-image-derivatives.php

chmod +x generate-image-derivatives.php
chmod 755 generate-image-derivatives.php
chown nginx: generate-image-derivatives.php

mv generate-image-derivatives.php /var/www/drupal/vendor/drush/drush/src/Utils/generate-image-derivatives.php

drush -l https://islandora.traefik.me scr /var/www/drupal/vendor/drush/drush/src/Utils/generate-image-derivatives.php

Recap of the modifications made from the original script:

  1. Added accessCheck(FALSE) to entity queries:

    • For taxonomy_term entity queries, the accessCheck(FALSE) method was added to explicitly disable access checking.
    $original_tid = reset(
        \Drupal::entityQuery('taxonomy_term')
          ->condition('field_external_uri', 'http://pcdm.org/use#OriginalFile')
          ->accessCheck(FALSE)
          ->execute()
    );
    
    $intermediate_tid = reset(
        \Drupal::entityQuery('taxonomy_term')
          ->condition('field_external_uri', 'http://pcdm.org/use#IntermediateFile')
          ->accessCheck(FALSE)
          ->execute()
    );
    
    $service_tid = reset(
        \Drupal::entityQuery('taxonomy_term')
          ->condition('field_external_uri', 'http://pcdm.org/use#ServiceFile')
          ->accessCheck(FALSE)
          ->execute()
    );
  2. Added a check to ensure the node is loaded before calling methods on it:

    • Before executing actions on the node, added a check to ensure that the node is not null.
    foreach ($results as $nid) {
      $node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
      if ($node) {  // Check if the node is loaded successfully
        $action = (in_array($nid, $nodes_w_intermediates)) ? $intermediate_action : $original_action;
        printf("Performing '%s' on '%s' at %s\n", $action->id(), $node->toUrl()->toString(), date(DATE_ATOM));
        $action->execute([$node]);
      } else {
        printf("Node with ID '%s' could not be loaded\n", $nid);
      }
    }

These changes ensure that the script handles access checks explicitly and prevents errors when attempting to call methods on null objects.

<?php
use Drupal\system\Entity\Action;
use Drupal\Core\Session\UserSession;
use Drupal\user\Entity\User;
$userid = 1;
$account = User::load($userid);
$accountSwitcher = \Drupal::service('account_switcher');
$userSession = new UserSession([
'uid' => $account->id(),
'name' => $account->getDisplayName(),
'roles' => $account->getRoles(),
]);
$accountSwitcher->switchTo($userSession);
$original_tid = reset(
\Drupal::entityQuery('taxonomy_term')
->condition('field_external_uri', 'http://pcdm.org/use#OriginalFile')
->accessCheck(FALSE)
->execute()
);
$intermediate_tid = reset(
\Drupal::entityQuery('taxonomy_term')
->condition('field_external_uri', 'http://pcdm.org/use#IntermediateFile')
->accessCheck(FALSE)
->execute()
);
$service_tid = reset(
\Drupal::entityQuery('taxonomy_term')
->condition('field_external_uri', 'http://pcdm.org/use#ServiceFile')
->accessCheck(FALSE)
->execute()
);
$originals_query = \Drupal::database()->select('media', 'm');
$originals_query->join('media__field_media_use', 'u', 'm.mid = u.entity_id');
$originals_query->join('media__field_media_of', 'o', 'm.mid = o.entity_id');
$originals_query->join('media__field_mime_type', 'mime', 'm.mid = mime.entity_id');
$originals_query->fields('o', ['field_media_of_target_id'])
->condition('u.field_media_use_target_id', $original_tid)
->condition('mime.field_mime_type_value', 'image/%%', 'LIKE');
$nodes_w_originals = $originals_query->execute()->fetchCol();
# We are likely to get more service files than originals because we aren't limiting
# to images. This is because we sometimes use PDF (or perhaps other) service files.
$service_query = \Drupal::database()->select('media', 'm');
$service_query->join('media__field_media_use', 'u', 'm.mid = u.entity_id');
$service_query->join('media__field_media_of', 'o', 'm.mid = o.entity_id');
$service_query->fields('o', ['field_media_of_target_id'])
->condition('u.field_media_use_target_id', $service_tid);
$nodes_w_service = $service_query->execute()->fetchCol();
# Similarly, we may have intermediates that aren't images.
$intermediate_query = \Drupal::database()->select('media', 'm');
$intermediate_query->join('media__field_media_use', 'u', 'm.mid = u.entity_id');
$intermediate_query->join('media__field_media_of', 'o', 'm.mid = o.entity_id');
$intermediate_query->fields('o', ['field_media_of_target_id'])
->condition('u.field_media_use_target_id', $intermediate_tid);
$nodes_w_intermediates = $intermediate_query->execute()->fetchCol();
$results = array_diff($nodes_w_originals, $nodes_w_service);
$original_action = Action::load('image_generate_a_service_file_from_an_original_file');
$intermediate_action = Action::load('image_generate_a_service_file_from_an_intermediate_file');
foreach ($results as $nid) {
$node = \Drupal::entityTypeManager()->getStorage('node')->load($nid);
if ($node) { // Check if the node is loaded successfully
$action = (in_array($nid, $nodes_w_intermediates)) ? $intermediate_action : $original_action;
printf("Performing '%s' on '%s' at %s\n", $action->id(), $node->toUrl()->toString(), date(DATE_ATOM));
$action->execute([$node]);
} else {
printf("Node with ID '%s' could not be loaded\n", $nid);
}
}
$accountSwitcher->switchBack();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment