Last active
February 16, 2016 23:22
-
-
Save scottrigby/0e664684e99dadaab6d2 to your computer and use it in GitHub Desktop.
Drush script shortens files with names that would be too long with s3 bucket added to uri.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env drush | |
/** | |
* Shortens files with names that would be too long with s3 bucket added to uri. | |
* | |
* Problem: | |
* - In order to migrate existing files to s3 we must replace existing public:// | |
* and private:// schemes to to s3://BUCKET_NAME/ in the uri column of the | |
* {file_managed} and {file_managed_revisions} tables. | |
* - However, some files that previously fit in these uri columns would now be | |
* too long with the BUCKET_NAME added. | |
* - Depending on the replace method used, those rows would either fail or skip | |
* (example MySQL IGNORE REPLACE). | |
* - In either case, the s3 scheme would not be added, so fields configured to | |
* use s3 for upload would render these existing files as broken images. | |
* | |
* Solution: | |
* - Shorten actual file names to fit the longest BUCKET_NAME in their full URI. | |
* - Update value in uri column of {file_managed} and {file_managed_revisions} | |
* tables to match the newly renamed file. | |
* | |
* Drush options (required): | |
* - max_len: Number of characters the uri column in {file_managed} table may | |
* have before the filename is shortened. | |
* - op: May be one of: | |
* - count: Returns a the number of records that will be effected. | |
* - list: Lists the URI for records that will be effected. | |
* - move: Performs file shortening operation, moving from old to new name. | |
* | |
* @see system_schema() | |
* @see file_entity_revisions_schema() | |
*/ | |
$max_len = drush_get_option('max_len'); | |
$op = drush_get_option('op'); | |
if (empty($max_len) || !is_numeric($max_len)) { | |
drush_set_error('NO_MAX_LENGTH', dt('The "max" option is required. Must be numeric.')); | |
$missing = TRUE; | |
} | |
if (empty($op) || !in_array($op, array('count', 'list', 'move'))) { | |
drush_set_error('NO_OP', dt('The "op" option is required. Must be one of "count", "list", or "move".')); | |
$missing = TRUE; | |
} | |
if ($missing) { | |
return; | |
} | |
// Note do not use :max or :public placeholders, as they are reserved. | |
$query = "SELECT fid, uri | |
FROM {file_managed} | |
WHERE LENGTH (uri) > :max_len | |
AND (uri LIKE :scheme1 OR uri LIKE :scheme2)"; | |
$args = array( | |
':max_len' => $max_len, | |
':scheme1' => 'public://%', | |
':scheme2' => 'private://%', | |
); | |
$records = db_query($query, $args); | |
if ('count' == $op) { | |
$count = $records->rowCount(); | |
drush_print($count); | |
} | |
else { | |
foreach ($records as $record) { | |
if ('list' == $op) { | |
drush_print($record->uri); | |
} | |
elseif ('move' == $op) { | |
// Shorten each actual file name, and update the file and DB accordingly. | |
$file = file_load($record->fid); | |
// Use md5 to get a unique shortened file name. | |
$pathinfo = pathinfo($record->uri); | |
$destination = $pathinfo['dirname'] . '/' . md5($pathinfo['filename']) . '.' . $pathinfo['extension']; | |
file_move($file, $destination, FILE_EXISTS_ERROR); | |
drush_print("Moving from $record->uri to {$destination}."); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment