captaincore/lib/remote-scripts/migrate
2024-05-23 09:58:04 -04:00

317 lines
10 KiB
Bash

#!/usr/bin/env bash
#
# Migrate site from backup snapshot
#
# `migrate --url=<backup-url>`
#
# [--update-urls]
# Update urls to destination WordPress site. Default will keep source urls.
#
# Loop through arguments and separate regular arguments from flags
for arg in "$@"; do
# Add to arguments array. (Does not starts with "--")
if [[ $arg != --* ]]; then
count=1+${#arguments[*]}
arguments[$count]=$arg
continue
fi
# Remove leading "--"
flag_name=$( echo $arg | cut -c 3- )
# Add to flags array
count=1+${#flags[*]}
flags[$count]=$arg
# Process flags without data (Assign to variable)
if [[ $arg != *"="* ]]; then
flag_name=${flag_name//-/_}
declare "$flag_name"=true
fi
# Process flags with data (Assign to variable)
if [[ $arg == *"="* ]]; then
flag_value=$( echo $flag_name | perl -n -e '/.+?=(.+)/&& print $1' ) # extract value
flag_name=$( echo $flag_name | perl -n -e '/(.+?)=.+/&& print $1' ) # extract name
flag_name=${flag_name/-/_}
# Remove first and last quote if found
flag_value="${flag_value%\"}"
flag_value="${flag_value#\"}"
declare "$flag_name"="$flag_value"
continue
fi
done
read -r -d '' php_code << heredoc
\$arguments = <<<PHPHEREDOC
$url
PHPHEREDOC;
echo urldecode( \$arguments );
heredoc
backup_url=$( php -r "$php_code" )
# Store current path
home_directory=$(pwd)
run_command() {
# Find private folder
if [ -d "_wpeprivate" ]; then
private=${home_directory}/_wpeprivate
fi
if [ -d "../private" ]; then
cd ../private
private=$(pwd)
cd $home_directory
fi
if [ -d "../tmp" ]; then
cd ../tmp
private=$(pwd)
cd $home_directory
fi
if [ ! -d "_wpeprivate" ] && [ ! -d "../private" ] && [ ! -d "../tmp" ]; then
echo "Can't locate private folder '/_wpeprivate', '../private' or '../tmp'. Migration cancelled."
return 1
fi
# Verifies WordPress
wp_home=$( wp option get home --skip-themes --skip-plugins )
if [[ "$wp_home" != "http"* ]]; then
echo "WordPress not found. Migration cancelled."
return 1
fi
cd $private
if [[ "$backup_url" == *"admin-ajax.php?action=pb_backupbuddy_backupbuddy&function=download_archive&backupbuddy_backup"* ]]; then
echo "Backup Buddy URL found"
backup_url=${backup_url/wp-admin\/admin-ajax.php?action=pb_backupbuddy_backupbuddy&function=download_archive&backupbuddy_backup=/wp-content\/uploads\/backupbuddy_backups/}
fi
if [[ "$backup_url" == *"www.dropbox.com"* ]] && [[ "$backup_url" == *"&dl=0" ]]; then
echo "Dropbox URL found"
backup_url=${backup_url/&dl=0/&dl=1}
fi
# Generate fresh snapshot directory
timedate=$(date +'%Y-%m-%d-%H%M%S')
mkdir -p restore_$timedate
cd restore_$timedate
# Downloads backup file (No local file found)
if [ ! -f "$private/$url" ]; then
echo "Downloading $backup_url"
wget --no-check-certificate --progress=bar:force:noscroll -O restore_$timedate.out $backup_url
fi
# Preps local restore file (local file found)
if [ -f "$private/$url" ]; then
echo "Local file '${url}' found. Renaming to 'restore_${timedate}.out'."
mv "$private/$url" "$private/restore_$timedate/restore_$timedate.out"
fi
if [[ "$backup_url" == *".gz"* ]]; then
mv restore_$timedate.out restore_$timedate.gz
tar xzf restore_$timedate.gz
rm restore_$timedate.gz
fi
if [[ "$backup_url" == *".zip"* ]]; then
mv restore_$timedate.out restore_$timedate.zip
unzip -q -o restore_$timedate.zip -x "__MACOSX/*" -x "cgi-bin/*" 2>&-
rm restore_$timedate.zip
fi
if [[ "$backup_url" == *".tar"* ]]; then
mv restore_$timedate.out restore_$timedate.tar
tar xzf restore_$timedate.tar
rm restore_$timedate.tar
fi
# Assume it's a zip, if nothing defined.
if [[ "$backup_url" != *".gz"* ]] && [[ "$backup_url" != *".zip"* ]] && [[ "$backup_url" != *".tar"* ]]; then
mv restore_$timedate.out restore_$timedate.zip
unzip -q -o restore_$timedate.zip -x "__MACOSX/*" -x "cgi-bin/*" 2>&-
rm restore_$timedate.zip
fi
# Finds WordPress path
wordpresspath=$( find "$(pwd)" -type d -name 'wp-content' -print -quit )
if [[ $wordpresspath == "" ]]; then
echo "Can't find wp-content/ in backup. Migration cancelled.";
return 1
fi
# Migrate mu-plugins if found
if [ -d "$wordpresspath/wp-content/mu-plugins" ]; then
echo "Moving: mu-plugins"
cd "$wordpresspath/wp-content/mu-plugins"
for working in *; do
echo "$working"
if [ -f "$home_directory/wp-content/mu-plugins/$working" ]; then
rm "$home_directory/wp-content/mu-plugins/$working"
fi
if [ -d "$home_directory/wp-content/mu-plugins/$working" ]; then
rm -rf "$home_directory/wp-content/mu-plugins/$working"
fi
mv "$working" "$home_directory/wp-content/mu-plugins/"
done
cd "${private}/restore_${timedate}"
fi
# Migrate blogs.dir if found
if [ -d "$wordpresspath/blogs.dir" ]; then
echo "Moving: blogs.dir"
rm -rf "$home_directory/wp-content/blogs.dir"
mv "$wordpresspath/blogs.dir" "$home_directory/wp-content/"
fi
# Migrate gallery if found
if [ -d "$wordpresspath/gallery" ]; then
echo "Moving: gallery"
rm -rf "$home_directory/wp-content/gallery"
mv "$wordpresspath/gallery" "$home_directory/wp-content/"
fi
# Migrate ngg if found
if [ -d "$wordpresspath/ngg" ]; then
echo "Moving: ngg"
rm -rf "$home_directory/wp-content/ngg"
mv "$wordpresspath/ngg" "$home_directory/wp-content/"
fi
# Migrate uploads if found
if [ -d "$wordpresspath/uploads" ]; then
echo "Moving: uploads"
rm -rf "$home_directory/wp-content/uploads"
mv "$wordpresspath/uploads" "$home_directory/wp-content/"
fi
# Migrate themes if found
for d in $wordpresspath/themes/*/; do
echo "Moving: themes/$( basename "$d" )"
rm -rf "$home_directory/wp-content/themes/$( basename "$d" )"
mv "$d" "$home_directory/wp-content/themes/"
done
# Migrate plugins if found
for d in $wordpresspath/plugins/*/; do
echo "Moving: plugins/$( basename "$d" )"
rm -rf "$home_directory/wp-content/plugins/$( basename "$d" )"
mv "$d" "$home_directory/wp-content/plugins/"
done
# Find non-default root level files and folders
cd "$wordpresspath/.."
default_files=( index.php license.txt readme.html wp-activate.php wp-app.php wp-blog-header.php wp-comments-post.php wp-config-sample.php wp-cron.php wp-links-opml.php wp-load.php wp-login.php wp-mail.php wp-pass.php wp-register.php wp-settings.php wp-signup.php wp-trackback.php xmlrpc.php wp-admin wp-config.php wp-content wp-includes database-backup.sql )
root_files=($( ls ))
for default_file in "${default_files[@]}"; do
for i in "${!root_files[@]}"; do
if [[ ${root_files[i]} == "$default_file" ]]; then
unset 'root_files[i]'
fi
done
done
# Move non-default root level files and folders
for file in "${root_files[@]}"; do
echo "Moving: $file to $home_directory/"
rm -rf "$home_directory/$file"
mv "$file" ${home_directory}/
done
cd "$home_directory"
# Remove select plugins if found
plugins=( backupbuddy wp-super-cache adminer wordfence w3-total-cache wp-file-cache broken-link-checker yet-another-related-posts-plugin comet-cache-1 woothemes-updater ewww-image-optimizer https-redirection really-simple-ssl hello wordpress-php-info force-strong-passwords )
for plugin in ${plugins[@]}; do
if $( wp plugin is-installed $plugin --skip-plugins --skip-themes ); then
wp plugin delete $plugin --skip-plugins --skip-themes
fi
done
# Grabs current privacy settings
search_privacy=$( wp option get blog_public --skip-plugins --skip-themes )
# Outputs table prefix and updates if different
cd "$wordpresspath/../"
if [ -f wp-config.php ]; then
cat wp-config.php | grep table_prefix
table_prefix=$( cat wp-config.php | grep table_prefix | perl -n -e '/\047(.+)\047/&& print $1' )
fi
cd "$home_directory"
current_table_prefix=$( wp config get table_prefix --skip-plugins --skip-themes )
if [[ $table_prefix != "" && $table_prefix != "$current_table_prefix" ]]; then
wp config set table_prefix $table_prefix --skip-plugins --skip-themes
fi
echo "Resetting file and folder permissions to defaults"
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
echo "Found the following database:"
find $home_directory/wp-content/uploads $private/restore_$timedate/ -type f -name '*.sql'
database=$( find $private/restore_$timedate/ -type f -name '*.sql' -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " )
if [[ "$database" == "" ]]; then
# Expand db search
database=$( find $home_directory -type f -name '*.sql' -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " )
fi
if [[ "$database" == "" ]]; then
echo "Database not found. Skipping database import.";
return 1
fi
if [ ! -f "$database" ]; then
echo "Database $database not found. Skipping database import.";
return 1
fi
echo "Importing $database"
wp db reset --yes --skip-plugins --skip-themes
wp db import $database --skip-plugins --skip-themes
wp cache flush --skip-plugins --skip-themes
# Secure database
if [ -f "$home_directory/wp-content/mysql.sql" ]; then
chmod 600 $home_directory/wp-content/mysql.sql
fi
# Reapply search privacy
wp option update blog_public $search_privacy --skip-plugins --skip-themes
# Fetch imported url
wp_home_imported=$( wp option get home --skip-plugins --skip-themes )
if [[ "$update_urls" == "true" ]]; then
echo "Updating urls from $wp_home_imported to $wp_home"
wp search-replace $wp_home_imported $wp_home --skip-plugins --skip-themes --all-tables --report-changed-only
fi
# Convert MyISAM tables to InnoDB
wp db query "SELECT CONCAT('ALTER TABLE ', TABLE_SCHEMA,'.', TABLE_NAME, ' ENGINE=InnoDB;') FROM information_schema.TABLES WHERE ENGINE = 'MyISAM'" --skip-column-names --skip-plugins --skip-themes > db_optimize.sql
wp db query --skip-plugins --skip-themes < db_optimize.sql
rm db_optimize.sql
# Flush permalinks
wp rewrite flush
# WooCommerce housecleaning
if $( wp plugin is-active woocommerce ); then
wp wc tool run regenerate_product_attributes_lookup_table --user=$( wp user list --field=email --role-administrator | tail -n 1 )
fi
}
run_command