Skip to content

Instantly share code, notes, and snippets.

@typhonius
Last active January 27, 2021 10:01
Show Gist options
  • Save typhonius/8599853 to your computer and use it in GitHub Desktop.
Save typhonius/8599853 to your computer and use it in GitHub Desktop.
This script can generate image derivatives for Drupal for warming up the filesystem prior to going live. Image derivative generation puts an amount of load on the servers so it images have been migrated from another server with no derivatives, it may be useful to pre-generate using this script.
<?php
/**
* Implements hook_drush_command().
*/
function seed_derivatives_drush_command() {
$items = array();
$items['seed_derivatives'] = array(
'description' => "Create image derivatives",
'callback' => 'drush_seed_derivatives',
'options' => array(
'styles' => array(
'description' => 'A comma separated list of all image styles needing generation, leaving this blank will use all styles',
'example_value' => 'small,medium,thumbnail',
),
'exclude' => array(
'description' => 'A comma separated list of all image styles to be excluded. Leaving this blank will use all styles from the "styles" parameter.',
'example_value' => 'large',
),
'dir' => array(
'description' => 'Set to the file path (relative to your public files directory) under which all files will have an image derivative created. Alternatively, set to "public" to just have your public files directory looked into with no recursion. With no option set, the default will run through every single file.',
'example_value' => 'field/image',
),
),
'examples' => array(
'drush seed_derivatives' => 'Creates image derivatives for every single image style for every file within the public file system.',
'drush seed_derivatives --styles=large,medium --dir=field' => 'Creates large and medium image derivatives for every single image stored underneath the "field" directory in the public file directory.',
'drush seed_derivatives --exclude=thumbnail --dir=public' => 'Creates image derivatives for every single image style except "thumbnail" for every file within the public file system directory but not in subdirectories.',
),
'core' => array('7'),
'bootstrap' => DRUSH_BOOTSTRAP_DRUPAL_FULL,
);
return $items;
}
/**
* Command callback to perform the file migration.
*
* The options for this script are styles, exclude and dir. The styles and exclude
* options will explicitly set or prohibit image styles to be created. The default
* is that all styles will be used.
* The dir parameter may be used to specify paths under the public files directory
* that processing may occur on. The default for this is all paths and the special
* path "public" will only process the public files directory without recursion.
*/
function drush_seed_derivatives() {
if (!module_exists("image")) {
return drush_set_error("This script requires the image module to be enabled.");
}
$extensions = array('jpeg', 'jpg', 'gif', 'png');
$mimetypes = array('image/jpeg', 'image/jpg', 'image/gif', 'image/png');
$dir = rtrim(drush_get_option('dir'), '/');
if ($dir == 'public') {
$file_pattern = "[^\/]*"; // Finds anything that does not contain "/", should be fine.
}
else {
$file_pattern = $dir ? $dir . ".+" : ".+";
}
$regex = "^public:\/\/(" . $file_pattern . ")\.(" . implode($extensions, '|') . ")$";
// Query the database for files that match this pattern.
$query = db_select('file_managed', 'f')
->condition('filemime', $mimetypes , 'IN')
->condition('uri', $regex, 'REGEXP');
$total_count = $query->countQuery()->execute()->fetchField();
drush_print(format_plural($total_count,
'1 entry is to have its image derivatives created.',
'@count entries are to have their image derivatives created.'));
// Select the files to have derivatives created..
$files = $query->fields('f', array('fid', 'filename', 'uri', 'timestamp'))
->execute()
->fetchAll();
$excludes = explode(",", drush_get_option('exclude'));
$includes = explode(",", drush_get_option('styles'));
foreach (image_styles() as $name => $style) {
if (!empty($excludes) && in_array($style['name'], $excludes)) {
drush_print('Excluding ' . $name);
continue;
}
if (empty($includes[0]) || in_array($style['name'], $includes)) {
drush_print('Processing ' . $name);
$count = 1;
foreach ($files as $file) {
$derivative_uri = image_style_path($style['name'], $file->uri);
if (!file_exists($derivative_uri)) {
image_style_create_derivative($style, $file->uri, $derivative_uri);
}
$progress = round(($count / $total_count) * 100);
drush_print($progress . '%');
$count++;
}
}
}
}
@drakakisgeo
Copy link

Create a folder named "drush" in sites/all and put this file there. Then you can execute it by running

drush seed_derivatives

@ilkka
Copy link

ilkka commented Feb 15, 2016

@typhonius do you happen to know how this differs from what the media module does normally when an image is requested? I can't get image style generation to work through drupal, but this script generates all styles beautifully.

@stela5
Copy link

stela5 commented Feb 23, 2016

Worked great, thanks!

@typhonius
Copy link
Author

@ilkka this doesn't change how Media/Drupal Core creates images. This sounds like a permissions issue where your Unix user has permissions to write new images on the filesystem but the Drupal user does not.

Copy link

ghost commented Nov 25, 2016

@typhonius I just tried using your drush module, however I discovered it was written for Drupal 7. Have you written a Drupal 8 version, or do you know of someone who has already written one?

@jimconte
Copy link

@zensabbah
Copy link

I added a drush folder under sites/all with this file inside but when I execute the command I receive: "The drush command 'seed_derivatives' could not be found."

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment