File: //bigscoots/wpo/extras/bigscoots.menu
#!/bin/bash
source /bigscoots/includes/common.sh
display_scoots_commands() {
# Define color variables
bold=$(tput bold)
green=$(tput setaf 2)
cyan=$(tput setaf 6)
reset=$(tput sgr0)
echo "${bold}BigScoots Commands:${reset}"
echo " ${green}Backups:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots backups${reset} - Manages backups"
echo " - ${bold}Usage:${reset} ${cyan}scoots backups enter${reset}"
echo " - ${bold}Usage:${reset} ${cyan}scoots backups list${reset}"
echo " ${green}WP Admin Access:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots wpadmin${reset} - Provides WP admin access"
echo " ${green}Migrate Domains:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots migrate${reset} - Migrates domains between servers"
echo " - ${bold}Usage:${reset} ${cyan}scoots migrate ALL DESTINATIONIP${reset}"
echo " - ${bold}Usage:${reset} ${cyan}scoots migrate domain.com DESTINATIONIP${reset}"
echo " ${green}Search/Replace Domain:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots domain${reset} - Search and replace the domain of the current WP install with the domain you specify (no https://)(specify www or non-www)"
echo " - ${bold}Example:${reset} ${cyan}scoots domain newdomain.com${reset}"
echo " - ${bold}Note:${reset} ${cyan}Only specify the new domain, it takes the current domain from the database.${reset}"
echo " ${green}Setup SSH Access:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots ssh${reset} - Sets up SSH access"
echo " ${green}Remove Buffer from Nginx Access Logs:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots nginx rbc${reset} - Removes the buffer from nginx access logs so tailing shows in real-time"
echo " ${green}Change PHP Version:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php set${reset} - Changes the PHP version"
echo " - ${bold}Example:${reset} ${cyan}scoots php set domain.com phpversion${reset}"
echo " - ${bold}Example:${reset} ${cyan}scoots php set domain.com 81${reset}"
echo " ${green}PHP OPcache management:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php opcache deploy${reset} - Deploys a temporary opcache GUI tool for 24 hours"
echo " ${green}See PHP Version Information:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php info${reset} - Displays which domain is using which PHP version"
echo " - ${bold}Example:${reset} ${cyan}scoots php info${reset} - Shows all domains"
echo " - ${bold}Example:${reset} ${cyan}scoots php info domain.com${reset} - Shows specific domain"
echo " ${green}Restart PHP Service:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php restart${reset} - Restarts PHP services for specified or all versions"
echo " - ${bold}Example:${reset} ${cyan}scoots php restart all${reset} - Restarts all PHP versions"
echo " - ${bold}Example:${reset} ${cyan}scoots php restart 81${reset} - Restarts PHP 8.1"
echo " ${green}Reload PHP Service:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php reload${reset} - Reloads PHP services for specified or all versions"
echo " - ${bold}Example:${reset} ${cyan}scoots php reload all${reset} - Reloads all PHP versions"
echo " - ${bold}Example:${reset} ${cyan}scoots php reload 81${reset} - Reloads PHP 8.1"
echo " ${green}Convert PHP Configs:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php convert${reset} - Converts PHP configurations to match current settings"
echo " ${green}Update PHP Service:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php update${reset} - Updates PHP service"
echo " - ${bold}Example:${reset} ${cyan}scoots php update${reset}"
echo " - ${bold}Example:${reset} ${cyan}scoots php update --reboot${reset}"
echo " ${green}PHP-FPM Max Children:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots php child set${reset} - Sets pm.max_children for different plans"
echo " - ${bold}Usage:${reset} ${cyan}scoots php child set [starter|professional|business|enterprise|man N]${reset}"
echo " - ${bold}Example:${reset} ${cyan}scoots php child set starter${reset} - Sets max children to 6"
echo " - ${bold}Example:${reset} ${cyan}scoots php child set pro${reset} - Sets max children to 12"
echo " - ${bold}Example:${reset} ${cyan}scoots php child set man 50${reset} - Sets max children to 50"
echo " - ${bold}Command:${reset} ${cyan}scoots php child get${reset} - Gets the current PHP-FPM configurations"
echo " - ${bold}Usage:${reset} ${cyan}scoots php child get${reset} - Retrieves current pm, max children, and max requests for all PHP-FPM pools"
echo " ${green}Print rsync command for current folder:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots rsync cmd${reset} - Prints an rsync command for the current folder"
echo " ${green}Issue or Reissue an SSL Certificate for a Domain:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots ssl${reset} - Manages SSL for a domain"
echo " - ${bold}Example:${reset} ${cyan}scoots ssl issue domain.com${reset} - Issues a new certificate"
echo " - ${bold}Example:${reset} ${cyan}scoots ssl reissue domain.com${reset} - Reissues an existing certificate"
echo " - ${bold}Example:${reset} ${cyan}scoots ssl issue domain.com --nowww${reset} - Issue certificate without www"
echo " - ${bold}Example:${reset} ${cyan}scoots ssl reissue domain.com --nowww${reset} - Reissue certificate without www"
echo " - ${bold}Example:${reset} ${cyan}scoots ssl status domain.com${reset} - Checks current certificate status"
echo " ${green}Database Operations:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots db convert${reset} - Converts ALL databases from MyISAM to InnoDB."
echo " - ${bold}Command:${reset} ${cyan}scoots db check${reset} - Checks if the InnoDB buffer is full and should be increased."
echo " - ${bold}Command:${reset} ${cyan}scoots db cleanup${reset} - Identifies any unused databases. Do not blindly remove databases."
echo " - ${bold}Command:${reset} ${cyan}scoots db list${reset} - Lists all WordPress databases on the server and their associated domains."
echo " - ${bold}Command:${reset} ${cyan}scoots db create${reset} - Creates the database & grants the user based on wp-config.php"
echo " - ${bold}Usage:${reset} ${cyan}scoots db create${reset} # uses wp-config.php in current directory"
echo " - ${bold}Usage:${reset} ${cyan}scoots db create /path/to/wp-install${reset} # uses wp-config.php at specified path"
echo " - ${bold}Command:${reset} ${cyan}scoots db convert-charset${reset} - Converts all utf8mb3 tables/columns to utf8mb4_unicode_ci"
echo " ${green}Manage Server Cronjobs per Domain for WP Cron:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots cron on domain.com${reset} - Adds a server cronjob for the domain and disables WP cron"
echo " - ${bold}Command:${reset} ${cyan}scoots cron off domain.com${reset} - Removes the server cronjob for the domain and enables WP cron"
echo " ${green}Object Cache (Redis) Management:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots oc default${reset} - Set default Redis object cache settings"
echo " - ${bold}Command:${reset} ${cyan}scoots oc on domain.com${reset} - Enable Redis object cache for the domain and installs the Redis cache plugin"
echo " - ${bold}Command:${reset} ${cyan}scoots oc mem MEMORY_IN_MB${reset} - Allocate specific memory (in MB) for Redis object cache"
echo " - ${bold}Example:${reset} ${cyan}scoots oc mem 2048${reset} - Sets redis memory limit to 2GB"
echo " ${green}IP Blocking Management:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots ip block <IP>${reset} - Blocks an IP address"
echo " - ${bold}Command:${reset} ${cyan}scoots ip unblock <IP>${reset} - Unblocks an IP address"
echo " - ${bold}Command:${reset} ${cyan}scoots ip list${reset} - Lists all blocked IPs"
echo " - ${bold}Example:${reset} ${cyan}scoots ip block 192.168.1.100${reset} - Blocks the specified IP."
echo " - ${bold}Example:${reset} ${cyan}scoots ip unblock 192.168.1.100${reset} - Unblocks the specified IP."
echo " - ${bold}Example:${reset} ${cyan}scoots ip list${reset} - Displays a list of currently blocked IPs."
echo " ${green}WordPress Management:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots plugin reinstall-all${reset} - Reinstalls all plugins in a WordPress install"
echo " - ${bold}Usage:${reset} ${cyan}scoots plugin reinstall-all${reset} - Reinstalls plugins in the current WP install"
echo " - ${bold}Usage:${reset} ${cyan}scoots plugin reinstall-all --all-domains${reset} - Runs on all installs concurrently (10 at a time)"
echo " ${green}Clone WordPress Site:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots clone <source domain> <destination domain> [--uploads=skip|overwrite|sync] [--staging]${reset} - Clones one site to another."
echo " - ${bold}--uploads${reset} options:"
echo " - ${cyan}skip${reset} → Do not copy /uploads/20* content"
echo " - ${cyan}overwrite${reset} → Clone everything including /uploads/20*, overwriting the destination"
echo " - ${cyan}sync${reset} → Sync new /uploads/20* content without deleting destination files"
echo " - ${bold}--staging${reset} optional flag will run the clone using the staging logic"
echo " ${green}Performance Tools:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots perf generate${reset} - WORDPRESS PERFMATTERS CONFIG GENERATOR"
echo " - ${bold}Command:${reset} ${cyan}scoots perf setup${reset} - Install/activate Perfmatters and activate license"
echo " ${green}Quick(Les) Server Status:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots qstat${reset} - Shows quick server stats and resource usage"
echo " - ${bold}Example:${reset} ${cyan}scoots qstat${reset}"
echo " ${green}Ahmad's Stats:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots astat${reset} - Ahmad's statistics for a domain"
echo " - ${bold}Example:${reset} ${cyan}scoots astat${reset} - Runs on current WP install"
echo " - ${bold}Example:${reset} ${cyan}scoots astat domain.com${reset}"
echo " ${green}Print Useful Stats for Each Domain:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots kstat${reset} - Prints out some useful stats for each domain"
echo " - ${bold}Example:${reset} ${cyan}scoots kstat${reset}"
echo " - ${bold}Example:${reset} ${cyan}scoots kstat domain.com${reset}"
echo " ${green}WordPress Security (Wordfence):${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots wf${reset} - Installs and launches the Wordfence security auditing tool"
echo " - ${bold}Usage:${reset} ${cyan}scoots wf${reset} - Opens the Wordfence interactive scan menu"
echo " - ${bold}Example:${reset} After launching, choose options like full audit, vulnerability scan, or malware scan"
echo " ${green}BigScoots Cache (Cloudflare)${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots bs_cache encrypt${reset} - Encrypts and prints CLI flags"
echo " - ${bold}Command:${reset} ${cyan}scoots bs_cache audit${reset} - Server-wide audit of Cache plugin status"
echo " - ${bold}Options:${reset} Cloudflare Email, Cloudflare API Key, Cloudflare Zone ID, Cloudflare Token, All (Email+API Key+Zone ID)"
echo " ${green}Fix Permissions & Ownership:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots fixperm${reset} - Fixes permissions (644/755) and ownership (nginx) for a domain"
echo " - ${bold}Usage:${reset} ${cyan}scoots fixperm all${reset} - Fixes all domains on the server"
echo " - ${bold}Usage:${reset} ${cyan}scoots fixperm domain.com${reset} - Fixes a specific domain"
echo " - ${bold}Usage:${reset} ${cyan}scoots fixperm${reset} - Automatically detects the domain from your current directory"
echo " ${green}Server Cleanup:${reset}"
echo " - ${bold}Command:${reset} ${cyan}scoots cleanup${reset} - Runs the BigScoots cleanup script for the current domain"
echo " - ${bold}Note:${reset} Automatically moves you to the domain's /public folder before running."
}
function list_databases() {
echo -e "\n🔹 Listing WordPress Databases on This Server:\n"
# Temporary file to store results
tmpfile=$(mktemp)
# Disable job control messages
set +m
# Run processes in parallel
{
for domain in $(ls -1 /home/nginx/domains/); do
(
db_name=$(wpcli config get DB_NAME --path=/home/nginx/domains/$domain/public 2>/dev/null)
if [[ ! -z "$db_name" ]]; then
echo "$domain → $db_name"
fi
) &
done
wait
} > "$tmpfile" 2>/dev/null # Redirect stdout and stderr to file
# Re-enable job control messages
set -m
# Sort and display the results
sort "$tmpfile"
rm -f "$tmpfile"
}
# --- BigScoots Cache: encryption helpers ---
encrypt_it() {
local salt="$1"
echo -n "$salt" | openssl enc -aes-256-cbc -base64 -A -K "546573746b6579" -iv "c25e89f34f9878266bede60ed2feddde" 2>/dev/null
}
bs_cache_encrypt() {
# Map of human labels -> CLI flag names
declare -A MAP=(
["Cloudflare Email"]="cf-email-salt"
["Cloudflare API Key"]="cf-api-key-salt"
["Cloudflare Zone ID"]="cf-zone-id-salt"
["Cloudflare Token"]="cf-api-token-salt"
)
local choices=("Cloudflare Email" "Cloudflare API Key" "Cloudflare Zone ID" "Cloudflare Token" "All (Cloudflare Email, Cloudflare API Key, Cloudflare Zone ID)")
echo
echo "Which value would you like to encrypt?"
PS3="Select an option [1-${#choices[@]}]: "
select choice in "${choices[@]}"; do
case "$REPLY" in
1|2|3|4)
# Single item flow
local label="$choice"
local flag="${MAP[$label]}"
echo -n "Enter $label: "
# Make API key / token silent input, others normal
local value
if [[ "$label" == "Cloudflare API Key" || "$label" == "Cloudflare Token" ]]; then
read -r -s value; echo
else
read -r value
fi
local enc
enc="$(encrypt_it "$value")"
echo
echo "$label is --$flag=\"$enc\""
echo
break
;;
5)
# All (Email, API Key, Zone ID) — per spec, exclude Token
local labels=("Cloudflare Email" "Cloudflare API Key" "Cloudflare Zone ID")
declare -A ENC
for lbl in "${labels[@]}"; do
local prompt="Enter $lbl: "
local val
if [[ "$lbl" == "Cloudflare API Key" ]]; then
echo -n "$prompt"; read -r -s val; echo
else
echo -n "$prompt"; read -r val
fi
ENC["$lbl"]="$(encrypt_it "$val")"
done
local outstr="--${MAP["Cloudflare Email"]}=\"${ENC["Cloudflare Email"]}\" --${MAP["Cloudflare API Key"]}=\"${ENC["Cloudflare API Key"]}\" --${MAP["Cloudflare Zone ID"]}=\"${ENC["Cloudflare Zone ID"]}\""
echo
echo "CLI options:"
echo "$outstr"
echo
;;
*)
echo "Invalid selection."
;;
esac
break
done
}
perf_setup() {
# ensure we're in a valid WP install
if ! wpcli core is-installed --quiet; then
echo "This directory does not appear to be a WordPress install (wpcli core is-installed failed)."
return 1
fi
# install / activate perfmatters
if wpcli plugin is-installed perfmatters; then
if wpcli plugin is-active perfmatters; then
echo "Perfmatters plugin is already active."
else
echo "Perfmatters plugin is installed but not active. Activating now..."
wpcli plugin activate perfmatters
fi
else
echo "Perfmatters plugin is not installed. Installing and activating now..."
# wpcli can install from a URL; --activate simplifies the flow
if ! wpcli plugin install "$(curl -fsSL https://sharemy.zip/get/perfmatters)" --activate; then
echo "Failed to install/activate Perfmatters."
return 1
fi
fi
# fetch license (kept out of the script body; pulled securely at runtime)
LICENSE="$(curl -fsSL https://www.bigscoots.com/downloads/perfmatters | tr -d '\r\n')"
if [ -z "$LICENSE" ]; then
echo "Failed to retrieve Perfmatters license key."
return 1
fi
echo "Activating Perfmatters license..."
if ! wp perfmatters activate-license "$LICENSE" --skip-themes --skip-plugins=$(skip_all_plugins_except perfmatters); then
echo "Perfmatters license activation failed."
return 1
fi
echo "Perfmatters setup complete."
}
function scoots() {
if [ "$1" == backups ]
then
if [ "$2" == enter ]
then
bash /bigscoots/wpo_backups_ovz_restore.sh enter
elif [ "$2" == list ]
then
bash /bigscoots/wpo_backups_ovz_restore.sh hh
else
echo "BigScoots Backup Commands:
scoots backups enter
scoots backups list"
fi
elif [ "$1" == "bs_cache" ]; then
if [ "$2" == "encrypt" ]; then
bs_cache_encrypt
elif [ "$2" == "audit" ]; then
bash /bigscoots/wpo/cloudflare/bs-cache-audit.sh
else
echo "BigScoots Cache Commands:
scoots bs_cache encrypt # Encrypt Cloudflare creds for bs_cache CLI
scoots bs_cache status # Audit cache status across server"
fi
elif [ "$1" == wpadmin ]
then
bash /bigscoots/wpo/extras/wpadmin_user.sh
elif [ "$1" == nginx ]
then
if [ "$2" == rbc ]
then
bash /bigscoots/wpo/manage/set.sh nginx rbc
else
display_scoots_commands
fi
elif [ "$1" == "cleanup" ]; then
CURRENT_DIR=$(pwd)
# Regex to capture the domain from the path
if [[ "$CURRENT_DIR" =~ ^(/home/nginx/domains/[^/]+) ]]; then
TARGET_PUBLIC="${BASH_REMATCH[1]}/public"
if [ -d "$TARGET_PUBLIC" ]; then
echo "Moving to $TARGET_PUBLIC and running cleanup..."
cd "$TARGET_PUBLIC" || return
bash /bigscoots/wp_cleanup.sh
else
echo "Error: Could not find public folder at $TARGET_PUBLIC"
fi
else
echo "Error: You must be inside a domain directory (/home/nginx/domains/domain.com/) to run cleanup."
fi
elif [ "$1" == "fixperm" ]; then
if [ "$2" == "all" ]; then
# Runs for all domains via wildcard
echo "Fixing permissions and ownership for ALL domains in the background..."
correct_permissions_ownership
elif [ -n "$2" ]; then
# Runs for specific domain provided as argument
echo "Fixing permissions and ownership for $2..."
correct_permissions_ownership "$2"
else
# Detect domain from current path
# If path is /home/nginx/domains/example.com/public/wp-content
# It extracts 'example.com'
CURRENT_DIR=$(pwd)
if [[ "$CURRENT_DIR" =~ /home/nginx/domains/([^/]+) ]]; then
DETECTED_DOMAIN="${BASH_REMATCH[1]}"
echo "Detected domain: $DETECTED_DOMAIN. Fixing permissions..."
correct_permissions_ownership "$DETECTED_DOMAIN"
else
echo "Error: You are not inside a domain directory (/home/nginx/domains/domain.com/)."
echo "Please specify a domain: scoots fixperm domain.com"
fi
fi
elif [ "$1" == php ]
then
if [ "$2" == opcache ] && [ "$3" == deploy ]
then
deploy_opcache_gui
elif [ "$2" == child ]
then
if [ "$3" == set ]
then
set_max_children "$4" "$5"
elif [ "$3" == get ]
then
get_php_fpm_configs
else
echo "Invalid option. Use 'scoots php child set [starter|professional|business|enterprise|man N]' or 'scoots php child get'"
fi
elif [ "$2" == update ]
then
if [ "$3" == "--reboot" ]
then
bash /bigscoots/wpo/phpfpm/multiphp.sh update --reboot
else
bash /bigscoots/wpo/phpfpm/multiphp.sh update
fi
elif [ "$2" == set ] && [ -n "$3" ] && [ -n "$4" ]
then
bash /bigscoots/wpo/phpfpm/multiphp.sh set --domain "$3" --phpver "$4"
elif [ "$2" == info ]
then
if [ -n "$3" ] && [ "$3" != all ]
then
bash /bigscoots/wpo/manage/info.sh --domain "$3" phpver | jq
else
bash /bigscoots/wpo/manage/info.sh --domain all phpver | jq
fi
elif [ "$2" == convert ]
then
bash /bigscoots/wpo/phpfpm/multiphp.sh update_configs >/dev/null 2>&1
domains=$(scoots php info | jq -r '.domains | to_entries[] | [.key, .value.php.version] | @tsv')
if [[ -n $domains ]]
then
while IFS=$'\t' read -r domain phpver
do
phpver="${phpver//./}"
bash /bigscoots/wpo/phpfpm/multiphp.sh set --domain "$domain" --phpver "$phpver" --bulk
done <<< "$domains"
fi
ngxreload_t "command ran: scoots php convert" || /usr/local/sbin/nginx -t
elif [ "$2" == restart ]
then
# Define an array of PHP versions to support
php_versions=("56" "70" "74" "80" "81" "82" "83" "84" "85")
if [ "$3" == all ]
then
/bin/fpmrestart >/dev/null 2>&1 && echo "Native PHP has been restarted."
# Loop through the PHP versions and only attempt to restart if the PHP binary exists
for ver in "${php_versions[@]}"
do
if [ -f "/opt/remi/php${ver}/root/usr/bin/php" ]
then
systemctl restart php"${ver}"-php-fpm.service >/dev/null 2>&1 && echo "PHP ${ver} restarted."
fi
done
elif [[ " ${php_versions[@]} " =~ " $3 " ]]
then
[ -f "/opt/remi/php${3}/root/usr/bin/php" ] && systemctl restart php"${3}"-php-fpm.service >/dev/null 2>&1 && echo "PHP $3 restarted."
else
echo "Invalid option. Use 'all' or specify a valid PHP version (${php_versions[*]})."
echo "If you are unsure what version a domain is using run: scoots php info \$domain"
fi
elif [ "$2" == reload ]
then
# Define an array of PHP versions to support
php_versions=("56" "70" "74" "80" "81" "82" "83" "84" "85")
if [ "$3" == all ]
then
/bin/fpmreload >/dev/null 2>&1 && echo "Native PHP has been reloaded."
# Loop through the PHP versions and only attempt to restart if the PHP binary exists
for ver in "${php_versions[@]}"
do
if [ -f "/opt/remi/php${ver}/root/usr/bin/php" ]
then
systemctl reload php"${ver}"-php-fpm.service >/dev/null 2>&1 && echo "PHP ${ver} reloaded."
fi
done
elif [[ " ${php_versions[@]} " =~ " $3 " ]]
then
[ -f "/opt/remi/php${3}/root/usr/bin/php" ] && systemctl reload php"${3}"-php-fpm.service >/dev/null 2>&1 && echo "PHP $3 reloaded."
else
echo "Invalid option. Use 'all' or specify a valid PHP version (${php_versions[*]})."
echo "If you are unsure what version a domain is using run: scoots php info \$domain"
fi
else
display_scoots_commands
fi
elif [ "$1" == qstat ]
then
bash /bigscoots/wpo/extras/les_audit.sh
elif [ "$1" == "perf" ]
then
case "$2" in
generate)
curl -fsSL "https://raw.githubusercontent.com/ahmad-den/useful_scripts/refs/heads/main/wp-perfmatters-config-generator.sh" | bash
;;
setup)
perf_setup
;;
*)
echo "BigScoots Performance Commands:
scoots perf generate # WORDPRESS PERFMATTERS CONFIG GENERATOR
scoots perf setup # Install+activate Perfmatters & license"
;;
esac
elif [ "$1" == db ]; then
if [ "$2" == convert ]; then
bash /bigscoots/wpo/manage/dbopt.sh convert
elif [ "$2" == check ]; then
bash /bigscoots/wpo/manage/dbopt.sh check
elif [ "$2" == cleanup ]; then
# 1) detect --apply / -y
apply=false
for arg in "${@:3}"; do
case "$arg" in
--apply|-y) apply=true ;;
esac
done
# 2) always run the check and capture unused DB names
mapfile -t unused_dbs < <(
bash /bigscoots/wpo/manage/disk_chk.sh check \
| awk '/To Remove/ {
for(i=1;i<=NF;i++) if($i=="drop") print $(i+1)
}'
)
# 3) if none found, bail out
if [ ${#unused_dbs[@]} -eq 0 ]; then
echo "No unused databases found."
return 0
fi
# 4) dry-run vs. apply
if ! $apply; then
echo
echo "Found ${#unused_dbs[@]} unused databases:"
printf ' - %s\n' "${unused_dbs[@]}"
echo
echo "Run 'scoots db cleanup --apply' (or -y) to actually drop these."
return 0
fi
# 5) actually drop
echo "Dropping ${#unused_dbs[@]} databases…"
for db in "${unused_dbs[@]}"; do
echo " • mysqladmin drop \"$db\" --force"
mysqladmin drop "$db" --force
done
echo "Done."
elif [ "$2" == list ]; then
list_databases
elif [ "$2" == create ]; then
# allow optional path argument, default to CWD
if [ -n "$3" ]; then
bash /bigscoots/wpo/manage/dbopt.sh create "$3"
else
bash /bigscoots/wpo/manage/dbopt.sh create
fi
elif [ "$2" == convert-charset ]; then
bash /bigscoots/wpo/manage/dbopt.sh convert-charset
else
echo "BigScoots Database Commands:
scoots db create [path] # Create DB & grant user from wp-config.php (default CWD)
scoots db convert # Converts all databases to InnoDB
scoots db check # Checks if the InnoDB buffer is full
scoots db cleanup # Finds unused databases
scoots db cleanup [--apply] # Finds unused databases (use --apply to drop)
scoots db list # Lists all domains & their database names
scoots db convert-charset # Converts utf8mb3 tables to utf8mb4_unicode_ci safely"
fi
elif [ "$1" == domain ]
then
if [ -n "$2" ]
then
DOMAIN="$2"
bash /bigscoots/wpo/manage/set.sh domain "${DOMAIN}"
else
echo "BigScoots Domain Commands:
scoots domain domain.com"
fi
elif [ "$1" == wf ]
then
URL=$(curl -s https://sharemy.zip/get/wordfence) && curl -s "$URL" > /var/tmp/wordfence.sh && chmod +x /var/tmp/wordfence.sh && /var/tmp/wordfence.sh "${@:2}" && rm -i -rf /var/tmp/wordfence.sh && cd /home/nginx/domains
elif [ "$1" == migrate ]
then
if [ -n "$2" ] && [ -n "$3" ]
then
# scoots migrate ALL destIP [extra flags...]
DOMAIN="$2"
DSTIP="$3"
EXTRA_ARGS=("${@:4}") # forward anything after the dest IP
if [ "$2" == "ALL" ]; then
# robust listing (one per line; avoid weird names)
mapfile -t DOMAINS < <(ls -1 /home/nginx/domains/ | sed '/^\s*$/d' | sort)
echo "Starting migration on the following domains:"
printf -- ' - %s\n' "${DOMAINS[@]}"
echo
echo 'If you see any issues, Ctrl+C now. Otherwise migration will start in 10 seconds...'
sleep 10
for D in "${DOMAINS[@]}"; do
bash /bigscoots/wpo/manage/migrate.sh "$D" "$DSTIP" "${EXTRA_ARGS[@]}"
done
else
bash /bigscoots/wpo/manage/migrate.sh "$DOMAIN" "$DSTIP" "${EXTRA_ARGS[@]}"
fi
else
echo "BigScoots Migrate Commands:
scoots migrate ALL DESTINATIONIP
scoots migrate domain.com DESTINATIONIP"
fi
elif [ "$1" == ssh ]
then
bash /bigscoots/wpo/extras/sshuser.sh manual
elif [ "$1" == rsync ]
then
if [ "$2" == cmd ]
then
ssh_port=$(grep -e "^\s*Port.*" /etc/ssh/sshd_config | grep -o "[0-9].*")
ssh_conn=$(whoami)@$serverip
domain=$(pwd | awk -F'/' '{print $(NF-1)}')
wpcli db export wpo_to_shared.sql
echo;echo "Run all of the following commands on the shared server, as the cPanel user, in the home directory, ex. /home/cpuser/";echo
echo "If this is the primary domain on the cPanel account, then symlink it to home directory like: ln -s public_html $domain";echo
echo "rsync -ahv --exclude wp-config.php --delete -e \"ssh -p $ssh_port\" $ssh_conn:$(pwd)/ $domain/"
echo;echo wp config set table_prefix \$\(wp config get table_prefix --path=$(pwd) --ssh=$ssh_conn:$ssh_port --allow-root --skip-plugins --skip-themes 2\>/dev/null\) --path=$domain 2\>/dev/null
echo;echo "wp db reset --yes --path=$domain"
echo;echo "wp db import $domain/wpo_to_shared.sql --path=$domain"
else
echo "BigScoots rsync Commands:
scoots rsync cmd # Prints an rsync command for the current folder."
fi
elif [ "$1" == ssl ]; then
DOMAIN="$3"
NOWWW=false
for arg in "$@"; do
if [ "$arg" == "--nowww" ]; then
NOWWW=true
fi
done
if [ "$2" == issue ] && [ -n "$DOMAIN" ]; then
if $NOWWW; then
bash /bigscoots/wpo/manage/ssl.sh issue "${DOMAIN}" --nowww
else
bash /bigscoots/wpo/manage/ssl.sh issue "${DOMAIN}"
fi
elif [ "$2" == reissue ] && [ -n "$DOMAIN" ]; then
if $NOWWW; then
bash /bigscoots/wpo/manage/ssl.sh reissue "${DOMAIN}" --nowww
else
bash /bigscoots/wpo/manage/ssl.sh reissue "${DOMAIN}"
fi
elif [ "$2" == status ] && [ -n "$DOMAIN" ]; then
bash /bigscoots/wpo/manage/ssl.sh status "${DOMAIN}"
else
echo "BigScoots SSL Commands:"
echo " scoots ssl issue domain.com # Issue a new SSL certificate"
echo " scoots ssl reissue domain.com # Reissue an existing SSL certificate"
echo " scoots ssl issue domain.com --nowww # Skip www during issue"
echo " scoots ssl reissue domain.com --nowww # Skip www during reissue"
echo " scoots ssl status domain.com # Check certificate status"
fi
elif [ "$1" == kstat ]
then
if [ -n "$2" ]
then
DOMAIN="$2"
bash /bigscoots/wpo/extras/khan_stats.sh "${DOMAIN}"
else
bash /bigscoots/wpo/extras/khan_stats.sh
fi
elif [ "$1" == plugin ] && [ "$2" == reinstall-all ]
then
reinstall_all_plugins "$3"
elif [ "$1" == astat ]
then
if [ -n "$2" ]
then
DOMAIN="$2"
bash /bigscoots/wpo/extras/ahmad_stats.sh "${DOMAIN}"
else
bash /bigscoots/wpo/extras/ahmad_stats.sh
fi
elif [ "$1" == "cron" ]
then
if [ "$2" == "on" ] && [ -n "$3" ]
then
bash /bigscoots/wpo/manage/wpcron.sh on "$3"
elif [ "$2" == "off" ] && [ -n "$3" ]
then
bash /bigscoots/wpo/manage/wpcron.sh off "$3"
else
display_scoots_commands
fi
elif [ "$1" == "oc" ]
then
if [ "$2" == "default" ]
then
bash /bigscoots/wpo/manage/set.sh redis default
elif [ "$2" == "on" ] && [ -n "$3" ]
then
bash /bigscoots/wpo/manage/set.sh redis on "$3"
elif [ "$2" == "mem" ] && [ -n "$3" ]
then
bash /bigscoots/wpo/manage/set.sh redis mem "$3"
else
display_scoots_commands
fi
elif [ "$1" == "ip" ]; then
if [ "$2" == "block" ] && [ -n "$3" ]; then
bash /bigscoots/wpo/nginx/blockip.sh block "$3"
elif [ "$2" == "unblock" ] && [ -n "$3" ]; then
bash /bigscoots/wpo/nginx/blockip.sh unblock "$3"
elif [ "$2" == "list" ]; then
bash /bigscoots/wpo/nginx/blockip.sh list | jq
else
echo "BigScoots IP Blocking Commands:"
echo " scoots ip block <IP> - Blocks an IP address"
echo " scoots ip unblock <IP> - Unblocks an IP address"
echo " scoots ip list - Lists all blocked IPs"
echo " - Example: scoots ip block 192.168.1.100 - Blocks the specified IP."
echo " - Example: scoots ip unblock 192.168.1.100 - Unblocks the specified IP."
echo " - Example: scoots ip list - Displays a list of currently blocked IPs."
fi
elif [ "$1" == "clone" ]; then
SOURCE="$2"
DEST="$3"
UPLOAD_OPTION=""
STAGING=false
# Validate source and dest
if [ -z "$SOURCE" ] || [ -z "$DEST" ]; then
echo "Usage: scoots clone <source domain> <destination domain> --uploads=skip|overwrite|sync [--staging]"
return 1
fi
# Parse remaining args
shift 3
for arg in "$@"; do
if [[ "$arg" == --uploads=* ]]; then
val="${arg#*=}"
case "$val" in
skip)
UPLOAD_OPTION="SKIPUPLOADS"
;;
overwrite)
UPLOAD_OPTION="OVERWRITEALL"
;;
sync)
UPLOAD_OPTION="SYNCUPLOADS"
;;
*)
echo "Invalid --uploads option: $val"
echo "Valid options: skip, overwrite, sync"
return 1
;;
esac
elif [ "$arg" == "--staging" ]; then
STAGING=true
fi
done
if [ -z "$UPLOAD_OPTION" ]; then
echo "Missing required --uploads option. Use --uploads=skip|overwrite|sync"
return 1
fi
if $STAGING; then
bash /bigscoots/wpo/manage/staging.sh "$SOURCE" "$DEST" skip "$UPLOAD_OPTION" && echo "Staging completed: https://$DEST"
else
bash /bigscoots/wpo/manage/clone.sh "$SOURCE" "$DEST" "$UPLOAD_OPTION" && echo "Clone completed: https://$DEST"
fi
else
display_scoots_commands
fi
}
# Helper function to set pm.max_children and pm.max_requests
function set_max_children() {
config_files=($(find /etc/opt/remi/ -type f -name "www.conf" 2>/dev/null))
local max_req=500
local reloaded_versions=""
case $1 in
starter) max_children=8 ;;
professional) max_children=16 ;;
business) max_children=32 ;;
enterprise) max_children=48 ;;
man) max_children="$2" ;;
*)
echo "Invalid option. Use 'starter', 'professional', 'business', 'enterprise', or 'man N'"
exit 1
;;
esac
for config_file in "${config_files[@]}"; do
if [ -f "$config_file" ]; then
# 1. Extract current values
current_max=$(grep -E "^pm.max_children" "$config_file" | awk -F'=' '{print $2}' | tr -d '[:space:]')
current_req=$(grep -E "^pm.max_requests" "$config_file" | awk -F'=' '{print $2}' | tr -d '[:space:]')
# 2. Update if values differ
if [[ "$current_max" != "$max_children" ]] || [[ "$current_req" != "$max_req" ]]; then
sed -i "s/^pm.max_children[[:space:]]*=[[:space:]]*[0-9]*/pm.max_children = $max_children/" "$config_file"
sed -i "s/^pm.max_requests[[:space:]]*=[[:space:]]*[0-9]*/pm.max_requests = $max_req/" "$config_file"
# 3. Identify PHP version from path (e.g., /etc/opt/remi/php83/... -> 83)
# This assumes the path structure follows the Remi standard
php_ver=$(echo "$config_file" | grep -oP 'php\K[0-9]+')
if [[ -n "$php_ver" ]]; then
# 4. Reload only this version and track it so we don't reload same version twice
if [[ ! "$reloaded_versions" =~ "$php_ver" ]]; then
scoots php reload "$php_ver" >/dev/null 2>&1
reloaded_versions+="$php_ver "
fi
fi
fi
fi
done
# Final response logic
if [ -n "$reloaded_versions" ]; then
msg="pm.max_children updated and reloaded PHP: $reloaded_versions"
else
msg="No changes required for any PHP versions"
fi
echo '{"errors": [], "messages": ["'"$msg"'"], "success": true, "result": {"updated_versions": "'"${reloaded_versions% }"'"}}' | jq
}
# Helper function to get current PHP-FPM configurations
function get_php_fpm_configs() {
config_files=($(find /etc/opt/remi/ -type f -name "www.conf" 2>/dev/null))
result="{"
for config_file in "${config_files[@]}"; do
if [ -f "$config_file" ]; then
php_version=$(echo "$config_file" | grep -oP 'php\d{2}')
pm=$(grep "^pm = " "$config_file" | cut -d ' ' -f 3)
max_children=$(grep "^pm.max_children = " "$config_file" | cut -d ' ' -f 3)
max_requests=$(grep "^pm.max_requests = " "$config_file" | cut -d ' ' -f 3)
result="$result\"$php_version\": {\"pm\": \"$pm\", \"pm.max_children\": \"$max_children\", \"pm.max_requests\": \"$max_requests\"},"
fi
done
result="${result%,}}"
echo "$result" | jq
}