Skip to content

Instantly share code, notes, and snippets.

@RowboTony
Created November 17, 2023 04:37
Show Gist options
  • Save RowboTony/acf9ee5afb78b6a29a7a763f56d1fb11 to your computer and use it in GitHub Desktop.
Save RowboTony/acf9ee5afb78b6a29a7a763f56d1fb11 to your computer and use it in GitHub Desktop.
Drush scripts to clean up database issues for Drupal 7 migrations
<?php
/**
* Drush script to delete a text format (filter format) from the Drupal 7 database.
*
* Usage:
* drush scr path/to/delete_filter_format.drush.php --filter_format=filtered_html [--dry-run]
*/
// Drush bootstrap for full Drupal access.
drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
// Fetch the filter format machine name from the command line options.
$filter_format = drush_get_option('filter_format', '');
$dry_run = drush_get_option('dry-run', FALSE);
if (empty($filter_format)) {
drush_print("No filter format machine name provided. Usage: drush scr delete_filter_format.drush.php --filter_format=filtered_html [--dry-run]");
exit();
}
// Load the filter format to make sure it exists.
$format = filter_format_load($filter_format);
// ... (preceding code)
if ($format) {
drush_print("Found filter format with machine name: '$filter_format'.");
// Check if the format is currently being used by any fields.
// Adjusted the query to check all text fields that might be using this format.
$usage = db_query("SELECT 1 FROM {field_config_instance} WHERE data LIKE :data", array(':data' => '%' . $filter_format . '%'))->fetchField();
if ($usage) {
drush_print("The text format '$filter_format' is currently in use and cannot be deleted.");
if (!$dry_run) {
exit();
}
} else {
if ($dry_run) {
drush_print("[DRY RUN] Would delete the text format '$filter_format'.");
} else {
// Delete the text format.
db_delete('filter_format')
->condition('format', $format->format)
->execute();
drush_print("Deleted the text format '$filter_format'.");
// Clear caches after deletion.
cache_clear_all('*', 'cache_filter', TRUE);
}
}
} else {
drush_print("No filter format found with machine name: '$filter_format'.");
}
// ... (following code)
if ($dry_run) {
drush_print("Dry run completed. No changes were made to the database.");
} else {
drush_print("Text format deletion process completed.");
}
<?php
/**
* Drush script to delete specific path aliases by their IDs (pids).
*
* Usage:
* drush scr path/to/delete_path_aliases.drush.php --pids=123,456,789 [--dry-run]
*/
// Drush bootstrap for full Drupal access.
drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
// Fetch the path alias IDs (pids) from the command line options.
$pids_option = drush_get_option('pids', '');
$pids = explode(',', $pids_option);
$dry_run = drush_get_option('dry-run', FALSE);
if (empty($pids_option)) {
drush_print("No path alias IDs (pids) provided. Usage: drush scr delete_path_aliases.drush.php --pids=123,456,789 [--dry-run]");
exit();
}
foreach ($pids as $pid) {
$pid = trim($pid);
if (!is_numeric($pid)) {
drush_print("Skipping invalid PID: $pid");
continue;
}
// Load the path alias to make sure it exists.
$alias = db_select('url_alias', 'ua')
->fields('ua')
->condition('pid', $pid)
->execute()
->fetchAssoc();
if ($alias) {
drush_print("Found path alias with ID (pid): '$pid' for path '{$alias['source']}' to alias '{$alias['alias']}'.");
if ($dry_run) {
drush_print("[DRY RUN] Would delete the path alias with ID (pid): $pid.");
} else {
// Delete the path alias.
db_delete('url_alias')
->condition('pid', $pid)
->execute();
drush_print("Deleted the path alias with ID (pid): $pid.");
}
} else {
drush_print("No path alias found with ID (pid): '$pid'.");
}
}
if ($dry_run) {
drush_print("Dry run completed. No changes were made to the database.");
} else {
drush_print("Path alias deletion process completed.");
}
<?php
/**
* Drush script to non-interactively delete all but the newest revision of nodes by content type,
* with an option for a dry run.
*
* Usage: drush scr delete_revisions_except_newest.drush.php [content-type] --autodelete [--dry-run]
*/
// Drush bootstrap for full Drupal access.
drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
// Fetch the content type and dry-run option from the command line arguments.
$args = drush_get_arguments();
$content_type = isset($args[2]) ? $args[2] : '';
$auto_delete = drush_get_option('autodelete', FALSE);
$dry_run = drush_get_option('dry-run', FALSE);
// Check if content type is provided.
if (empty($content_type)) {
drush_print("No content type provided. Usage: drush scr delete_revisions_except_newest.drush.php [content-type] --autodelete [--dry-run]");
exit();
}
$operation = $dry_run ? "Dry run for deleting" : ($auto_delete ? "Auto-deleting" : "Listing");
drush_print("Preparing to {$operation} revisions for content type: " . $content_type);
// Query for all nodes of the given content type.
$nodes_query = db_select('node', 'n')
->fields('n', array('nid', 'title'))
->condition('type', $content_type)
->execute();
foreach ($nodes_query as $node) {
drush_print("Node ID: " . $node->nid . " with title: " . $node->title);
// Query for all revisions of the given node, ordered by vid descending.
$revisions_query = db_select('node_revision', 'nr')
->fields('nr', array('vid', 'timestamp'))
->condition('nid', $node->nid)
->orderBy('vid', 'DESC')
->execute();
$revisions = $revisions_query->fetchAll();
// Skip the first one (most recent revision).
array_shift($revisions);
// If we have more revisions left, those are older and can be deleted.
if (!empty($revisions)) {
foreach ($revisions as $revision) {
if ($auto_delete && !$dry_run) {
// Perform the deletion of this revision.
node_revision_delete($revision->vid);
drush_print("Auto-deleted revision VID: " . $revision->vid);
} else {
$revision_date = format_date($revision->timestamp, 'custom', 'Y-m-d H:i:s');
$action = $dry_run ? "Would delete" : "Older";
drush_print("{$action} Revision VID: " . $revision->vid . " from " . $revision_date);
}
}
} else {
drush_print(" - No older revisions found for this node.");
}
}
$process = $dry_run ? "Dry run completed" : "Process completed";
drush_print($process . ".");
<?php
/**
* Drush script to delete specified unused fields with a dry-run option.
*
* Usage:
* drush scr path/to/delete_fields.drush.php --fields=field1,field2,field3 [--dry-run]
*/
// Drush bootstrap for full Drupal access.
drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
// Fetch command line options.
$fields_option = drush_get_option('fields', '');
$dry_run = drush_get_option('dry-run', FALSE);
// Convert the comma-separated list of field names into an array.
$fields_to_delete = array_filter(array_map('trim', explode(',', $fields_option)));
if (empty($fields_to_delete)) {
drush_print("No field names provided. Usage: drush scr delete_fields.drush.php --fields=field1,field2,field3 [--dry-run]");
exit();
}
foreach ($fields_to_delete as $field_name) {
// Check if the field exists.
$field = field_info_field($field_name);
if ($field) {
if ($dry_run) {
drush_print("[DRY RUN] Would delete field: $field_name");
} else {
// Delete the field data first.
field_delete_field($field_name);
drush_print("Deleted field data for: $field_name");
// Purge the field data. Note: This might need to be run several times in a real deletion.
$purged = field_purge_batch(1000);
drush_print("Purged $purged field data records for: $field_name");
}
} else {
drush_print("Field not found or already deleted: $field_name");
}
}
if ($dry_run) {
drush_print("Dry run completed. No changes were made to the database.");
} else {
drush_print("Field deletion process completed.");
}
<?php
/**
* Drush script to delete URL aliases based on provided PIDs.
*
* Usage:
* drush scr path/to/delete_url_aliases.drush.php --pids=1,2,3 [--dry-run] [--autodelete]
*/
// Drush bootstrap for full Drupal access.
drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
// Fetch command line options.
$pids_option = drush_get_option('pids', '');
$dry_run = drush_get_option('dry-run', FALSE);
$auto_delete = drush_get_option('autodelete', FALSE);
// Convert the comma-separated list of PIDs into an array.
$pids = array_filter(array_map('trim', explode(',', $pids_option)));
if (empty($pids)) {
drush_print("No PIDs provided. Usage: drush scr delete_url_aliases.drush.php --pids=1,2,3 [--dry-run] [--autodelete]");
exit();
}
foreach ($pids as $pid) {
if (!is_numeric($pid)) {
drush_print("Skipping invalid PID: $pid");
continue;
}
// Retrieve the URL alias details.
$alias_details = db_select('url_alias', 'ua')
->fields('ua', array('source', 'alias'))
->condition('pid', $pid)
->execute()
->fetchAssoc();
if ($alias_details) {
$source = $alias_details['source'];
$alias = $alias_details['alias'];
// Perform a dry run if specified.
if ($dry_run) {
drush_print("[DRY RUN] Would delete URL alias with pid: $pid, source: $source, alias: $alias");
} else if ($auto_delete) {
// Perform the deletion.
db_delete('url_alias')
->condition('pid', $pid)
->execute();
drush_print("Deleted URL alias with pid: $pid, source: $source, alias: $alias");
}
} else {
drush_print("No URL alias found with pid: $pid");
}
}
if ($dry_run) {
drush_print("Dry run completed. No changes were made to the database.");
} else if ($auto_delete) {
drush_print("URL alias deletion process completed.");
} else {
drush_print("Specify --autodelete to perform the deletion.");
}
<?php
/**
* Drush script to remove a field from a specific content type with a dry-run option.
*
* Usage: drush scr remove_field_from_content_type.drush.php --dry-run
* drush scr remove_field_from_content_type.drush.php
*/
// Drush bootstrap for full Drupal access.
drush_bootstrap(DRUSH_BOOTSTRAP_DRUPAL_FULL);
// Fetch the field name and content type from the command line options.
$field_name = drush_get_option('field_name', '');
$content_type = drush_get_option('content_type', '');
$dry_run = drush_get_option('dry-run', FALSE);
if ($dry_run) {
drush_print("Running in dry-run mode. No changes will be made.");
}
// Check if the field exists and is attached to the content type.
$field = field_info_field($field_name);
$field_instance = field_info_instance('node', $field_name, $content_type);
if ($field_instance) {
if (!$dry_run) {
// Delete the field instance from the content type.
field_delete_instance($field_instance);
field_cache_clear();
drush_print("Deleted field instance '$field_name' from content type '$content_type'.");
} else {
drush_print("Would delete field instance '$field_name' from content type '$content_type'.");
}
// Check if the field is now unused and delete the field if it is.
$field_instances = field_info_instances('node', $field_name);
if (empty($field_instances)) {
if (!$dry_run) {
field_delete_field($field_name);
field_cache_clear();
drush_print("Deleted field '$field_name' from the system.");
} else {
drush_print("Would delete field '$field_name' from the system.");
}
}
else {
drush_print("Field '$field_name' is still used by other content types and was not deleted from the system.");
}
}
else {
drush_print("Field '$field_name' does not exist or is not attached to content type '$content_type'.");
}
drush_print("Field removal process " . ($dry_run ? "would be" : "is") . " completed.");
@RowboTony
Copy link
Author

RowboTony commented Nov 17, 2023

As-is, no guarantee or warranty. Drop these in your Drupal 7 root, and see if they help you. Most should have a --dry-run option to be non-destructive. Use at your own risk.

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