do/commands/backup
2025-09-18 08:22:11 -04:00

106 lines
No EOL
4.3 KiB
Bash

# ----------------------------------------------------
# Creates a full backup of a WordPress site (files + database).
# ----------------------------------------------------
function full_backup() {
# --- 1. Argument Parsing ---
local target_folder="$1"
local quiet_flag="$2"
local format_flag="$3"
shift 3 # Move past the first two arguments
local exclude_patterns=("$@") # The rest of the arguments are the exclude patterns
# --- 2. Validation ---
if [ -z "$target_folder" ]
then echo "Error: Please provide a folder path." >&2; echo "Usage: _do backup <folder>" >&2; return 1;
fi
if ! command -v realpath &> /dev/null; then echo "Error: 'realpath' command not found. Please install it." >&2; return 1; fi
if [ ! -d "$target_folder" ]; then echo "Error: Folder '$target_folder' not found." >&2; return 1; fi
# --- 3. Setup Paths and Filenames ---
# Resolve the absolute path to handle cases like "."
local full_target_path; full_target_path=$(realpath "$target_folder")
local parent_dir; parent_dir=$(dirname "$full_target_path")
local site_dir_name; site_dir_name=$(basename "$full_target_path")
local today; today=$(date +"%Y-%m-%d")
local random; random=$(openssl rand -hex 4 | head -c 7)
local backup_filename="${today}_${random}.zip"
local original_dir; original_dir=$(pwd)
# Change to the parent directory for consistent relative paths in the zip
cd "$parent_dir" || return 1
# --- 4. Database Export ---
if ! setup_wp_cli; then echo "Error: wp-cli is not installed." >&2; cd "$original_dir"; return 1; fi
local home_url; home_url=$("$WP_CLI_CMD" option get home --path="$site_dir_name" --skip-plugins --skip-themes)
local name; name=$("$WP_CLI_CMD" option get blogname --path="$site_dir_name" --skip-plugins --skip-themes)
local database_file="db_export.sql"
if [[ "$quiet_flag" != "true" ]]; then
echo "Exporting database for '$name'...";
fi
if ! "$WP_CLI_CMD" db export "$site_dir_name/$database_file" --path="$site_dir_name" --add-drop-table --default-character-set=utf8mb4 > /dev/null; then
echo "Error: Database export failed." >&2
cd "$original_dir"
return 1
fi
if [[ "$quiet_flag" != "true" ]]; then
echo "Creating zip archive...";
if [ ${#exclude_patterns[@]} -gt 0 ]; then
echo "Excluding the following patterns:"
for pattern in "${exclude_patterns[@]}"; do
echo " - $pattern"
done
fi
fi
# --- 5. Zip Archive Creation ---
local zip_exclude_args=()
zip_exclude_args+=(-x "$site_dir_name/wp-content/updraft/*") # Add default exclude
for pattern in "${exclude_patterns[@]}"; do
zip_exclude_args+=(-x "$site_dir_name/$pattern*") # Add user-defined excludes
done
# Create the zip in the parent directory, zipping the site directory
if ! zip -r "$backup_filename" "$site_dir_name" "${zip_exclude_args[@]}" > /dev/null; then
echo "Error: Failed to zip files." >&2
rm -f "$site_dir_name/$database_file"
cd "$original_dir"
return 1
fi
# Add wp-config.php if it exists in the site directory
if [ -f "$site_dir_name/wp-config.php" ]; then
zip "$backup_filename" "$site_dir_name/wp-config.php" > /dev/null
fi
# --- 6. Cleanup and Final Report ---
local size
size=$(ls -lh "$backup_filename" | awk '{print $5}')
rm -f "$site_dir_name/$database_file"
mv "$backup_filename" "$site_dir_name/"
local final_backup_location="$site_dir_name/$backup_filename"
cd "$original_dir"
local final_backup_location="$full_target_path/$backup_filename"
local final_url="${home_url}/${backup_filename}"
if [[ "$format_flag" == "filename" ]]; then
echo "$backup_filename"
return 0
fi
if [[ "$quiet_flag" == "true" ]]; then
echo "$final_url"
return 0
fi
echo "-----------------------------------------------------"
echo "✅ Full site backup complete!"
echo " Name: $name"
echo " Location: $final_backup_location"
echo " Size: $size"
echo " URL: $final_url"
echo "-----------------------------------------------------"
echo "When done, remember to remove the backup file."
echo "rm -f \"$final_backup_location\""
}